diff options
| -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) |
