diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-02-19 20:03:26 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-03-05 15:44:55 -0500 |
commit | acdc53b2146c7ee67feb1f02f7bc3020126514b8 (patch) | |
tree | 3d8b087e8526c4caed87229fe12c2a2b261dd0a5 | |
parent | c988950eb6dd6f8e6d98503ca094622729e9aa13 (diff) |
NFS: Replace __nfs_write_mapping with sync_inode()
Now that we have correct COMMIT semantics in writeback_single_inode, we can
reduce and simplify nfs_wb_all(). Also replace nfs_wb_nocommit() with a
call to filemap_write_and_wait(), which doesn't need to hold the
inode->i_mutex.
With that done, we can eliminate nfs_write_mapping() altogether.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/inode.c | 15 | ||||
-rw-r--r-- | fs/nfs/write.c | 42 | ||||
-rw-r--r-- | include/linux/nfs_fs.h | 2 |
3 files changed, 10 insertions, 49 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index aa5a831001ab..443772df9b17 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -495,17 +495,11 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
495 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; | 495 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; |
496 | int err; | 496 | int err; |
497 | 497 | ||
498 | /* | 498 | /* Flush out writes to the server in order to update c/mtime. */ |
499 | * Flush out writes to the server in order to update c/mtime. | ||
500 | * | ||
501 | * Hold the i_mutex to suspend application writes temporarily; | ||
502 | * this prevents long-running writing applications from blocking | ||
503 | * nfs_wb_nocommit. | ||
504 | */ | ||
505 | if (S_ISREG(inode->i_mode)) { | 499 | if (S_ISREG(inode->i_mode)) { |
506 | mutex_lock(&inode->i_mutex); | 500 | err = filemap_write_and_wait(inode->i_mapping); |
507 | nfs_wb_nocommit(inode); | 501 | if (err) |
508 | mutex_unlock(&inode->i_mutex); | 502 | goto out; |
509 | } | 503 | } |
510 | 504 | ||
511 | /* | 505 | /* |
@@ -529,6 +523,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
529 | generic_fillattr(inode, stat); | 523 | generic_fillattr(inode, stat); |
530 | stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); | 524 | stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); |
531 | } | 525 | } |
526 | out: | ||
532 | return err; | 527 | return err; |
533 | } | 528 | } |
534 | 529 | ||
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index dc7f5e9a23b4..0b323091b481 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -1454,7 +1454,6 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr | |||
1454 | pgoff_t idx_start, idx_end; | 1454 | pgoff_t idx_start, idx_end; |
1455 | unsigned int npages = 0; | 1455 | unsigned int npages = 0; |
1456 | LIST_HEAD(head); | 1456 | LIST_HEAD(head); |
1457 | int nocommit = how & FLUSH_NOCOMMIT; | ||
1458 | long pages, ret; | 1457 | long pages, ret; |
1459 | 1458 | ||
1460 | /* FIXME */ | 1459 | /* FIXME */ |
@@ -1471,14 +1470,11 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr | |||
1471 | npages = 0; | 1470 | npages = 0; |
1472 | } | 1471 | } |
1473 | } | 1472 | } |
1474 | how &= ~FLUSH_NOCOMMIT; | ||
1475 | spin_lock(&inode->i_lock); | 1473 | spin_lock(&inode->i_lock); |
1476 | do { | 1474 | do { |
1477 | ret = nfs_wait_on_requests_locked(inode, idx_start, npages); | 1475 | ret = nfs_wait_on_requests_locked(inode, idx_start, npages); |
1478 | if (ret != 0) | 1476 | if (ret != 0) |
1479 | continue; | 1477 | continue; |
1480 | if (nocommit) | ||
1481 | break; | ||
1482 | pages = nfs_scan_commit(inode, &head, idx_start, npages); | 1478 | pages = nfs_scan_commit(inode, &head, idx_start, npages); |
1483 | if (pages == 0) | 1479 | if (pages == 0) |
1484 | break; | 1480 | break; |
@@ -1492,47 +1488,19 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr | |||
1492 | return ret; | 1488 | return ret; |
1493 | } | 1489 | } |
1494 | 1490 | ||
1495 | static int __nfs_write_mapping(struct address_space *mapping, struct writeback_control *wbc, int how) | 1491 | /* |
1496 | { | 1492 | * flush the inode to disk. |
1497 | int ret; | 1493 | */ |
1498 | 1494 | int nfs_wb_all(struct inode *inode) | |
1499 | ret = nfs_writepages(mapping, wbc); | ||
1500 | if (ret < 0) | ||
1501 | goto out; | ||
1502 | ret = nfs_sync_mapping_wait(mapping, wbc, how); | ||
1503 | if (ret < 0) | ||
1504 | goto out; | ||
1505 | return 0; | ||
1506 | out: | ||
1507 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); | ||
1508 | return ret; | ||
1509 | } | ||
1510 | |||
1511 | /* Two pass sync: first using WB_SYNC_NONE, then WB_SYNC_ALL */ | ||
1512 | static int nfs_write_mapping(struct address_space *mapping, int how) | ||
1513 | { | 1495 | { |
1514 | struct writeback_control wbc = { | 1496 | struct writeback_control wbc = { |
1515 | .bdi = mapping->backing_dev_info, | ||
1516 | .sync_mode = WB_SYNC_ALL, | 1497 | .sync_mode = WB_SYNC_ALL, |
1517 | .nr_to_write = LONG_MAX, | 1498 | .nr_to_write = LONG_MAX, |
1518 | .range_start = 0, | 1499 | .range_start = 0, |
1519 | .range_end = LLONG_MAX, | 1500 | .range_end = LLONG_MAX, |
1520 | }; | 1501 | }; |
1521 | 1502 | ||
1522 | return __nfs_write_mapping(mapping, &wbc, how); | 1503 | return sync_inode(inode, &wbc); |
1523 | } | ||
1524 | |||
1525 | /* | ||
1526 | * flush the inode to disk. | ||
1527 | */ | ||
1528 | int nfs_wb_all(struct inode *inode) | ||
1529 | { | ||
1530 | return nfs_write_mapping(inode->i_mapping, 0); | ||
1531 | } | ||
1532 | |||
1533 | int nfs_wb_nocommit(struct inode *inode) | ||
1534 | { | ||
1535 | return nfs_write_mapping(inode->i_mapping, FLUSH_NOCOMMIT); | ||
1536 | } | 1504 | } |
1537 | 1505 | ||
1538 | int nfs_wb_page_cancel(struct inode *inode, struct page *page) | 1506 | int nfs_wb_page_cancel(struct inode *inode, struct page *page) |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 1083134c02ff..93f439e7c5bf 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -33,7 +33,6 @@ | |||
33 | #define FLUSH_STABLE 4 /* commit to stable storage */ | 33 | #define FLUSH_STABLE 4 /* commit to stable storage */ |
34 | #define FLUSH_LOWPRI 8 /* low priority background flush */ | 34 | #define FLUSH_LOWPRI 8 /* low priority background flush */ |
35 | #define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */ | 35 | #define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */ |
36 | #define FLUSH_NOCOMMIT 32 /* Don't send the NFSv3/v4 COMMIT */ | ||
37 | 36 | ||
38 | #ifdef __KERNEL__ | 37 | #ifdef __KERNEL__ |
39 | 38 | ||
@@ -478,7 +477,6 @@ extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *); | |||
478 | */ | 477 | */ |
479 | extern long nfs_sync_mapping_wait(struct address_space *, struct writeback_control *, int); | 478 | extern long nfs_sync_mapping_wait(struct address_space *, struct writeback_control *, int); |
480 | extern int nfs_wb_all(struct inode *inode); | 479 | extern int nfs_wb_all(struct inode *inode); |
481 | extern int nfs_wb_nocommit(struct inode *inode); | ||
482 | extern int nfs_wb_page(struct inode *inode, struct page* page); | 480 | extern int nfs_wb_page(struct inode *inode, struct page* page); |
483 | extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); | 481 | extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); |
484 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 482 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |