diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-01-12 08:52:30 -0500 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-05-05 05:43:29 -0400 |
commit | 149f0c5200188a43f1fc11ca2fb14d8183013d10 (patch) | |
tree | 6fed760d28b70790e26803f6f18a663eb487764c /fs/ntfs/aops.c | |
parent | 07a4e2da7dd3c9345f84b2552872f9d38c257451 (diff) |
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: | |||
1237 | static int ntfs_writepage(struct page *page, struct writeback_control *wbc) | 1237 | static int ntfs_writepage(struct page *page, struct writeback_control *wbc) |
1238 | { | 1238 | { |
1239 | loff_t i_size; | 1239 | loff_t i_size; |
1240 | struct inode *vi; | 1240 | struct inode *vi = page->mapping->host; |
1241 | ntfs_inode *ni, *base_ni; | 1241 | ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi); |
1242 | char *kaddr; | 1242 | char *kaddr; |
1243 | ntfs_attr_search_ctx *ctx; | 1243 | ntfs_attr_search_ctx *ctx = NULL; |
1244 | MFT_RECORD *m; | 1244 | MFT_RECORD *m = NULL; |
1245 | u32 attr_len; | 1245 | u32 attr_len; |
1246 | int err; | 1246 | int err; |
1247 | 1247 | ||
1248 | BUG_ON(!PageLocked(page)); | 1248 | BUG_ON(!PageLocked(page)); |
1249 | 1249 | /* | |
1250 | vi = page->mapping->host; | 1250 | * If a previous ntfs_truncate() failed, repeat it and abort if it |
1251 | * fails again. | ||
1252 | */ | ||
1253 | if (unlikely(NInoTruncateFailed(ni))) { | ||
1254 | down_write(&vi->i_alloc_sem); | ||
1255 | err = ntfs_truncate(vi); | ||
1256 | up_write(&vi->i_alloc_sem); | ||
1257 | if (err || NInoTruncateFailed(ni)) { | ||
1258 | if (!err) | ||
1259 | err = -EIO; | ||
1260 | goto err_out; | ||
1261 | } | ||
1262 | } | ||
1251 | i_size = i_size_read(vi); | 1263 | i_size = i_size_read(vi); |
1252 | |||
1253 | /* Is the page fully outside i_size? (truncate in progress) */ | 1264 | /* Is the page fully outside i_size? (truncate in progress) */ |
1254 | if (unlikely(page->index >= (i_size + PAGE_CACHE_SIZE - 1) >> | 1265 | if (unlikely(page->index >= (i_size + PAGE_CACHE_SIZE - 1) >> |
1255 | PAGE_CACHE_SHIFT)) { | 1266 | PAGE_CACHE_SHIFT)) { |
@@ -1262,8 +1273,6 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc) | |||
1262 | ntfs_debug("Write outside i_size - truncated?"); | 1273 | ntfs_debug("Write outside i_size - truncated?"); |
1263 | return 0; | 1274 | return 0; |
1264 | } | 1275 | } |
1265 | ni = NTFS_I(vi); | ||
1266 | |||
1267 | /* NInoNonResident() == NInoIndexAllocPresent() */ | 1276 | /* NInoNonResident() == NInoIndexAllocPresent() */ |
1268 | if (NInoNonResident(ni)) { | 1277 | if (NInoNonResident(ni)) { |
1269 | /* | 1278 | /* |
@@ -1419,8 +1428,10 @@ err_out: | |||
1419 | err = 0; | 1428 | err = 0; |
1420 | } else { | 1429 | } else { |
1421 | ntfs_error(vi->i_sb, "Resident attribute write failed with " | 1430 | ntfs_error(vi->i_sb, "Resident attribute write failed with " |
1422 | "error %i. Setting page error flag.", err); | 1431 | "error %i.", err); |
1423 | SetPageError(page); | 1432 | SetPageError(page); |
1433 | NVolSetErrors(ni->vol); | ||
1434 | make_bad_inode(vi); | ||
1424 | } | 1435 | } |
1425 | unlock_page(page); | 1436 | unlock_page(page); |
1426 | if (ctx) | 1437 | if (ctx) |