aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/attrib.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ntfs/attrib.c')
-rw-r--r--fs/ntfs/attrib.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 98b5b96e8397..3f9a4ff42ee5 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1372,6 +1372,12 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1372 return err; 1372 return err;
1373 } 1373 }
1374 /* 1374 /*
1375 * FIXME: Compressed and encrypted attributes are not supported when
1376 * writing and we should never have gotten here for them.
1377 */
1378 BUG_ON(NInoCompressed(ni));
1379 BUG_ON(NInoEncrypted(ni));
1380 /*
1375 * The size needs to be aligned to a cluster boundary for allocation 1381 * The size needs to be aligned to a cluster boundary for allocation
1376 * purposes. 1382 * purposes.
1377 */ 1383 */
@@ -1447,10 +1453,15 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1447 BUG_ON(a->non_resident); 1453 BUG_ON(a->non_resident);
1448 /* 1454 /*
1449 * Calculate new offsets for the name and the mapping pairs array. 1455 * Calculate new offsets for the name and the mapping pairs array.
1450 * We assume the attribute is not compressed or sparse.
1451 */ 1456 */
1452 name_ofs = (offsetof(ATTR_REC, 1457 if (NInoSparse(ni) || NInoCompressed(ni))
1453 data.non_resident.compressed_size) + 7) & ~7; 1458 name_ofs = (offsetof(ATTR_REC,
1459 data.non_resident.compressed_size) +
1460 sizeof(a->data.non_resident.compressed_size) +
1461 7) & ~7;
1462 else
1463 name_ofs = (offsetof(ATTR_REC,
1464 data.non_resident.compressed_size) + 7) & ~7;
1454 mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7; 1465 mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
1455 /* 1466 /*
1456 * Determine the size of the resident part of the now non-resident 1467 * Determine the size of the resident part of the now non-resident
@@ -1489,24 +1500,23 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1489 memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset), 1500 memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
1490 a->name_length * sizeof(ntfschar)); 1501 a->name_length * sizeof(ntfschar));
1491 a->name_offset = cpu_to_le16(name_ofs); 1502 a->name_offset = cpu_to_le16(name_ofs);
1492 /*
1493 * FIXME: For now just clear all of these as we do not support them
1494 * when writing.
1495 */
1496 a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE |
1497 ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK));
1498 /* Setup the fields specific to non-resident attributes. */ 1503 /* Setup the fields specific to non-resident attributes. */
1499 a->data.non_resident.lowest_vcn = 0; 1504 a->data.non_resident.lowest_vcn = 0;
1500 a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >> 1505 a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >>
1501 vol->cluster_size_bits); 1506 vol->cluster_size_bits);
1502 a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs); 1507 a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
1503 a->data.non_resident.compression_unit = 0;
1504 memset(&a->data.non_resident.reserved, 0, 1508 memset(&a->data.non_resident.reserved, 0,
1505 sizeof(a->data.non_resident.reserved)); 1509 sizeof(a->data.non_resident.reserved));
1506 a->data.non_resident.allocated_size = cpu_to_sle64(new_size); 1510 a->data.non_resident.allocated_size = cpu_to_sle64(new_size);
1507 a->data.non_resident.data_size = 1511 a->data.non_resident.data_size =
1508 a->data.non_resident.initialized_size = 1512 a->data.non_resident.initialized_size =
1509 cpu_to_sle64(attr_size); 1513 cpu_to_sle64(attr_size);
1514 if (NInoSparse(ni) || NInoCompressed(ni)) {
1515 a->data.non_resident.compression_unit = 4;
1516 a->data.non_resident.compressed_size =
1517 a->data.non_resident.allocated_size;
1518 } else
1519 a->data.non_resident.compression_unit = 0;
1510 /* Generate the mapping pairs array into the attribute record. */ 1520 /* Generate the mapping pairs array into the attribute record. */
1511 err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs, 1521 err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs,
1512 arec_size - mp_ofs, rl, 0, -1, NULL); 1522 arec_size - mp_ofs, rl, 0, -1, NULL);
@@ -1516,16 +1526,19 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1516 goto undo_err_out; 1526 goto undo_err_out;
1517 } 1527 }
1518 /* Setup the in-memory attribute structure to be non-resident. */ 1528 /* Setup the in-memory attribute structure to be non-resident. */
1519 /*
1520 * FIXME: For now just clear all of these as we do not support them
1521 * when writing.
1522 */
1523 NInoClearSparse(ni);
1524 NInoClearEncrypted(ni);
1525 NInoClearCompressed(ni);
1526 ni->runlist.rl = rl; 1529 ni->runlist.rl = rl;
1527 write_lock_irqsave(&ni->size_lock, flags); 1530 write_lock_irqsave(&ni->size_lock, flags);
1528 ni->allocated_size = new_size; 1531 ni->allocated_size = new_size;
1532 if (NInoSparse(ni) || NInoCompressed(ni)) {
1533 ni->itype.compressed.size = ni->allocated_size;
1534 ni->itype.compressed.block_size = 1U <<
1535 (a->data.non_resident.compression_unit +
1536 vol->cluster_size_bits);
1537 ni->itype.compressed.block_size_bits =
1538 ffs(ni->itype.compressed.block_size) - 1;
1539 ni->itype.compressed.block_clusters = 1U <<
1540 a->data.non_resident.compression_unit;
1541 }
1529 write_unlock_irqrestore(&ni->size_lock, flags); 1542 write_unlock_irqrestore(&ni->size_lock, flags);
1530 /* 1543 /*
1531 * This needs to be last since the address space operations ->readpage 1544 * This needs to be last since the address space operations ->readpage
@@ -1673,6 +1686,12 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
1673 BUG_ON(cnt < 0); 1686 BUG_ON(cnt < 0);
1674 if (!cnt) 1687 if (!cnt)
1675 goto done; 1688 goto done;
1689 /*
1690 * FIXME: Compressed and encrypted attributes are not supported when
1691 * writing and we should never have gotten here for them.
1692 */
1693 BUG_ON(NInoCompressed(ni));
1694 BUG_ON(NInoEncrypted(ni));
1676 mapping = VFS_I(ni)->i_mapping; 1695 mapping = VFS_I(ni)->i_mapping;
1677 /* Work out the starting index and page offset. */ 1696 /* Work out the starting index and page offset. */
1678 idx = ofs >> PAGE_CACHE_SHIFT; 1697 idx = ofs >> PAGE_CACHE_SHIFT;