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.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 33e689f82a55..380f70a5f2e1 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1501,10 +1501,17 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
1501/** 1501/**
1502 * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute 1502 * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
1503 * @ni: ntfs inode describing the attribute to convert 1503 * @ni: ntfs inode describing the attribute to convert
1504 * @data_size: size of the resident data to copy to the non-resident attribute
1504 * 1505 *
1505 * Convert the resident ntfs attribute described by the ntfs inode @ni to a 1506 * Convert the resident ntfs attribute described by the ntfs inode @ni to a
1506 * non-resident one. 1507 * non-resident one.
1507 * 1508 *
1509 * @data_size must be equal to the attribute value size. This is needed since
1510 * we need to know the size before we can map the mft record and our callers
1511 * always know it. The reason we cannot simply read the size from the vfs
1512 * inode i_size is that this is not necessarily uptodate. This happens when
1513 * ntfs_attr_make_non_resident() is called in the ->truncate call path(s).
1514 *
1508 * Return 0 on success and -errno on error. The following error return codes 1515 * Return 0 on success and -errno on error. The following error return codes
1509 * are defined: 1516 * are defined:
1510 * -EPERM - The attribute is not allowed to be non-resident. 1517 * -EPERM - The attribute is not allowed to be non-resident.
@@ -1525,7 +1532,7 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
1525 * 1532 *
1526 * Locking: - The caller must hold i_sem on the inode. 1533 * Locking: - The caller must hold i_sem on the inode.
1527 */ 1534 */
1528int ntfs_attr_make_non_resident(ntfs_inode *ni) 1535int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
1529{ 1536{
1530 s64 new_size; 1537 s64 new_size;
1531 struct inode *vi = VFS_I(ni); 1538 struct inode *vi = VFS_I(ni);
@@ -1563,7 +1570,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1563 * The size needs to be aligned to a cluster boundary for allocation 1570 * The size needs to be aligned to a cluster boundary for allocation
1564 * purposes. 1571 * purposes.
1565 */ 1572 */
1566 new_size = (i_size_read(vi) + vol->cluster_size - 1) & 1573 new_size = (data_size + vol->cluster_size - 1) &
1567 ~(vol->cluster_size - 1); 1574 ~(vol->cluster_size - 1);
1568 if (new_size > 0) { 1575 if (new_size > 0) {
1569 /* 1576 /*
@@ -1647,7 +1654,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1647 * attribute value. 1654 * attribute value.
1648 */ 1655 */
1649 attr_size = le32_to_cpu(a->data.resident.value_length); 1656 attr_size = le32_to_cpu(a->data.resident.value_length);
1650 BUG_ON(attr_size != i_size_read(vi)); 1657 BUG_ON(attr_size != data_size);
1651 if (page && !PageUptodate(page)) { 1658 if (page && !PageUptodate(page)) {
1652 kaddr = kmap_atomic(page, KM_USER0); 1659 kaddr = kmap_atomic(page, KM_USER0);
1653 memcpy(kaddr, (u8*)a + 1660 memcpy(kaddr, (u8*)a +