diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2011-04-07 21:29:10 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-05-19 10:10:50 -0400 |
commit | 9ad1506b42c828dff0b9d8f3914e1f837734e91c (patch) | |
tree | 6108ad6564b013a978a717f52b06d5fff4d3ff0e /fs/cifs | |
parent | 1cb06d0b50536af177b2f2f7cab25546f3731d3e (diff) |
CIFS: Add launder_page operation (try #3)
Add this let us drop filemap_write_and_wait from cifs_invalidate_mapping
and simplify the code to properly process invalidate logic.
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/file.c | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index faf59529e847..00b466e667ab 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1420,9 +1420,10 @@ retry_write: | |||
1420 | return rc; | 1420 | return rc; |
1421 | } | 1421 | } |
1422 | 1422 | ||
1423 | static int cifs_writepage(struct page *page, struct writeback_control *wbc) | 1423 | static int |
1424 | cifs_writepage_locked(struct page *page, struct writeback_control *wbc) | ||
1424 | { | 1425 | { |
1425 | int rc = -EFAULT; | 1426 | int rc; |
1426 | int xid; | 1427 | int xid; |
1427 | 1428 | ||
1428 | xid = GetXid(); | 1429 | xid = GetXid(); |
@@ -1442,15 +1443,29 @@ static int cifs_writepage(struct page *page, struct writeback_control *wbc) | |||
1442 | * to fail to update with the state of the page correctly. | 1443 | * to fail to update with the state of the page correctly. |
1443 | */ | 1444 | */ |
1444 | set_page_writeback(page); | 1445 | set_page_writeback(page); |
1446 | retry_write: | ||
1445 | rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); | 1447 | rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); |
1446 | SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ | 1448 | if (rc == -EAGAIN && wbc->sync_mode == WB_SYNC_ALL) |
1447 | unlock_page(page); | 1449 | goto retry_write; |
1450 | else if (rc == -EAGAIN) | ||
1451 | redirty_page_for_writepage(wbc, page); | ||
1452 | else if (rc != 0) | ||
1453 | SetPageError(page); | ||
1454 | else | ||
1455 | SetPageUptodate(page); | ||
1448 | end_page_writeback(page); | 1456 | end_page_writeback(page); |
1449 | page_cache_release(page); | 1457 | page_cache_release(page); |
1450 | FreeXid(xid); | 1458 | FreeXid(xid); |
1451 | return rc; | 1459 | return rc; |
1452 | } | 1460 | } |
1453 | 1461 | ||
1462 | static int cifs_writepage(struct page *page, struct writeback_control *wbc) | ||
1463 | { | ||
1464 | int rc = cifs_writepage_locked(page, wbc); | ||
1465 | unlock_page(page); | ||
1466 | return rc; | ||
1467 | } | ||
1468 | |||
1454 | static int cifs_write_end(struct file *file, struct address_space *mapping, | 1469 | static int cifs_write_end(struct file *file, struct address_space *mapping, |
1455 | loff_t pos, unsigned len, unsigned copied, | 1470 | loff_t pos, unsigned len, unsigned copied, |
1456 | struct page *page, void *fsdata) | 1471 | struct page *page, void *fsdata) |
@@ -2415,6 +2430,27 @@ static void cifs_invalidate_page(struct page *page, unsigned long offset) | |||
2415 | cifs_fscache_invalidate_page(page, &cifsi->vfs_inode); | 2430 | cifs_fscache_invalidate_page(page, &cifsi->vfs_inode); |
2416 | } | 2431 | } |
2417 | 2432 | ||
2433 | static int cifs_launder_page(struct page *page) | ||
2434 | { | ||
2435 | int rc = 0; | ||
2436 | loff_t range_start = page_offset(page); | ||
2437 | loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); | ||
2438 | struct writeback_control wbc = { | ||
2439 | .sync_mode = WB_SYNC_ALL, | ||
2440 | .nr_to_write = 0, | ||
2441 | .range_start = range_start, | ||
2442 | .range_end = range_end, | ||
2443 | }; | ||
2444 | |||
2445 | cFYI(1, "Launder page: %p", page); | ||
2446 | |||
2447 | if (clear_page_dirty_for_io(page)) | ||
2448 | rc = cifs_writepage_locked(page, &wbc); | ||
2449 | |||
2450 | cifs_fscache_invalidate_page(page, page->mapping->host); | ||
2451 | return rc; | ||
2452 | } | ||
2453 | |||
2418 | void cifs_oplock_break(struct work_struct *work) | 2454 | void cifs_oplock_break(struct work_struct *work) |
2419 | { | 2455 | { |
2420 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, | 2456 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, |
@@ -2486,7 +2522,7 @@ const struct address_space_operations cifs_addr_ops = { | |||
2486 | .set_page_dirty = __set_page_dirty_nobuffers, | 2522 | .set_page_dirty = __set_page_dirty_nobuffers, |
2487 | .releasepage = cifs_release_page, | 2523 | .releasepage = cifs_release_page, |
2488 | .invalidatepage = cifs_invalidate_page, | 2524 | .invalidatepage = cifs_invalidate_page, |
2489 | /* .direct_IO = */ | 2525 | .launder_page = cifs_launder_page, |
2490 | }; | 2526 | }; |
2491 | 2527 | ||
2492 | /* | 2528 | /* |
@@ -2503,5 +2539,5 @@ const struct address_space_operations cifs_addr_ops_smallbuf = { | |||
2503 | .set_page_dirty = __set_page_dirty_nobuffers, | 2539 | .set_page_dirty = __set_page_dirty_nobuffers, |
2504 | .releasepage = cifs_release_page, | 2540 | .releasepage = cifs_release_page, |
2505 | .invalidatepage = cifs_invalidate_page, | 2541 | .invalidatepage = cifs_invalidate_page, |
2506 | /* .direct_IO = */ | 2542 | .launder_page = cifs_launder_page, |
2507 | }; | 2543 | }; |