Skip to content

Commit 466bd31

Browse files
spuiuksmfrench
authored andcommitted
cifs: Avoid calling unlock_page() twice in cifs_readpage() when using fscache
When reading a single page with cifs_readpage(), we make a call to fscache_read_or_alloc_page() which once done, asynchronously calls the completion function cifs_readpage_from_fscache_complete(). This completion function unlocks the page once it has been populated from cache. The module then attempts to unlock the page a second time in cifs_readpage() which leads to warning messages. In case of a successful call to fscache_read_or_alloc_page() we should skip the second unlock_page() since this will be called by the cifs_readpage_from_fscache_complete() once the page has been populated by fscache. With the modifications to cifs_readpage_worker(), we will need to re-grab the page lock in cifs_write_begin(). The problem was first noticed when testing new fscache patches for cifs. https://bugzilla.redhat.com/show_bug.cgi?id=1005737 Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
1 parent a9e9b7b commit 466bd31

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

fs/cifs/file.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3419,6 +3419,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
34193419

34203420
io_error:
34213421
kunmap(page);
3422+
unlock_page(page);
34223423

34233424
read_complete:
34243425
return rc;
@@ -3443,8 +3444,6 @@ static int cifs_readpage(struct file *file, struct page *page)
34433444

34443445
rc = cifs_readpage_worker(file, page, &offset);
34453446

3446-
unlock_page(page);
3447-
34483447
free_xid(xid);
34493448
return rc;
34503449
}
@@ -3498,6 +3497,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping,
34983497
loff_t pos, unsigned len, unsigned flags,
34993498
struct page **pagep, void **fsdata)
35003499
{
3500+
int oncethru = 0;
35013501
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
35023502
loff_t offset = pos & (PAGE_CACHE_SIZE - 1);
35033503
loff_t page_start = pos & PAGE_MASK;
@@ -3507,6 +3507,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping,
35073507

35083508
cifs_dbg(FYI, "write_begin from %lld len %d\n", (long long)pos, len);
35093509

3510+
start:
35103511
page = grab_cache_page_write_begin(mapping, index, flags);
35113512
if (!page) {
35123513
rc = -ENOMEM;
@@ -3548,13 +3549,16 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping,
35483549
}
35493550
}
35503551

3551-
if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
3552+
if ((file->f_flags & O_ACCMODE) != O_WRONLY && !oncethru) {
35523553
/*
35533554
* might as well read a page, it is fast enough. If we get
35543555
* an error, we don't need to return it. cifs_write_end will
35553556
* do a sync write instead since PG_uptodate isn't set.
35563557
*/
35573558
cifs_readpage_worker(file, page, &page_start);
3559+
page_cache_release(page);
3560+
oncethru = 1;
3561+
goto start;
35583562
} else {
35593563
/* we could try using another file handle if there is one -
35603564
but how would we lock it to prevent close of that handle

0 commit comments

Comments
 (0)