aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ntfs/inode.c')
-rw-r--r--fs/ntfs/inode.c172
1 files changed, 82 insertions, 90 deletions
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.