aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/aops.c
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-03-10 06:06:19 -0500
committerAnton Altaparmakov <aia21@cantab.net>2005-05-05 06:26:01 -0400
commit905685f68fc72844b8c2689c39a5c6c35e840152 (patch)
tree0ff1d145a7771b24643c1b685ecbb3f791cda6fb /fs/ntfs/aops.c
parent43b01fda8b17b2b63e7dcdeed11c2ebba56b1fc9 (diff)
NTFS: - Modify ->readpage and ->writepage (fs/ntfs/aops.c) so they detect
and handle the case where an attribute is converted from resident to non-resident by a concurrent file write. - Reorder some operations when converting an attribute from resident to non-resident (fs/ntfs/attrib.c) so it is safe wrt concurrent ->readpage and ->writepage. Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs/aops.c')
-rw-r--r--fs/ntfs/aops.c18
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
358retry_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
1260retry_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;