aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorFred Isaman <iisaman@netapp.com>2011-01-06 06:36:32 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-01-06 14:46:32 -0500
commitf7e8917a67980924651a9e244510e63ef05c7755 (patch)
treefb00db5ef8b3b26793fae7a1186f1cd16205ab9d /fs/nfs/nfs4proc.c
parent36840370845629e6cb4324d1dd4aff6778670503 (diff)
pnfs: layout roc code
A layout can request return-on-close. How this interacts with the forgetful model of never sending LAYOUTRETURNS is a bit ambiguous. We forget any layouts marked roc, and wait for them to be completely forgotten before continuing with the close. In addition, to compensate for races with any inflight LAYOUTGETs, and the fact that we do not get any layout stateid back from the server, we set the barrier to the worst case scenario of current_seqid + number of outstanding LAYOUTGETS. Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a3549ce72ab..88f590feeb7 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1839,6 +1839,8 @@ struct nfs4_closedata {
1839 struct nfs_closeres res; 1839 struct nfs_closeres res;
1840 struct nfs_fattr fattr; 1840 struct nfs_fattr fattr;
1841 unsigned long timestamp; 1841 unsigned long timestamp;
1842 bool roc;
1843 u32 roc_barrier;
1842}; 1844};
1843 1845
1844static void nfs4_free_closedata(void *data) 1846static void nfs4_free_closedata(void *data)
@@ -1846,6 +1848,8 @@ static void nfs4_free_closedata(void *data)
1846 struct nfs4_closedata *calldata = data; 1848 struct nfs4_closedata *calldata = data;
1847 struct nfs4_state_owner *sp = calldata->state->owner; 1849 struct nfs4_state_owner *sp = calldata->state->owner;
1848 1850
1851 if (calldata->roc)
1852 pnfs_roc_release(calldata->state->inode);
1849 nfs4_put_open_state(calldata->state); 1853 nfs4_put_open_state(calldata->state);
1850 nfs_free_seqid(calldata->arg.seqid); 1854 nfs_free_seqid(calldata->arg.seqid);
1851 nfs4_put_state_owner(sp); 1855 nfs4_put_state_owner(sp);
@@ -1878,6 +1882,9 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1878 */ 1882 */
1879 switch (task->tk_status) { 1883 switch (task->tk_status) {
1880 case 0: 1884 case 0:
1885 if (calldata->roc)
1886 pnfs_roc_set_barrier(state->inode,
1887 calldata->roc_barrier);
1881 nfs_set_open_stateid(state, &calldata->res.stateid, 0); 1888 nfs_set_open_stateid(state, &calldata->res.stateid, 0);
1882 renew_lease(server, calldata->timestamp); 1889 renew_lease(server, calldata->timestamp);
1883 nfs4_close_clear_stateid_flags(state, 1890 nfs4_close_clear_stateid_flags(state,
@@ -1930,8 +1937,15 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
1930 return; 1937 return;
1931 } 1938 }
1932 1939
1933 if (calldata->arg.fmode == 0) 1940 if (calldata->arg.fmode == 0) {
1934 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE]; 1941 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
1942 if (calldata->roc &&
1943 pnfs_roc_drain(calldata->inode, &calldata->roc_barrier)) {
1944 rpc_sleep_on(&NFS_SERVER(calldata->inode)->roc_rpcwaitq,
1945 task, NULL);
1946 return;
1947 }
1948 }
1935 1949
1936 nfs_fattr_init(calldata->res.fattr); 1950 nfs_fattr_init(calldata->res.fattr);
1937 calldata->timestamp = jiffies; 1951 calldata->timestamp = jiffies;
@@ -1959,7 +1973,7 @@ static const struct rpc_call_ops nfs4_close_ops = {
1959 * 1973 *
1960 * NOTE: Caller must be holding the sp->so_owner semaphore! 1974 * NOTE: Caller must be holding the sp->so_owner semaphore!
1961 */ 1975 */
1962int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait) 1976int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc)
1963{ 1977{
1964 struct nfs_server *server = NFS_SERVER(state->inode); 1978 struct nfs_server *server = NFS_SERVER(state->inode);
1965 struct nfs4_closedata *calldata; 1979 struct nfs4_closedata *calldata;
@@ -1994,6 +2008,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, i
1994 calldata->res.fattr = &calldata->fattr; 2008 calldata->res.fattr = &calldata->fattr;
1995 calldata->res.seqid = calldata->arg.seqid; 2009 calldata->res.seqid = calldata->arg.seqid;
1996 calldata->res.server = server; 2010 calldata->res.server = server;
2011 calldata->roc = roc;
1997 path_get(path); 2012 path_get(path);
1998 calldata->path = *path; 2013 calldata->path = *path;
1999 2014
@@ -2011,6 +2026,8 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, i
2011out_free_calldata: 2026out_free_calldata:
2012 kfree(calldata); 2027 kfree(calldata);
2013out: 2028out:
2029 if (roc)
2030 pnfs_roc_release(state->inode);
2014 nfs4_put_open_state(state); 2031 nfs4_put_open_state(state);
2015 nfs4_put_state_owner(sp); 2032 nfs4_put_state_owner(sp);
2016 return status; 2033 return status;