diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-01-13 10:26:29 -0500 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-05-05 05:47:05 -0400 |
commit | 946929d813a3bde095678526dd037ab9ac6efe35 (patch) | |
tree | eb2601dc94364d9d376be372ccaadb304c921653 /fs/ntfs | |
parent | 3834c3f227725e2395840aed82342bda4ee9d379 (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/ntfs')
-rw-r--r-- | fs/ntfs/ChangeLog | 5 | ||||
-rw-r--r-- | fs/ntfs/aops.c | 21 |
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 | ||
55 | 2.1.22 - Many bug and race fixes and error handling improvements. | 60 | 2.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); |
2004 | done_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 | /* |