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>
This commit is contained in:
Anton Altaparmakov
2005-03-10 11:06:19 +00:00
parent 43b01fda8b
commit 905685f68f
3 changed files with 46 additions and 16 deletions

View File

@@ -355,6 +355,7 @@ static int ntfs_readpage(struct file *file, struct page *page)
u32 attr_len;
int err = 0;
retry_readpage:
BUG_ON(!PageLocked(page));
/*
* This can potentially happen because we clear PageUptodate() during
@@ -408,6 +409,14 @@ static int ntfs_readpage(struct file *file, struct page *page)
err = PTR_ERR(mrec);
goto err_out;
}
/*
* If a parallel write made the attribute non-resident, drop the mft
* record and retry the readpage.
*/
if (unlikely(NInoNonResident(ni))) {
unmap_mft_record(base_ni);
goto retry_readpage;
}
ctx = ntfs_attr_get_search_ctx(base_ni, mrec);
if (unlikely(!ctx)) {
err = -ENOMEM;
@@ -1248,6 +1257,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
u32 attr_len;
int err;
retry_writepage:
BUG_ON(!PageLocked(page));
i_size = i_size_read(vi);
/* 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)
ctx = NULL;
goto err_out;
}
/*
* If a parallel write made the attribute non-resident, drop the mft
* record and retry the writepage.
*/
if (unlikely(NInoNonResident(ni))) {
unmap_mft_record(base_ni);
goto retry_writepage;
}
ctx = ntfs_attr_get_search_ctx(base_ni, m);
if (unlikely(!ctx)) {
err = -ENOMEM;