diff options
-rw-r--r-- | fs/ntfs/ChangeLog | 6 | ||||
-rw-r--r-- | fs/ntfs/attrib.c | 13 | ||||
-rw-r--r-- | fs/ntfs/attrib.h | 2 |
3 files changed, 17 insertions, 4 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index aad2a3f2d1f8..60ba3c5cb2ea 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog | |||
@@ -37,6 +37,12 @@ ToDo/Notes: | |||
37 | - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc() | 37 | - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc() |
38 | with @is_extension set to TRUE and remove the runlist terminator | 38 | with @is_extension set to TRUE and remove the runlist terminator |
39 | fixup code as this is now done by ntfs_cluster_alloc(). | 39 | fixup code as this is now done by ntfs_cluster_alloc(). |
40 | - Change ntfs_attr_make_non_resident to take the attribute value size | ||
41 | as an extra parameter. This is needed since we need to know the size | ||
42 | before we can map the mft record and our callers always know it. The | ||
43 | reason we cannot simply read the size from the vfs inode i_size is | ||
44 | that this is not necessarily uptodate. This happens when | ||
45 | ntfs_attr_make_non_resident() is called in the ->truncate call path. | ||
40 | 46 | ||
41 | 2.1.24 - Lots of bug fixes and support more clean journal states. | 47 | 2.1.24 - Lots of bug fixes and support more clean journal states. |
42 | 48 | ||
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 + |
diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h index 62f76258d9c3..a959af9cef12 100644 --- a/fs/ntfs/attrib.h +++ b/fs/ntfs/attrib.h | |||
@@ -103,7 +103,7 @@ extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size); | |||
103 | extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, | 103 | extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, |
104 | const u32 new_size); | 104 | const u32 new_size); |
105 | 105 | ||
106 | extern int ntfs_attr_make_non_resident(ntfs_inode *ni); | 106 | extern int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size); |
107 | 107 | ||
108 | extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, | 108 | extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, |
109 | const u8 val); | 109 | const u8 val); |