diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/file.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index d044b35ce228..eb955b525e55 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -3379,6 +3379,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
3379 | return rc; | 3379 | return rc; |
3380 | } | 3380 | } |
3381 | 3381 | ||
3382 | /* | ||
3383 | * cifs_readpage_worker must be called with the page pinned | ||
3384 | */ | ||
3382 | static int cifs_readpage_worker(struct file *file, struct page *page, | 3385 | static int cifs_readpage_worker(struct file *file, struct page *page, |
3383 | loff_t *poffset) | 3386 | loff_t *poffset) |
3384 | { | 3387 | { |
@@ -3390,7 +3393,6 @@ static int cifs_readpage_worker(struct file *file, struct page *page, | |||
3390 | if (rc == 0) | 3393 | if (rc == 0) |
3391 | goto read_complete; | 3394 | goto read_complete; |
3392 | 3395 | ||
3393 | page_cache_get(page); | ||
3394 | read_data = kmap(page); | 3396 | read_data = kmap(page); |
3395 | /* for reads over a certain size could initiate async read ahead */ | 3397 | /* for reads over a certain size could initiate async read ahead */ |
3396 | 3398 | ||
@@ -3417,7 +3419,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page, | |||
3417 | 3419 | ||
3418 | io_error: | 3420 | io_error: |
3419 | kunmap(page); | 3421 | kunmap(page); |
3420 | page_cache_release(page); | 3422 | unlock_page(page); |
3421 | 3423 | ||
3422 | read_complete: | 3424 | read_complete: |
3423 | return rc; | 3425 | return rc; |
@@ -3442,8 +3444,6 @@ static int cifs_readpage(struct file *file, struct page *page) | |||
3442 | 3444 | ||
3443 | rc = cifs_readpage_worker(file, page, &offset); | 3445 | rc = cifs_readpage_worker(file, page, &offset); |
3444 | 3446 | ||
3445 | unlock_page(page); | ||
3446 | |||
3447 | free_xid(xid); | 3447 | free_xid(xid); |
3448 | return rc; | 3448 | return rc; |
3449 | } | 3449 | } |
@@ -3497,6 +3497,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping, | |||
3497 | loff_t pos, unsigned len, unsigned flags, | 3497 | loff_t pos, unsigned len, unsigned flags, |
3498 | struct page **pagep, void **fsdata) | 3498 | struct page **pagep, void **fsdata) |
3499 | { | 3499 | { |
3500 | int oncethru = 0; | ||
3500 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; | 3501 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
3501 | loff_t offset = pos & (PAGE_CACHE_SIZE - 1); | 3502 | loff_t offset = pos & (PAGE_CACHE_SIZE - 1); |
3502 | loff_t page_start = pos & PAGE_MASK; | 3503 | loff_t page_start = pos & PAGE_MASK; |
@@ -3506,6 +3507,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping, | |||
3506 | 3507 | ||
3507 | cifs_dbg(FYI, "write_begin from %lld len %d\n", (long long)pos, len); | 3508 | cifs_dbg(FYI, "write_begin from %lld len %d\n", (long long)pos, len); |
3508 | 3509 | ||
3510 | start: | ||
3509 | page = grab_cache_page_write_begin(mapping, index, flags); | 3511 | page = grab_cache_page_write_begin(mapping, index, flags); |
3510 | if (!page) { | 3512 | if (!page) { |
3511 | rc = -ENOMEM; | 3513 | rc = -ENOMEM; |
@@ -3547,13 +3549,16 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping, | |||
3547 | } | 3549 | } |
3548 | } | 3550 | } |
3549 | 3551 | ||
3550 | if ((file->f_flags & O_ACCMODE) != O_WRONLY) { | 3552 | if ((file->f_flags & O_ACCMODE) != O_WRONLY && !oncethru) { |
3551 | /* | 3553 | /* |
3552 | * might as well read a page, it is fast enough. If we get | 3554 | * might as well read a page, it is fast enough. If we get |
3553 | * an error, we don't need to return it. cifs_write_end will | 3555 | * an error, we don't need to return it. cifs_write_end will |
3554 | * do a sync write instead since PG_uptodate isn't set. | 3556 | * do a sync write instead since PG_uptodate isn't set. |
3555 | */ | 3557 | */ |
3556 | cifs_readpage_worker(file, page, &page_start); | 3558 | cifs_readpage_worker(file, page, &page_start); |
3559 | page_cache_release(page); | ||
3560 | oncethru = 1; | ||
3561 | goto start; | ||
3557 | } else { | 3562 | } else { |
3558 | /* we could try using another file handle if there is one - | 3563 | /* we could try using another file handle if there is one - |
3559 | but how would we lock it to prevent close of that handle | 3564 | but how would we lock it to prevent close of that handle |