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:
@@ -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;
|
||||
|
Reference in New Issue
Block a user