diff options
Diffstat (limited to 'fs/ntfs/attrib.c')
-rw-r--r-- | fs/ntfs/attrib.c | 13 |
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 | */ |
1528 | int ntfs_attr_make_non_resident(ntfs_inode *ni) | 1535 | int 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 + |