aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-10-04 09:48:20 -0400
committerAnton Altaparmakov <aia21@cantab.net>2005-10-04 09:48:20 -0400
commit8925d4f0d3479b9c5ed7e49acc648beccca95f21 (patch)
treefc740f0fbc17edc8b855c27c02d074679a0f0f03
parentfc0fa7dc7d243afabdb3fb6a11d59a944a9c91f8 (diff)
NTFS: Change ntfs_attr_make_non_resident to take the attribute value size
as an extra parameter. This is needed since we need to know the size before we can map the mft record and our callers always know it. The reason we cannot simply read the size from the vfs inode i_size is that this is not necessarily uptodate. This happens when ntfs_attr_make_non_resident() is called in the ->truncate call path. Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
-rw-r--r--fs/ntfs/ChangeLog6
-rw-r--r--fs/ntfs/attrib.c13
-rw-r--r--fs/ntfs/attrib.h2
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
412.1.24 - Lots of bug fixes and support more clean journal states. 472.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 */
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 +
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);
103extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, 103extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
104 const u32 new_size); 104 const u32 new_size);
105 105
106extern int ntfs_attr_make_non_resident(ntfs_inode *ni); 106extern int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size);
107 107
108extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, 108extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt,
109 const u8 val); 109 const u8 val);