diff options
Diffstat (limited to 'fs/ntfs/aops.c')
| -rw-r--r-- | fs/ntfs/aops.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index 2a7cba258cca..6241c4cfbe28 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c | |||
| @@ -355,6 +355,7 @@ static int ntfs_readpage(struct file *file, struct page *page) | |||
| 355 | u32 attr_len; | 355 | u32 attr_len; |
| 356 | int err = 0; | 356 | int err = 0; |
| 357 | 357 | ||
| 358 | retry_readpage: | ||
| 358 | BUG_ON(!PageLocked(page)); | 359 | BUG_ON(!PageLocked(page)); |
| 359 | /* | 360 | /* |
| 360 | * This can potentially happen because we clear PageUptodate() during | 361 | * This can potentially happen because we clear PageUptodate() during |
| @@ -408,6 +409,14 @@ static int ntfs_readpage(struct file *file, struct page *page) | |||
| 408 | err = PTR_ERR(mrec); | 409 | err = PTR_ERR(mrec); |
| 409 | goto err_out; | 410 | goto err_out; |
| 410 | } | 411 | } |
| 412 | /* | ||
| 413 | * If a parallel write made the attribute non-resident, drop the mft | ||
| 414 | * record and retry the readpage. | ||
| 415 | */ | ||
| 416 | if (unlikely(NInoNonResident(ni))) { | ||
| 417 | unmap_mft_record(base_ni); | ||
| 418 | goto retry_readpage; | ||
| 419 | } | ||
| 411 | ctx = ntfs_attr_get_search_ctx(base_ni, mrec); | 420 | ctx = ntfs_attr_get_search_ctx(base_ni, mrec); |
| 412 | if (unlikely(!ctx)) { | 421 | if (unlikely(!ctx)) { |
| 413 | err = -ENOMEM; | 422 | err = -ENOMEM; |
| @@ -1248,6 +1257,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc) | |||
| 1248 | u32 attr_len; | 1257 | u32 attr_len; |
| 1249 | int err; | 1258 | int err; |
| 1250 | 1259 | ||
| 1260 | retry_writepage: | ||
| 1251 | BUG_ON(!PageLocked(page)); | 1261 | BUG_ON(!PageLocked(page)); |
| 1252 | i_size = i_size_read(vi); | 1262 | i_size = i_size_read(vi); |
| 1253 | /* Is the page fully outside i_size? (truncate in progress) */ | 1263 | /* Is the page fully outside i_size? (truncate in progress) */ |
| @@ -1338,6 +1348,14 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc) | |||
| 1338 | ctx = NULL; | 1348 | ctx = NULL; |
| 1339 | goto err_out; | 1349 | goto err_out; |
| 1340 | } | 1350 | } |
| 1351 | /* | ||
| 1352 | * If a parallel write made the attribute non-resident, drop the mft | ||
| 1353 | * record and retry the writepage. | ||
| 1354 | */ | ||
| 1355 | if (unlikely(NInoNonResident(ni))) { | ||
| 1356 | unmap_mft_record(base_ni); | ||
| 1357 | goto retry_writepage; | ||
| 1358 | } | ||
| 1341 | ctx = ntfs_attr_get_search_ctx(base_ni, m); | 1359 | ctx = ntfs_attr_get_search_ctx(base_ni, m); |
| 1342 | if (unlikely(!ctx)) { | 1360 | if (unlikely(!ctx)) { |
| 1343 | err = -ENOMEM; | 1361 | err = -ENOMEM; |
