diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-03-03 09:43:43 -0500 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-05-05 06:15:46 -0400 |
commit | 9451f8519c5e6d5d064c30033fc3d4ce77de321c (patch) | |
tree | 104eedf065c4091838a27f6e674875a035c30820 /fs/ntfs | |
parent | 413826868fb49d200b741bcaeaf58ea5c5e45321 (diff) |
NTFS: Correct sparse file handling. The compressed values need to be
checked and set in the ntfs inode as done for compressed files
and the compressed size needs to be used for vfs inode->i_blocks
instead of the allocated size, again, as done for compressed files.
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs')
-rw-r--r-- | fs/ntfs/ChangeLog | 4 | ||||
-rw-r--r-- | fs/ntfs/inode.c | 172 | ||||
-rw-r--r-- | fs/ntfs/layout.h | 15 |
3 files changed, 94 insertions, 97 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index cf21e0571b68..cd348f0b90e5 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog | |||
@@ -84,6 +84,10 @@ ToDo/Notes: | |||
84 | - Make fs/ntfs/namei.c::ntfs_get_{parent,dentry} static and move the | 84 | - Make fs/ntfs/namei.c::ntfs_get_{parent,dentry} static and move the |
85 | definition of ntfs_export_ops from fs/ntfs/super.c to namei.c. Also, | 85 | definition of ntfs_export_ops from fs/ntfs/super.c to namei.c. Also, |
86 | declare ntfs_export_ops in fs/ntfs/ntfs.h. | 86 | declare ntfs_export_ops in fs/ntfs/ntfs.h. |
87 | - Correct sparse file handling. The compressed values need to be | ||
88 | checked and set in the ntfs inode as done for compressed files and | ||
89 | the compressed size needs to be used for vfs inode->i_blocks instead | ||
90 | of the allocated size, again, as done for compressed files. | ||
87 | 91 | ||
88 | 2.1.22 - Many bug and race fixes and error handling improvements. | 92 | 2.1.22 - Many bug and race fixes and error handling improvements. |
89 | 93 | ||
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 7ae647c640bb..f7bee8d014d9 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
@@ -1016,26 +1016,31 @@ skip_large_dir_stuff: | |||
1016 | /* Setup the state. */ | 1016 | /* Setup the state. */ |
1017 | if (a->non_resident) { | 1017 | if (a->non_resident) { |
1018 | NInoSetNonResident(ni); | 1018 | NInoSetNonResident(ni); |
1019 | if (a->flags & ATTR_COMPRESSION_MASK) { | 1019 | if (a->flags & (ATTR_COMPRESSION_MASK | |
1020 | NInoSetCompressed(ni); | 1020 | ATTR_IS_SPARSE)) { |
1021 | if (vol->cluster_size > 4096) { | 1021 | if (a->flags & ATTR_COMPRESSION_MASK) { |
1022 | ntfs_error(vi->i_sb, "Found " | 1022 | NInoSetCompressed(ni); |
1023 | "compressed data but " | 1023 | if (vol->cluster_size > 4096) { |
1024 | "compression is disabled due " | 1024 | ntfs_error(vi->i_sb, "Found " |
1025 | "to cluster size (%i) > 4kiB.", | 1025 | "compressed data but " |
1026 | vol->cluster_size); | 1026 | "compression is " |
1027 | goto unm_err_out; | 1027 | "disabled due to " |
1028 | } | 1028 | "cluster size (%i) > " |
1029 | if ((a->flags & ATTR_COMPRESSION_MASK) | 1029 | "4kiB.", |
1030 | != ATTR_IS_COMPRESSED) { | 1030 | vol->cluster_size); |
1031 | ntfs_error(vi->i_sb, "Found " | 1031 | goto unm_err_out; |
1032 | "unknown compression method or " | 1032 | } |
1033 | "corrupt file."); | 1033 | if ((a->flags & ATTR_COMPRESSION_MASK) |
1034 | goto unm_err_out; | 1034 | != ATTR_IS_COMPRESSED) { |
1035 | ntfs_error(vi->i_sb, "Found " | ||
1036 | "unknown compression " | ||
1037 | "method or corrupt " | ||
1038 | "file."); | ||
1039 | goto unm_err_out; | ||
1040 | } | ||
1035 | } | 1041 | } |
1036 | ni->itype.compressed.block_clusters = 1U << | 1042 | if (a->flags & ATTR_IS_SPARSE) |
1037 | a->data.non_resident. | 1043 | NInoSetSparse(ni); |
1038 | compression_unit; | ||
1039 | if (a->data.non_resident.compression_unit != | 1044 | if (a->data.non_resident.compression_unit != |
1040 | 4) { | 1045 | 4) { |
1041 | ntfs_error(vi->i_sb, "Found " | 1046 | ntfs_error(vi->i_sb, "Found " |
@@ -1047,12 +1052,19 @@ skip_large_dir_stuff: | |||
1047 | err = -EOPNOTSUPP; | 1052 | err = -EOPNOTSUPP; |
1048 | goto unm_err_out; | 1053 | goto unm_err_out; |
1049 | } | 1054 | } |
1055 | ni->itype.compressed.block_clusters = 1U << | ||
1056 | a->data.non_resident. | ||
1057 | compression_unit; | ||
1050 | ni->itype.compressed.block_size = 1U << ( | 1058 | ni->itype.compressed.block_size = 1U << ( |
1051 | a->data.non_resident. | 1059 | a->data.non_resident. |
1052 | compression_unit + | 1060 | compression_unit + |
1053 | vol->cluster_size_bits); | 1061 | vol->cluster_size_bits); |
1054 | ni->itype.compressed.block_size_bits = ffs( | 1062 | ni->itype.compressed.block_size_bits = ffs( |
1055 | ni->itype.compressed.block_size) - 1; | 1063 | ni->itype.compressed. |
1064 | block_size) - 1; | ||
1065 | ni->itype.compressed.size = sle64_to_cpu( | ||
1066 | a->data.non_resident. | ||
1067 | compressed_size); | ||
1056 | } | 1068 | } |
1057 | if (a->flags & ATTR_IS_ENCRYPTED) { | 1069 | if (a->flags & ATTR_IS_ENCRYPTED) { |
1058 | if (a->flags & ATTR_COMPRESSION_MASK) { | 1070 | if (a->flags & ATTR_COMPRESSION_MASK) { |
@@ -1062,27 +1074,19 @@ skip_large_dir_stuff: | |||
1062 | } | 1074 | } |
1063 | NInoSetEncrypted(ni); | 1075 | NInoSetEncrypted(ni); |
1064 | } | 1076 | } |
1065 | if (a->flags & ATTR_IS_SPARSE) | ||
1066 | NInoSetSparse(ni); | ||
1067 | if (a->data.non_resident.lowest_vcn) { | 1077 | if (a->data.non_resident.lowest_vcn) { |
1068 | ntfs_error(vi->i_sb, "First extent of $DATA " | 1078 | ntfs_error(vi->i_sb, "First extent of $DATA " |
1069 | "attribute has non zero " | 1079 | "attribute has non zero " |
1070 | "lowest_vcn."); | 1080 | "lowest_vcn."); |
1071 | goto unm_err_out; | 1081 | goto unm_err_out; |
1072 | } | 1082 | } |
1073 | /* Setup all the sizes. */ | ||
1074 | vi->i_size = sle64_to_cpu( | 1083 | vi->i_size = sle64_to_cpu( |
1075 | a->data.non_resident.data_size); | 1084 | a->data.non_resident.data_size); |
1076 | ni->initialized_size = sle64_to_cpu( | 1085 | ni->initialized_size = sle64_to_cpu( |
1077 | a->data.non_resident.initialized_size); | 1086 | a->data.non_resident.initialized_size); |
1078 | ni->allocated_size = sle64_to_cpu( | 1087 | ni->allocated_size = sle64_to_cpu( |
1079 | a->data.non_resident.allocated_size); | 1088 | a->data.non_resident.allocated_size); |
1080 | if (NInoCompressed(ni)) | ||
1081 | ni->itype.compressed.size = sle64_to_cpu( | ||
1082 | a->data.non_resident. | ||
1083 | compressed_size); | ||
1084 | } else { /* Resident attribute. */ | 1089 | } else { /* Resident attribute. */ |
1085 | /* Setup all the sizes. */ | ||
1086 | vi->i_size = ni->initialized_size = le32_to_cpu( | 1090 | vi->i_size = ni->initialized_size = le32_to_cpu( |
1087 | a->data.resident.value_length); | 1091 | a->data.resident.value_length); |
1088 | ni->allocated_size = le32_to_cpu(a->length) - | 1092 | ni->allocated_size = le32_to_cpu(a->length) - |
@@ -1120,11 +1124,10 @@ no_data_attr_special_case: | |||
1120 | * sizes of all non-resident attributes present to give us the Linux | 1124 | * sizes of all non-resident attributes present to give us the Linux |
1121 | * correct size that should go into i_blocks (after division by 512). | 1125 | * correct size that should go into i_blocks (after division by 512). |
1122 | */ | 1126 | */ |
1123 | if (S_ISDIR(vi->i_mode) || !NInoCompressed(ni)) | 1127 | if (S_ISREG(vi->i_mode) && (NInoCompressed(ni) || NInoSparse(ni))) |
1124 | vi->i_blocks = ni->allocated_size >> 9; | ||
1125 | else | ||
1126 | vi->i_blocks = ni->itype.compressed.size >> 9; | 1128 | vi->i_blocks = ni->itype.compressed.size >> 9; |
1127 | 1129 | else | |
1130 | vi->i_blocks = ni->allocated_size >> 9; | ||
1128 | ntfs_debug("Done."); | 1131 | ntfs_debug("Done."); |
1129 | return 0; | 1132 | return 0; |
1130 | 1133 | ||
@@ -1226,14 +1229,13 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) | |||
1226 | "linux-ntfs-dev@lists.sourceforge.net"); | 1229 | "linux-ntfs-dev@lists.sourceforge.net"); |
1227 | goto unm_err_out; | 1230 | goto unm_err_out; |
1228 | } | 1231 | } |
1229 | /* Resident attribute. Setup all the sizes. */ | ||
1230 | vi->i_size = ni->initialized_size = le32_to_cpu( | 1232 | vi->i_size = ni->initialized_size = le32_to_cpu( |
1231 | a->data.resident.value_length); | 1233 | a->data.resident.value_length); |
1232 | ni->allocated_size = le32_to_cpu(a->length) - | 1234 | ni->allocated_size = le32_to_cpu(a->length) - |
1233 | le16_to_cpu(a->data.resident.value_offset); | 1235 | le16_to_cpu(a->data.resident.value_offset); |
1234 | if (vi->i_size > ni->allocated_size) { | 1236 | if (vi->i_size > ni->allocated_size) { |
1235 | ntfs_error(vi->i_sb, "Resident data attribute is " | 1237 | ntfs_error(vi->i_sb, "Resident attribute is corrupt " |
1236 | "corrupt (size exceeds allocation)."); | 1238 | "(size exceeds allocation)."); |
1237 | goto unm_err_out; | 1239 | goto unm_err_out; |
1238 | } | 1240 | } |
1239 | } else { | 1241 | } else { |
@@ -1249,43 +1251,50 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) | |||
1249 | "the mapping pairs array."); | 1251 | "the mapping pairs array."); |
1250 | goto unm_err_out; | 1252 | goto unm_err_out; |
1251 | } | 1253 | } |
1252 | if (a->flags & ATTR_COMPRESSION_MASK) { | 1254 | if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) { |
1255 | if (a->flags & ATTR_COMPRESSION_MASK) { | ||
1256 | NInoSetCompressed(ni); | ||
1257 | if ((ni->type != AT_DATA) || (ni->type == | ||
1258 | AT_DATA && ni->name_len)) { | ||
1259 | ntfs_error(vi->i_sb, "Found compressed " | ||
1260 | "non-data or named " | ||
1261 | "data attribute. " | ||
1262 | "Please report you " | ||
1263 | "saw this message to " | ||
1264 | "linux-ntfs-dev@lists." | ||
1265 | "sourceforge.net"); | ||
1266 | goto unm_err_out; | ||
1267 | } | ||
1268 | if (vol->cluster_size > 4096) { | ||
1269 | ntfs_error(vi->i_sb, "Found compressed " | ||
1270 | "attribute but " | ||
1271 | "compression is " | ||
1272 | "disabled due to " | ||
1273 | "cluster size (%i) > " | ||
1274 | "4kiB.", | ||
1275 | vol->cluster_size); | ||
1276 | goto unm_err_out; | ||
1277 | } | ||
1278 | if ((a->flags & ATTR_COMPRESSION_MASK) != | ||
1279 | ATTR_IS_COMPRESSED) { | ||
1280 | ntfs_error(vi->i_sb, "Found unknown " | ||
1281 | "compression method."); | ||
1282 | goto unm_err_out; | ||
1283 | } | ||
1284 | } | ||
1253 | if (NInoMstProtected(ni)) { | 1285 | if (NInoMstProtected(ni)) { |
1254 | ntfs_error(vi->i_sb, "Found mst protected " | 1286 | ntfs_error(vi->i_sb, "Found mst protected " |
1255 | "attribute but the attribute " | 1287 | "attribute but the attribute " |
1256 | "is compressed. Please report " | 1288 | "is %s. Please report you " |
1257 | "you saw this message to " | 1289 | "saw this message to " |
1258 | "linux-ntfs-dev@lists." | ||
1259 | "sourceforge.net"); | ||
1260 | goto unm_err_out; | ||
1261 | } | ||
1262 | NInoSetCompressed(ni); | ||
1263 | if ((ni->type != AT_DATA) || (ni->type == AT_DATA && | ||
1264 | ni->name_len)) { | ||
1265 | ntfs_error(vi->i_sb, "Found compressed " | ||
1266 | "non-data or named data " | ||
1267 | "attribute. Please report " | ||
1268 | "you saw this message to " | ||
1269 | "linux-ntfs-dev@lists." | 1290 | "linux-ntfs-dev@lists." |
1270 | "sourceforge.net"); | 1291 | "sourceforge.net", |
1271 | goto unm_err_out; | 1292 | NInoCompressed(ni) ? |
1272 | } | 1293 | "compressed" : "sparse"); |
1273 | if (vol->cluster_size > 4096) { | ||
1274 | ntfs_error(vi->i_sb, "Found compressed " | ||
1275 | "attribute but compression is " | ||
1276 | "disabled due to cluster size " | ||
1277 | "(%i) > 4kiB.", | ||
1278 | vol->cluster_size); | ||
1279 | goto unm_err_out; | ||
1280 | } | ||
1281 | if ((a->flags & ATTR_COMPRESSION_MASK) != | ||
1282 | ATTR_IS_COMPRESSED) { | ||
1283 | ntfs_error(vi->i_sb, "Found unknown " | ||
1284 | "compression method."); | ||
1285 | goto unm_err_out; | 1294 | goto unm_err_out; |
1286 | } | 1295 | } |
1287 | ni->itype.compressed.block_clusters = 1U << | 1296 | if (a->flags & ATTR_IS_SPARSE) |
1288 | a->data.non_resident.compression_unit; | 1297 | NInoSetSparse(ni); |
1289 | if (a->data.non_resident.compression_unit != 4) { | 1298 | if (a->data.non_resident.compression_unit != 4) { |
1290 | ntfs_error(vi->i_sb, "Found nonstandard " | 1299 | ntfs_error(vi->i_sb, "Found nonstandard " |
1291 | "compression unit (%u instead " | 1300 | "compression unit (%u instead " |
@@ -1295,11 +1304,15 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) | |||
1295 | err = -EOPNOTSUPP; | 1304 | err = -EOPNOTSUPP; |
1296 | goto unm_err_out; | 1305 | goto unm_err_out; |
1297 | } | 1306 | } |
1307 | ni->itype.compressed.block_clusters = 1U << | ||
1308 | a->data.non_resident.compression_unit; | ||
1298 | ni->itype.compressed.block_size = 1U << ( | 1309 | ni->itype.compressed.block_size = 1U << ( |
1299 | a->data.non_resident.compression_unit + | 1310 | a->data.non_resident.compression_unit + |
1300 | vol->cluster_size_bits); | 1311 | vol->cluster_size_bits); |
1301 | ni->itype.compressed.block_size_bits = ffs( | 1312 | ni->itype.compressed.block_size_bits = ffs( |
1302 | ni->itype.compressed.block_size) - 1; | 1313 | ni->itype.compressed.block_size) - 1; |
1314 | ni->itype.compressed.size = sle64_to_cpu( | ||
1315 | a->data.non_resident.compressed_size); | ||
1303 | } | 1316 | } |
1304 | if (a->flags & ATTR_IS_ENCRYPTED) { | 1317 | if (a->flags & ATTR_IS_ENCRYPTED) { |
1305 | if (a->flags & ATTR_COMPRESSION_MASK) { | 1318 | if (a->flags & ATTR_COMPRESSION_MASK) { |
@@ -1318,34 +1331,17 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) | |||
1318 | } | 1331 | } |
1319 | NInoSetEncrypted(ni); | 1332 | NInoSetEncrypted(ni); |
1320 | } | 1333 | } |
1321 | if (a->flags & ATTR_IS_SPARSE) { | ||
1322 | if (NInoMstProtected(ni)) { | ||
1323 | ntfs_error(vi->i_sb, "Found mst protected " | ||
1324 | "attribute but the attribute " | ||
1325 | "is sparse. Please report " | ||
1326 | "you saw this message to " | ||
1327 | "linux-ntfs-dev@lists." | ||
1328 | "sourceforge.net"); | ||
1329 | goto unm_err_out; | ||
1330 | } | ||
1331 | NInoSetSparse(ni); | ||
1332 | } | ||
1333 | if (a->data.non_resident.lowest_vcn) { | 1334 | if (a->data.non_resident.lowest_vcn) { |
1334 | ntfs_error(vi->i_sb, "First extent of attribute has " | 1335 | ntfs_error(vi->i_sb, "First extent of attribute has " |
1335 | "non-zero lowest_vcn."); | 1336 | "non-zero lowest_vcn."); |
1336 | goto unm_err_out; | 1337 | goto unm_err_out; |
1337 | } | 1338 | } |
1338 | /* Setup all the sizes. */ | ||
1339 | vi->i_size = sle64_to_cpu(a->data.non_resident.data_size); | 1339 | vi->i_size = sle64_to_cpu(a->data.non_resident.data_size); |
1340 | ni->initialized_size = sle64_to_cpu( | 1340 | ni->initialized_size = sle64_to_cpu( |
1341 | a->data.non_resident.initialized_size); | 1341 | a->data.non_resident.initialized_size); |
1342 | ni->allocated_size = sle64_to_cpu( | 1342 | ni->allocated_size = sle64_to_cpu( |
1343 | a->data.non_resident.allocated_size); | 1343 | a->data.non_resident.allocated_size); |
1344 | if (NInoCompressed(ni)) | ||
1345 | ni->itype.compressed.size = sle64_to_cpu( | ||
1346 | a->data.non_resident.compressed_size); | ||
1347 | } | 1344 | } |
1348 | |||
1349 | /* Setup the operations for this attribute inode. */ | 1345 | /* Setup the operations for this attribute inode. */ |
1350 | vi->i_op = NULL; | 1346 | vi->i_op = NULL; |
1351 | vi->i_fop = NULL; | 1347 | vi->i_fop = NULL; |
@@ -1353,12 +1349,10 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) | |||
1353 | vi->i_mapping->a_ops = &ntfs_mst_aops; | 1349 | vi->i_mapping->a_ops = &ntfs_mst_aops; |
1354 | else | 1350 | else |
1355 | vi->i_mapping->a_ops = &ntfs_aops; | 1351 | vi->i_mapping->a_ops = &ntfs_aops; |
1356 | 1352 | if (NInoCompressed(ni) || NInoSparse(ni)) | |
1357 | if (!NInoCompressed(ni)) | ||
1358 | vi->i_blocks = ni->allocated_size >> 9; | ||
1359 | else | ||
1360 | vi->i_blocks = ni->itype.compressed.size >> 9; | 1353 | vi->i_blocks = ni->itype.compressed.size >> 9; |
1361 | 1354 | else | |
1355 | vi->i_blocks = ni->allocated_size >> 9; | ||
1362 | /* | 1356 | /* |
1363 | * Make sure the base inode doesn't go away and attach it to the | 1357 | * Make sure the base inode doesn't go away and attach it to the |
1364 | * attribute inode. | 1358 | * attribute inode. |
@@ -1643,7 +1637,6 @@ skip_large_index_stuff: | |||
1643 | vi->i_fop = NULL; | 1637 | vi->i_fop = NULL; |
1644 | vi->i_mapping->a_ops = &ntfs_mst_aops; | 1638 | vi->i_mapping->a_ops = &ntfs_mst_aops; |
1645 | vi->i_blocks = ni->allocated_size >> 9; | 1639 | vi->i_blocks = ni->allocated_size >> 9; |
1646 | |||
1647 | /* | 1640 | /* |
1648 | * Make sure the base inode doesn't go away and attach it to the | 1641 | * Make sure the base inode doesn't go away and attach it to the |
1649 | * index inode. | 1642 | * index inode. |
@@ -1728,7 +1721,6 @@ int ntfs_read_inode_mount(struct inode *vi) | |||
1728 | ni->type = AT_DATA; | 1721 | ni->type = AT_DATA; |
1729 | ni->name = NULL; | 1722 | ni->name = NULL; |
1730 | ni->name_len = 0; | 1723 | ni->name_len = 0; |
1731 | |||
1732 | /* | 1724 | /* |
1733 | * This sets up our little cheat allowing us to reuse the async read io | 1725 | * This sets up our little cheat allowing us to reuse the async read io |
1734 | * completion handler for directories. | 1726 | * completion handler for directories. |
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h index 7cb8806d4559..8d1f1326612f 100644 --- a/fs/ntfs/layout.h +++ b/fs/ntfs/layout.h | |||
@@ -749,10 +749,11 @@ typedef struct { | |||
749 | record header aligned to 8-byte boundary. */ | 749 | record header aligned to 8-byte boundary. */ |
750 | /* 34*/ u8 compression_unit; /* The compression unit expressed | 750 | /* 34*/ u8 compression_unit; /* The compression unit expressed |
751 | as the log to the base 2 of the number of | 751 | as the log to the base 2 of the number of |
752 | clusters in a compression unit. 0 means not | 752 | clusters in a compression unit. 0 means not |
753 | compressed. (This effectively limits the | 753 | compressed. (This effectively limits the |
754 | compression unit size to be a power of two | 754 | compression unit size to be a power of two |
755 | clusters.) WinNT4 only uses a value of 4. */ | 755 | clusters.) WinNT4 only uses a value of 4. |
756 | Sparse files also have this set to 4. */ | ||
756 | /* 35*/ u8 reserved[5]; /* Align to 8-byte boundary. */ | 757 | /* 35*/ u8 reserved[5]; /* Align to 8-byte boundary. */ |
757 | /* The sizes below are only used when lowest_vcn is zero, as otherwise it would | 758 | /* The sizes below are only used when lowest_vcn is zero, as otherwise it would |
758 | be difficult to keep them up-to-date.*/ | 759 | be difficult to keep them up-to-date.*/ |
@@ -772,10 +773,10 @@ typedef struct { | |||
772 | data_size. */ | 773 | data_size. */ |
773 | /* sizeof(uncompressed attr) = 64*/ | 774 | /* sizeof(uncompressed attr) = 64*/ |
774 | /* 64*/ sle64 compressed_size; /* Byte size of the attribute | 775 | /* 64*/ sle64 compressed_size; /* Byte size of the attribute |
775 | value after compression. Only present when | 776 | value after compression. Only present when |
776 | compressed. Always is a multiple of the | 777 | compressed or sparse. Always is a multiple of |
777 | cluster size. Represents the actual amount of | 778 | the cluster size. Represents the actual amount |
778 | disk space being used on the disk. */ | 779 | of disk space being used on the disk. */ |
779 | /* sizeof(compressed attr) = 72*/ | 780 | /* sizeof(compressed attr) = 72*/ |
780 | } __attribute__ ((__packed__)) non_resident; | 781 | } __attribute__ ((__packed__)) non_resident; |
781 | } __attribute__ ((__packed__)) data; | 782 | } __attribute__ ((__packed__)) data; |