diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-01-12 14:52:30 +0100 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-05-05 11:43:29 +0200 |
commit | 149f0c5200188a43f1fc11ca2fb14d8183013d10 (patch) | |
tree | 6fed760d28b70790e26803f6f18a663eb487764c /fs/ntfs/aops.c | |
parent | NTFS: Use i_size_{read,write}() in fs/ntfs/{aops.c,mft.c} and protect (diff) | |
download | linux-149f0c5200188a43f1fc11ca2fb14d8183013d10.tar.xz linux-149f0c5200188a43f1fc11ca2fb14d8183013d10.zip |
NTFS: Repeat a failed ntfs_truncate() in fs/ntfs/aops.c::ntfs_writepage()
and abort if it fails again.
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs/aops.c')
-rw-r--r-- | fs/ntfs/aops.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index a53212793809..ac65806ee515 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c @@ -1237,19 +1237,30 @@ done: static int ntfs_writepage(struct page *page, struct writeback_control *wbc) { loff_t i_size; - struct inode *vi; - ntfs_inode *ni, *base_ni; + struct inode *vi = page->mapping->host; + ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi); char *kaddr; - ntfs_attr_search_ctx *ctx; - MFT_RECORD *m; + ntfs_attr_search_ctx *ctx = NULL; + MFT_RECORD *m = NULL; u32 attr_len; int err; BUG_ON(!PageLocked(page)); - - vi = page->mapping->host; + /* + * If a previous ntfs_truncate() failed, repeat it and abort if it + * fails again. + */ + if (unlikely(NInoTruncateFailed(ni))) { + down_write(&vi->i_alloc_sem); + err = ntfs_truncate(vi); + up_write(&vi->i_alloc_sem); + if (err || NInoTruncateFailed(ni)) { + if (!err) + err = -EIO; + goto err_out; + } + } i_size = i_size_read(vi); - /* Is the page fully outside i_size? (truncate in progress) */ if (unlikely(page->index >= (i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)) { @@ -1262,8 +1273,6 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc) ntfs_debug("Write outside i_size - truncated?"); return 0; } - ni = NTFS_I(vi); - /* NInoNonResident() == NInoIndexAllocPresent() */ if (NInoNonResident(ni)) { /* @@ -1419,8 +1428,10 @@ err_out: err = 0; } else { ntfs_error(vi->i_sb, "Resident attribute write failed with " - "error %i. Setting page error flag.", err); + "error %i.", err); SetPageError(page); + NVolSetErrors(ni->vol); + make_bad_inode(vi); } unlock_page(page); if (ctx) |