diff options
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index f1bdb7254776..ac1dc331ba31 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include "fscache.h" | 31 | #include "fscache.h" |
32 | #include "pnfs.h" | 32 | #include "pnfs.h" |
33 | 33 | ||
34 | #include "nfstrace.h" | ||
35 | |||
34 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE | 36 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE |
35 | 37 | ||
36 | #define MIN_POOL_WRITE (32) | 38 | #define MIN_POOL_WRITE (32) |
@@ -861,7 +863,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page) | |||
861 | return 0; | 863 | return 0; |
862 | l_ctx = req->wb_lock_context; | 864 | l_ctx = req->wb_lock_context; |
863 | do_flush = req->wb_page != page || req->wb_context != ctx; | 865 | do_flush = req->wb_page != page || req->wb_context != ctx; |
864 | if (l_ctx) { | 866 | if (l_ctx && ctx->dentry->d_inode->i_flock != NULL) { |
865 | do_flush |= l_ctx->lockowner.l_owner != current->files | 867 | do_flush |= l_ctx->lockowner.l_owner != current->files |
866 | || l_ctx->lockowner.l_pid != current->tgid; | 868 | || l_ctx->lockowner.l_pid != current->tgid; |
867 | } | 869 | } |
@@ -874,6 +876,33 @@ int nfs_flush_incompatible(struct file *file, struct page *page) | |||
874 | } | 876 | } |
875 | 877 | ||
876 | /* | 878 | /* |
879 | * Avoid buffered writes when a open context credential's key would | ||
880 | * expire soon. | ||
881 | * | ||
882 | * Returns -EACCES if the key will expire within RPC_KEY_EXPIRE_FAIL. | ||
883 | * | ||
884 | * Return 0 and set a credential flag which triggers the inode to flush | ||
885 | * and performs NFS_FILE_SYNC writes if the key will expired within | ||
886 | * RPC_KEY_EXPIRE_TIMEO. | ||
887 | */ | ||
888 | int | ||
889 | nfs_key_timeout_notify(struct file *filp, struct inode *inode) | ||
890 | { | ||
891 | struct nfs_open_context *ctx = nfs_file_open_context(filp); | ||
892 | struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth; | ||
893 | |||
894 | return rpcauth_key_timeout_notify(auth, ctx->cred); | ||
895 | } | ||
896 | |||
897 | /* | ||
898 | * Test if the open context credential key is marked to expire soon. | ||
899 | */ | ||
900 | bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx) | ||
901 | { | ||
902 | return rpcauth_cred_key_to_expire(ctx->cred); | ||
903 | } | ||
904 | |||
905 | /* | ||
877 | * If the page cache is marked as unsafe or invalid, then we can't rely on | 906 | * If the page cache is marked as unsafe or invalid, then we can't rely on |
878 | * the PageUptodate() flag. In this case, we will need to turn off | 907 | * the PageUptodate() flag. In this case, we will need to turn off |
879 | * write optimisations that depend on the page contents being correct. | 908 | * write optimisations that depend on the page contents being correct. |
@@ -993,6 +1022,9 @@ int nfs_initiate_write(struct rpc_clnt *clnt, | |||
993 | data->args.count, | 1022 | data->args.count, |
994 | (unsigned long long)data->args.offset); | 1023 | (unsigned long long)data->args.offset); |
995 | 1024 | ||
1025 | nfs4_state_protect_write(NFS_SERVER(inode)->nfs_client, | ||
1026 | &task_setup_data.rpc_client, &msg, data); | ||
1027 | |||
996 | task = rpc_run_task(&task_setup_data); | 1028 | task = rpc_run_task(&task_setup_data); |
997 | if (IS_ERR(task)) { | 1029 | if (IS_ERR(task)) { |
998 | ret = PTR_ERR(task); | 1030 | ret = PTR_ERR(task); |
@@ -1265,9 +1297,10 @@ EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds); | |||
1265 | void nfs_write_prepare(struct rpc_task *task, void *calldata) | 1297 | void nfs_write_prepare(struct rpc_task *task, void *calldata) |
1266 | { | 1298 | { |
1267 | struct nfs_write_data *data = calldata; | 1299 | struct nfs_write_data *data = calldata; |
1268 | NFS_PROTO(data->header->inode)->write_rpc_prepare(task, data); | 1300 | int err; |
1269 | if (unlikely(test_bit(NFS_CONTEXT_BAD, &data->args.context->flags))) | 1301 | err = NFS_PROTO(data->header->inode)->write_rpc_prepare(task, data); |
1270 | rpc_exit(task, -EIO); | 1302 | if (err) |
1303 | rpc_exit(task, err); | ||
1271 | } | 1304 | } |
1272 | 1305 | ||
1273 | void nfs_commit_prepare(struct rpc_task *task, void *calldata) | 1306 | void nfs_commit_prepare(struct rpc_task *task, void *calldata) |
@@ -1458,6 +1491,9 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data, | |||
1458 | 1491 | ||
1459 | dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); | 1492 | dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); |
1460 | 1493 | ||
1494 | nfs4_state_protect(NFS_SERVER(data->inode)->nfs_client, | ||
1495 | NFS_SP4_MACH_CRED_COMMIT, &task_setup_data.rpc_client, &msg); | ||
1496 | |||
1461 | task = rpc_run_task(&task_setup_data); | 1497 | task = rpc_run_task(&task_setup_data); |
1462 | if (IS_ERR(task)) | 1498 | if (IS_ERR(task)) |
1463 | return PTR_ERR(task); | 1499 | return PTR_ERR(task); |
@@ -1732,8 +1768,14 @@ int nfs_wb_all(struct inode *inode) | |||
1732 | .range_start = 0, | 1768 | .range_start = 0, |
1733 | .range_end = LLONG_MAX, | 1769 | .range_end = LLONG_MAX, |
1734 | }; | 1770 | }; |
1771 | int ret; | ||
1735 | 1772 | ||
1736 | return sync_inode(inode, &wbc); | 1773 | trace_nfs_writeback_inode_enter(inode); |
1774 | |||
1775 | ret = sync_inode(inode, &wbc); | ||
1776 | |||
1777 | trace_nfs_writeback_inode_exit(inode, ret); | ||
1778 | return ret; | ||
1737 | } | 1779 | } |
1738 | EXPORT_SYMBOL_GPL(nfs_wb_all); | 1780 | EXPORT_SYMBOL_GPL(nfs_wb_all); |
1739 | 1781 | ||
@@ -1781,6 +1823,8 @@ int nfs_wb_page(struct inode *inode, struct page *page) | |||
1781 | }; | 1823 | }; |
1782 | int ret; | 1824 | int ret; |
1783 | 1825 | ||
1826 | trace_nfs_writeback_page_enter(inode); | ||
1827 | |||
1784 | for (;;) { | 1828 | for (;;) { |
1785 | wait_on_page_writeback(page); | 1829 | wait_on_page_writeback(page); |
1786 | if (clear_page_dirty_for_io(page)) { | 1830 | if (clear_page_dirty_for_io(page)) { |
@@ -1789,14 +1833,15 @@ int nfs_wb_page(struct inode *inode, struct page *page) | |||
1789 | goto out_error; | 1833 | goto out_error; |
1790 | continue; | 1834 | continue; |
1791 | } | 1835 | } |
1836 | ret = 0; | ||
1792 | if (!PagePrivate(page)) | 1837 | if (!PagePrivate(page)) |
1793 | break; | 1838 | break; |
1794 | ret = nfs_commit_inode(inode, FLUSH_SYNC); | 1839 | ret = nfs_commit_inode(inode, FLUSH_SYNC); |
1795 | if (ret < 0) | 1840 | if (ret < 0) |
1796 | goto out_error; | 1841 | goto out_error; |
1797 | } | 1842 | } |
1798 | return 0; | ||
1799 | out_error: | 1843 | out_error: |
1844 | trace_nfs_writeback_page_exit(inode, ret); | ||
1800 | return ret; | 1845 | return ret; |
1801 | } | 1846 | } |
1802 | 1847 | ||