diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-03 03:55:21 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-06 14:58:45 -0500 |
commit | 26e976a884be9aa08f8ff906372f25f68df0d948 (patch) | |
tree | ef675345b5c6126dca86699e077b75a375b504b9 /fs/nfs | |
parent | 2bd615797ef32ec06ef0ee44198a7aecc21ffd8c (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.c | 34 |
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 | ||
177 | static void | 177 | static void renew_lease(const struct nfs_server *server, unsigned long timestamp) |
178 | renew_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 | ||
1054 | static void nfs4_free_closedata(void *data) | 1063 | static 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 | ||
2913 | static void nfs4_delegreturn_release(void *calldata) | 2933 | static 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 | ||
3072 | static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl, | 3095 | static 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); |
3277 | out: | 3304 | out: |
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); |
3303 | out: | 3331 | out: |