aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-03 03:55:21 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-06 14:58:45 -0500
commit26e976a884be9aa08f8ff906372f25f68df0d948 (patch)
treeef675345b5c6126dca86699e077b75a375b504b9 /fs/nfs
parent2bd615797ef32ec06ef0ee44198a7aecc21ffd8c (diff)
NFSv4: OPEN/LOCK/LOCKU/CLOSE will automatically renew the NFSv4 lease
Cut down on the number of unnecessary RENEW requests on the wire. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f060e6538edc..76d7d0259b6c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -174,8 +174,7 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
174 kunmap_atomic(start, KM_USER0); 174 kunmap_atomic(start, KM_USER0);
175} 175}
176 176
177static void 177static void renew_lease(const struct nfs_server *server, unsigned long timestamp)
178renew_lease(struct nfs_server *server, unsigned long timestamp)
179{ 178{
180 struct nfs4_client *clp = server->nfs4_state; 179 struct nfs4_client *clp = server->nfs4_state;
181 spin_lock(&clp->cl_lock); 180 spin_lock(&clp->cl_lock);
@@ -207,6 +206,7 @@ struct nfs4_opendata {
207 struct dentry *dir; 206 struct dentry *dir;
208 struct nfs4_state_owner *owner; 207 struct nfs4_state_owner *owner;
209 struct iattr attrs; 208 struct iattr attrs;
209 unsigned long timestamp;
210 int rpc_status; 210 int rpc_status;
211 int cancelled; 211 int cancelled;
212}; 212};
@@ -548,6 +548,7 @@ static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
548 .rpc_resp = &data->c_res, 548 .rpc_resp = &data->c_res,
549 .rpc_cred = data->owner->so_cred, 549 .rpc_cred = data->owner->so_cred,
550 }; 550 };
551 data->timestamp = jiffies;
551 rpc_call_setup(task, &msg, 0); 552 rpc_call_setup(task, &msg, 0);
552} 553}
553 554
@@ -558,9 +559,11 @@ static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
558 data->rpc_status = task->tk_status; 559 data->rpc_status = task->tk_status;
559 if (RPC_ASSASSINATED(task)) 560 if (RPC_ASSASSINATED(task))
560 return; 561 return;
561 if (data->rpc_status == 0) 562 if (data->rpc_status == 0) {
562 memcpy(data->o_res.stateid.data, data->c_res.stateid.data, 563 memcpy(data->o_res.stateid.data, data->c_res.stateid.data,
563 sizeof(data->o_res.stateid.data)); 564 sizeof(data->o_res.stateid.data));
565 renew_lease(data->o_res.server, data->timestamp);
566 }
564 nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid); 567 nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid);
565 nfs_confirm_seqid(&data->owner->so_seqid, data->rpc_status); 568 nfs_confirm_seqid(&data->owner->so_seqid, data->rpc_status);
566} 569}
@@ -633,6 +636,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
633 data->o_arg.clientid = sp->so_client->cl_clientid; 636 data->o_arg.clientid = sp->so_client->cl_clientid;
634 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) 637 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS)
635 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; 638 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
639 data->timestamp = jiffies;
636 rpc_call_setup(task, &msg, 0); 640 rpc_call_setup(task, &msg, 0);
637} 641}
638 642
@@ -656,6 +660,7 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
656 default: 660 default:
657 data->rpc_status = -ENOTDIR; 661 data->rpc_status = -ENOTDIR;
658 } 662 }
663 renew_lease(data->o_res.server, data->timestamp);
659 } 664 }
660 nfs_increment_open_seqid(data->rpc_status, data->o_arg.seqid); 665 nfs_increment_open_seqid(data->rpc_status, data->o_arg.seqid);
661} 666}
@@ -1014,6 +1019,7 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
1014 .rpc_argp = &arg, 1019 .rpc_argp = &arg,
1015 .rpc_resp = &res, 1020 .rpc_resp = &res,
1016 }; 1021 };
1022 unsigned long timestamp = jiffies;
1017 int status; 1023 int status;
1018 1024
1019 nfs_fattr_init(fattr); 1025 nfs_fattr_init(fattr);
@@ -1025,6 +1031,8 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
1025 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid)); 1031 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
1026 1032
1027 status = rpc_call_sync(server->client, &msg, 0); 1033 status = rpc_call_sync(server->client, &msg, 0);
1034 if (status == 0 && state != NULL)
1035 renew_lease(server, timestamp);
1028 return status; 1036 return status;
1029} 1037}
1030 1038
@@ -1049,6 +1057,7 @@ struct nfs4_closedata {
1049 struct nfs_closeargs arg; 1057 struct nfs_closeargs arg;
1050 struct nfs_closeres res; 1058 struct nfs_closeres res;
1051 struct nfs_fattr fattr; 1059 struct nfs_fattr fattr;
1060 unsigned long timestamp;
1052}; 1061};
1053 1062
1054static void nfs4_free_closedata(void *data) 1063static void nfs4_free_closedata(void *data)
@@ -1078,6 +1087,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1078 case 0: 1087 case 0:
1079 memcpy(&state->stateid, &calldata->res.stateid, 1088 memcpy(&state->stateid, &calldata->res.stateid,
1080 sizeof(state->stateid)); 1089 sizeof(state->stateid));
1090 renew_lease(server, calldata->timestamp);
1081 break; 1091 break;
1082 case -NFS4ERR_STALE_STATEID: 1092 case -NFS4ERR_STALE_STATEID:
1083 case -NFS4ERR_EXPIRED: 1093 case -NFS4ERR_EXPIRED:
@@ -1130,6 +1140,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
1130 if (mode != 0) 1140 if (mode != 0)
1131 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; 1141 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1132 calldata->arg.open_flags = mode; 1142 calldata->arg.open_flags = mode;
1143 calldata->timestamp = jiffies;
1133 rpc_call_setup(task, &msg, 0); 1144 rpc_call_setup(task, &msg, 0);
1134} 1145}
1135 1146
@@ -1694,11 +1705,13 @@ static int _nfs4_proc_write(struct nfs_write_data *wdata)
1694 1705
1695 wdata->args.bitmask = server->attr_bitmask; 1706 wdata->args.bitmask = server->attr_bitmask;
1696 wdata->res.server = server; 1707 wdata->res.server = server;
1708 wdata->timestamp = jiffies;
1697 nfs_fattr_init(fattr); 1709 nfs_fattr_init(fattr);
1698 status = rpc_call_sync(server->client, &msg, rpcflags); 1710 status = rpc_call_sync(server->client, &msg, rpcflags);
1699 dprintk("NFS reply write: %d\n", status); 1711 dprintk("NFS reply write: %d\n", status);
1700 if (status < 0) 1712 if (status < 0)
1701 return status; 1713 return status;
1714 renew_lease(server, wdata->timestamp);
1702 nfs_post_op_update_inode(inode, fattr); 1715 nfs_post_op_update_inode(inode, fattr);
1703 return wdata->res.count; 1716 return wdata->res.count;
1704} 1717}
@@ -1733,8 +1746,11 @@ static int _nfs4_proc_commit(struct nfs_write_data *cdata)
1733 1746
1734 cdata->args.bitmask = server->attr_bitmask; 1747 cdata->args.bitmask = server->attr_bitmask;
1735 cdata->res.server = server; 1748 cdata->res.server = server;
1749 cdata->timestamp = jiffies;
1736 nfs_fattr_init(fattr); 1750 nfs_fattr_init(fattr);
1737 status = rpc_call_sync(server->client, &msg, 0); 1751 status = rpc_call_sync(server->client, &msg, 0);
1752 if (status >= 0)
1753 renew_lease(server, cdata->timestamp);
1738 dprintk("NFS reply commit: %d\n", status); 1754 dprintk("NFS reply commit: %d\n", status);
1739 if (status >= 0) 1755 if (status >= 0)
1740 nfs_post_op_update_inode(inode, fattr); 1756 nfs_post_op_update_inode(inode, fattr);
@@ -2890,6 +2906,8 @@ struct nfs4_delegreturndata {
2890 struct nfs_fh fh; 2906 struct nfs_fh fh;
2891 nfs4_stateid stateid; 2907 nfs4_stateid stateid;
2892 struct rpc_cred *cred; 2908 struct rpc_cred *cred;
2909 unsigned long timestamp;
2910 const struct nfs_server *server;
2893 int rpc_status; 2911 int rpc_status;
2894}; 2912};
2895 2913
@@ -2908,6 +2926,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
2908{ 2926{
2909 struct nfs4_delegreturndata *data = calldata; 2927 struct nfs4_delegreturndata *data = calldata;
2910 data->rpc_status = task->tk_status; 2928 data->rpc_status = task->tk_status;
2929 if (data->rpc_status == 0)
2930 renew_lease(data->server, data->timestamp);
2911} 2931}
2912 2932
2913static void nfs4_delegreturn_release(void *calldata) 2933static void nfs4_delegreturn_release(void *calldata)
@@ -2938,6 +2958,8 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
2938 nfs_copy_fh(&data->fh, NFS_FH(inode)); 2958 nfs_copy_fh(&data->fh, NFS_FH(inode));
2939 memcpy(&data->stateid, stateid, sizeof(data->stateid)); 2959 memcpy(&data->stateid, stateid, sizeof(data->stateid));
2940 data->cred = get_rpccred(cred); 2960 data->cred = get_rpccred(cred);
2961 data->timestamp = jiffies;
2962 data->server = NFS_SERVER(inode);
2941 data->rpc_status = 0; 2963 data->rpc_status = 0;
2942 2964
2943 task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data); 2965 task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data);
@@ -3067,6 +3089,7 @@ struct nfs4_unlockdata {
3067 struct nfs_open_context *ctx; 3089 struct nfs_open_context *ctx;
3068 struct file_lock fl; 3090 struct file_lock fl;
3069 const struct nfs_server *server; 3091 const struct nfs_server *server;
3092 unsigned long timestamp;
3070}; 3093};
3071 3094
3072static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl, 3095static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
@@ -3114,6 +3137,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3114 memcpy(calldata->lsp->ls_stateid.data, 3137 memcpy(calldata->lsp->ls_stateid.data,
3115 calldata->res.stateid.data, 3138 calldata->res.stateid.data,
3116 sizeof(calldata->lsp->ls_stateid.data)); 3139 sizeof(calldata->lsp->ls_stateid.data));
3140 renew_lease(calldata->server, calldata->timestamp);
3117 break; 3141 break;
3118 case -NFS4ERR_STALE_STATEID: 3142 case -NFS4ERR_STALE_STATEID:
3119 case -NFS4ERR_EXPIRED: 3143 case -NFS4ERR_EXPIRED:
@@ -3143,6 +3167,7 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
3143 task->tk_action = NULL; 3167 task->tk_action = NULL;
3144 return; 3168 return;
3145 } 3169 }
3170 calldata->timestamp = jiffies;
3146 rpc_call_setup(task, &msg, 0); 3171 rpc_call_setup(task, &msg, 0);
3147} 3172}
3148 3173
@@ -3214,6 +3239,7 @@ struct nfs4_lockdata {
3214 struct nfs4_lock_state *lsp; 3239 struct nfs4_lock_state *lsp;
3215 struct nfs_open_context *ctx; 3240 struct nfs_open_context *ctx;
3216 struct file_lock fl; 3241 struct file_lock fl;
3242 unsigned long timestamp;
3217 int rpc_status; 3243 int rpc_status;
3218 int cancelled; 3244 int cancelled;
3219}; 3245};
@@ -3273,6 +3299,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
3273 data->arg.open_stateid = &state->stateid; 3299 data->arg.open_stateid = &state->stateid;
3274 data->arg.new_lock_owner = 1; 3300 data->arg.new_lock_owner = 1;
3275 } 3301 }
3302 data->timestamp = jiffies;
3276 rpc_call_setup(task, &msg, 0); 3303 rpc_call_setup(task, &msg, 0);
3277out: 3304out:
3278 dprintk("%s: done!, ret = %d\n", __FUNCTION__, data->rpc_status); 3305 dprintk("%s: done!, ret = %d\n", __FUNCTION__, data->rpc_status);
@@ -3298,6 +3325,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3298 memcpy(data->lsp->ls_stateid.data, data->res.stateid.data, 3325 memcpy(data->lsp->ls_stateid.data, data->res.stateid.data,
3299 sizeof(data->lsp->ls_stateid.data)); 3326 sizeof(data->lsp->ls_stateid.data));
3300 data->lsp->ls_flags |= NFS_LOCK_INITIALIZED; 3327 data->lsp->ls_flags |= NFS_LOCK_INITIALIZED;
3328 renew_lease(NFS_SERVER(data->ctx->dentry->d_inode), data->timestamp);
3301 } 3329 }
3302 nfs_increment_lock_seqid(data->rpc_status, data->arg.lock_seqid); 3330 nfs_increment_lock_seqid(data->rpc_status, data->arg.lock_seqid);
3303out: 3331out: