aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-01-13 10:26:29 -0500
committerAnton Altaparmakov <aia21@cantab.net>2005-05-05 05:47:05 -0400
commit946929d813a3bde095678526dd037ab9ac6efe35 (patch)
treeeb2601dc94364d9d376be372ccaadb304c921653 /fs
parent3834c3f227725e2395840aed82342bda4ee9d379 (diff)
NTFS: Fixup the resident attribute resizing code in
fs/ntfs/aops.c::ntfs_{prepare,commit}_write()() and re-enable it. It should be safe now. (Famous last words...) Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs')
-rw-r--r--fs/ntfs/ChangeLog5
-rw-r--r--fs/ntfs/aops.c21
2 files changed, 19 insertions, 7 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 051c6818aad8..8a249df2b5c2 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -51,6 +51,11 @@ ToDo/Notes:
51 value afterwards when reading the size of the bitmap inode. 51 value afterwards when reading the size of the bitmap inode.
52 - Use i_size_{read,write}() in fs/ntfs/{aops.c,mft.c} and protect 52 - Use i_size_{read,write}() in fs/ntfs/{aops.c,mft.c} and protect
53 access to the i_size and other size fields using the size_lock. 53 access to the i_size and other size fields using the size_lock.
54 - Implement extension of resident files in the regular file write code
55 paths (fs/ntfs/aops.c::ntfs_{prepare,commit}_write()). At present
56 this only works until the data attribute becomes too big for the mft
57 record after which we abort the write returning -EOPNOTSUPP from
58 ntfs_prepare_write().
54 59
552.1.22 - Many bug and race fixes and error handling improvements. 602.1.22 - Many bug and race fixes and error handling improvements.
56 61
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index ac65806ee515..92215228eeab 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -872,6 +872,7 @@ static int ntfs_write_mst_block(struct page *page,
872 if (likely(block < rec_block)) { 872 if (likely(block < rec_block)) {
873 if (unlikely(block >= dblock)) { 873 if (unlikely(block >= dblock)) {
874 clear_buffer_dirty(bh); 874 clear_buffer_dirty(bh);
875 set_buffer_uptodate(bh);
875 continue; 876 continue;
876 } 877 }
877 /* 878 /*
@@ -1830,6 +1831,7 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
1830 unsigned from, unsigned to) 1831 unsigned from, unsigned to)
1831{ 1832{
1832 s64 new_size; 1833 s64 new_size;
1834 unsigned long flags;
1833 struct inode *vi = page->mapping->host; 1835 struct inode *vi = page->mapping->host;
1834 ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi); 1836 ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);
1835 ntfs_volume *vol = ni->vol; 1837 ntfs_volume *vol = ni->vol;
@@ -1903,12 +1905,6 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
1903 /* If we do not need to resize the attribute allocation we are done. */ 1905 /* If we do not need to resize the attribute allocation we are done. */
1904 if (new_size <= i_size_read(vi)) 1906 if (new_size <= i_size_read(vi))
1905 goto done; 1907 goto done;
1906
1907 // FIXME: We abort for now as this code is not safe.
1908 ntfs_error(vi->i_sb, "Changing the file size is not supported yet. "
1909 "Sorry.");
1910 return -EOPNOTSUPP;
1911
1912 /* Map, pin, and lock the (base) mft record. */ 1908 /* Map, pin, and lock the (base) mft record. */
1913 if (!NInoAttr(ni)) 1909 if (!NInoAttr(ni))
1914 base_ni = ni; 1910 base_ni = ni;
@@ -1937,7 +1933,17 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
1937 a = ctx->attr; 1933 a = ctx->attr;
1938 /* The total length of the attribute value. */ 1934 /* The total length of the attribute value. */
1939 attr_len = le32_to_cpu(a->data.resident.value_length); 1935 attr_len = le32_to_cpu(a->data.resident.value_length);
1940 BUG_ON(i_size_read(vi) != attr_len); 1936 /* Fix an eventual previous failure of ntfs_commit_write(). */
1937 read_lock_irqsave(&ni->size_lock, flags);
1938 if (unlikely(ni->initialized_size < attr_len)) {
1939 attr_len = ni->initialized_size;
1940 a->data.resident.value_length = cpu_to_le32(attr_len);
1941 BUG_ON(attr_len < i_size_read(vi));
1942 }
1943 read_unlock_irqrestore(&ni->size_lock, flags);
1944 /* If we do not need to resize the attribute allocation we are done. */
1945 if (new_size <= attr_len)
1946 goto done_unm;
1941 /* Check if new size is allowed in $AttrDef. */ 1947 /* Check if new size is allowed in $AttrDef. */
1942 err = ntfs_attr_size_bounds_check(vol, ni->type, new_size); 1948 err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);
1943 if (unlikely(err)) { 1949 if (unlikely(err)) {
@@ -1995,6 +2001,7 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
1995 } 2001 }
1996 flush_dcache_mft_record_page(ctx->ntfs_ino); 2002 flush_dcache_mft_record_page(ctx->ntfs_ino);
1997 mark_mft_record_dirty(ctx->ntfs_ino); 2003 mark_mft_record_dirty(ctx->ntfs_ino);
2004done_unm:
1998 ntfs_attr_put_search_ctx(ctx); 2005 ntfs_attr_put_search_ctx(ctx);
1999 unmap_mft_record(base_ni); 2006 unmap_mft_record(base_ni);
2000 /* 2007 /*