diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-12-23 15:21:45 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-12-23 15:21:45 -0500 |
commit | 95d35cb4c473c754824967c0b069bbeb7efa4847 (patch) | |
tree | bd46a5b0e4d35f9256cf44ca2706493fc3dd2819 /fs/nfs | |
parent | 19e03c570e6099ffaf24e5628d4fe1a8acbe820d (diff) |
NFSv4: Remove nfs_client->cl_sem
Now that we're using the flags to indicate state that needs to be
recovered, as well as having implemented proper refcounting and spinlocking
on the state and open_owners, we can get rid of nfs_client->cl_sem. The
only remaining case that was dubious was the file locking, and that case is
now covered by the nfsi->rwsem.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/client.c | 1 | ||||
-rw-r--r-- | fs/nfs/delegation.c | 5 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 20 | ||||
-rw-r--r-- | fs/nfs/nfs4renewd.c | 3 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 17 |
5 files changed, 1 insertions, 45 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 70b6d9e8517d..b643f0ec5c21 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -143,7 +143,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_ | |||
143 | clp->cl_proto = cl_init->proto; | 143 | clp->cl_proto = cl_init->proto; |
144 | 144 | ||
145 | #ifdef CONFIG_NFS_V4 | 145 | #ifdef CONFIG_NFS_V4 |
146 | init_rwsem(&clp->cl_sem); | ||
147 | INIT_LIST_HEAD(&clp->cl_delegations); | 146 | INIT_LIST_HEAD(&clp->cl_delegations); |
148 | spin_lock_init(&clp->cl_lock); | 147 | spin_lock_init(&clp->cl_lock); |
149 | INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); | 148 | INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 646ba3e75a1e..ebc06f2da31a 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -243,16 +243,13 @@ static void nfs_msync_inode(struct inode *inode) | |||
243 | */ | 243 | */ |
244 | static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation) | 244 | static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation) |
245 | { | 245 | { |
246 | struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; | ||
247 | struct nfs_inode *nfsi = NFS_I(inode); | 246 | struct nfs_inode *nfsi = NFS_I(inode); |
248 | 247 | ||
249 | nfs_msync_inode(inode); | 248 | nfs_msync_inode(inode); |
250 | down_read(&clp->cl_sem); | ||
251 | /* Guard against new delegated open calls */ | 249 | /* Guard against new delegated open calls */ |
252 | down_write(&nfsi->rwsem); | 250 | down_write(&nfsi->rwsem); |
253 | nfs_delegation_claim_opens(inode, &delegation->stateid); | 251 | nfs_delegation_claim_opens(inode, &delegation->stateid); |
254 | up_write(&nfsi->rwsem); | 252 | up_write(&nfsi->rwsem); |
255 | up_read(&clp->cl_sem); | ||
256 | nfs_msync_inode(inode); | 253 | nfs_msync_inode(inode); |
257 | 254 | ||
258 | return nfs_do_return_delegation(inode, delegation, 1); | 255 | return nfs_do_return_delegation(inode, delegation, 1); |
@@ -425,7 +422,6 @@ static int recall_thread(void *data) | |||
425 | daemonize("nfsv4-delegreturn"); | 422 | daemonize("nfsv4-delegreturn"); |
426 | 423 | ||
427 | nfs_msync_inode(inode); | 424 | nfs_msync_inode(inode); |
428 | down_read(&clp->cl_sem); | ||
429 | down_write(&nfsi->rwsem); | 425 | down_write(&nfsi->rwsem); |
430 | spin_lock(&clp->cl_lock); | 426 | spin_lock(&clp->cl_lock); |
431 | delegation = nfs_detach_delegation_locked(nfsi, args->stateid); | 427 | delegation = nfs_detach_delegation_locked(nfsi, args->stateid); |
@@ -437,7 +433,6 @@ static int recall_thread(void *data) | |||
437 | complete(&args->started); | 433 | complete(&args->started); |
438 | nfs_delegation_claim_opens(inode, args->stateid); | 434 | nfs_delegation_claim_opens(inode, args->stateid); |
439 | up_write(&nfsi->rwsem); | 435 | up_write(&nfsi->rwsem); |
440 | up_read(&clp->cl_sem); | ||
441 | nfs_msync_inode(inode); | 436 | nfs_msync_inode(inode); |
442 | 437 | ||
443 | if (delegation != NULL) | 438 | if (delegation != NULL) |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index aec4e47c462d..26dcd77abb07 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -207,12 +207,8 @@ static int nfs4_wait_clnt_recover(struct nfs_client *clp) | |||
207 | 207 | ||
208 | might_sleep(); | 208 | might_sleep(); |
209 | 209 | ||
210 | rwsem_acquire(&clp->cl_sem.dep_map, 0, 0, _RET_IP_); | ||
211 | |||
212 | res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER, | 210 | res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER, |
213 | nfs4_wait_bit_killable, TASK_KILLABLE); | 211 | nfs4_wait_bit_killable, TASK_KILLABLE); |
214 | |||
215 | rwsem_release(&clp->cl_sem.dep_map, 1, _RET_IP_); | ||
216 | return res; | 212 | return res; |
217 | } | 213 | } |
218 | 214 | ||
@@ -1135,7 +1131,6 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct | |||
1135 | struct nfs4_state_owner *sp; | 1131 | struct nfs4_state_owner *sp; |
1136 | struct nfs4_state *state = NULL; | 1132 | struct nfs4_state *state = NULL; |
1137 | struct nfs_server *server = NFS_SERVER(dir); | 1133 | struct nfs_server *server = NFS_SERVER(dir); |
1138 | struct nfs_client *clp = server->nfs_client; | ||
1139 | struct nfs4_opendata *opendata; | 1134 | struct nfs4_opendata *opendata; |
1140 | int status; | 1135 | int status; |
1141 | 1136 | ||
@@ -1150,11 +1145,10 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct | |||
1150 | goto err_put_state_owner; | 1145 | goto err_put_state_owner; |
1151 | if (path->dentry->d_inode != NULL) | 1146 | if (path->dentry->d_inode != NULL) |
1152 | nfs4_return_incompatible_delegation(path->dentry->d_inode, flags & (FMODE_READ|FMODE_WRITE)); | 1147 | nfs4_return_incompatible_delegation(path->dentry->d_inode, flags & (FMODE_READ|FMODE_WRITE)); |
1153 | down_read(&clp->cl_sem); | ||
1154 | status = -ENOMEM; | 1148 | status = -ENOMEM; |
1155 | opendata = nfs4_opendata_alloc(path, sp, flags, sattr); | 1149 | opendata = nfs4_opendata_alloc(path, sp, flags, sattr); |
1156 | if (opendata == NULL) | 1150 | if (opendata == NULL) |
1157 | goto err_release_rwsem; | 1151 | goto err_put_state_owner; |
1158 | 1152 | ||
1159 | if (path->dentry->d_inode != NULL) | 1153 | if (path->dentry->d_inode != NULL) |
1160 | opendata->state = nfs4_get_open_state(path->dentry->d_inode, sp); | 1154 | opendata->state = nfs4_get_open_state(path->dentry->d_inode, sp); |
@@ -1172,13 +1166,10 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct | |||
1172 | goto err_opendata_put; | 1166 | goto err_opendata_put; |
1173 | nfs4_opendata_put(opendata); | 1167 | nfs4_opendata_put(opendata); |
1174 | nfs4_put_state_owner(sp); | 1168 | nfs4_put_state_owner(sp); |
1175 | up_read(&clp->cl_sem); | ||
1176 | *res = state; | 1169 | *res = state; |
1177 | return 0; | 1170 | return 0; |
1178 | err_opendata_put: | 1171 | err_opendata_put: |
1179 | nfs4_opendata_put(opendata); | 1172 | nfs4_opendata_put(opendata); |
1180 | err_release_rwsem: | ||
1181 | up_read(&clp->cl_sem); | ||
1182 | err_put_state_owner: | 1173 | err_put_state_owner: |
1183 | nfs4_put_state_owner(sp); | 1174 | nfs4_put_state_owner(sp); |
1184 | out_err: | 1175 | out_err: |
@@ -3099,7 +3090,6 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock | |||
3099 | struct nfs4_lock_state *lsp; | 3090 | struct nfs4_lock_state *lsp; |
3100 | int status; | 3091 | int status; |
3101 | 3092 | ||
3102 | down_read(&clp->cl_sem); | ||
3103 | arg.lock_owner.clientid = clp->cl_clientid; | 3093 | arg.lock_owner.clientid = clp->cl_clientid; |
3104 | status = nfs4_set_lock_state(state, request); | 3094 | status = nfs4_set_lock_state(state, request); |
3105 | if (status != 0) | 3095 | if (status != 0) |
@@ -3116,7 +3106,6 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock | |||
3116 | } | 3106 | } |
3117 | request->fl_ops->fl_release_private(request); | 3107 | request->fl_ops->fl_release_private(request); |
3118 | out: | 3108 | out: |
3119 | up_read(&clp->cl_sem); | ||
3120 | return status; | 3109 | return status; |
3121 | } | 3110 | } |
3122 | 3111 | ||
@@ -3273,7 +3262,6 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl, | |||
3273 | 3262 | ||
3274 | static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request) | 3263 | static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request) |
3275 | { | 3264 | { |
3276 | struct nfs_client *clp = state->owner->so_client; | ||
3277 | struct nfs_inode *nfsi = NFS_I(state->inode); | 3265 | struct nfs_inode *nfsi = NFS_I(state->inode); |
3278 | struct nfs_seqid *seqid; | 3266 | struct nfs_seqid *seqid; |
3279 | struct nfs4_lock_state *lsp; | 3267 | struct nfs4_lock_state *lsp; |
@@ -3284,15 +3272,12 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock * | |||
3284 | status = nfs4_set_lock_state(state, request); | 3272 | status = nfs4_set_lock_state(state, request); |
3285 | /* Unlock _before_ we do the RPC call */ | 3273 | /* Unlock _before_ we do the RPC call */ |
3286 | request->fl_flags |= FL_EXISTS; | 3274 | request->fl_flags |= FL_EXISTS; |
3287 | down_read(&clp->cl_sem); | ||
3288 | down_read(&nfsi->rwsem); | 3275 | down_read(&nfsi->rwsem); |
3289 | if (do_vfs_lock(request->fl_file, request) == -ENOENT) { | 3276 | if (do_vfs_lock(request->fl_file, request) == -ENOENT) { |
3290 | up_read(&nfsi->rwsem); | 3277 | up_read(&nfsi->rwsem); |
3291 | up_read(&clp->cl_sem); | ||
3292 | goto out; | 3278 | goto out; |
3293 | } | 3279 | } |
3294 | up_read(&nfsi->rwsem); | 3280 | up_read(&nfsi->rwsem); |
3295 | up_read(&clp->cl_sem); | ||
3296 | if (status != 0) | 3281 | if (status != 0) |
3297 | goto out; | 3282 | goto out; |
3298 | /* Is this a delegated lock? */ | 3283 | /* Is this a delegated lock? */ |
@@ -3518,7 +3503,6 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request | |||
3518 | 3503 | ||
3519 | static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) | 3504 | static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) |
3520 | { | 3505 | { |
3521 | struct nfs_client *clp = state->owner->so_client; | ||
3522 | struct nfs_inode *nfsi = NFS_I(state->inode); | 3506 | struct nfs_inode *nfsi = NFS_I(state->inode); |
3523 | unsigned char fl_flags = request->fl_flags; | 3507 | unsigned char fl_flags = request->fl_flags; |
3524 | int status; | 3508 | int status; |
@@ -3531,7 +3515,6 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock | |||
3531 | status = do_vfs_lock(request->fl_file, request); | 3515 | status = do_vfs_lock(request->fl_file, request); |
3532 | if (status < 0) | 3516 | if (status < 0) |
3533 | goto out; | 3517 | goto out; |
3534 | down_read(&clp->cl_sem); | ||
3535 | down_read(&nfsi->rwsem); | 3518 | down_read(&nfsi->rwsem); |
3536 | if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { | 3519 | if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { |
3537 | /* Yes: cache locks! */ | 3520 | /* Yes: cache locks! */ |
@@ -3549,7 +3532,6 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock | |||
3549 | printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __func__); | 3532 | printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __func__); |
3550 | out_unlock: | 3533 | out_unlock: |
3551 | up_read(&nfsi->rwsem); | 3534 | up_read(&nfsi->rwsem); |
3552 | up_read(&clp->cl_sem); | ||
3553 | out: | 3535 | out: |
3554 | request->fl_flags = fl_flags; | 3536 | request->fl_flags = fl_flags; |
3555 | return status; | 3537 | return status; |
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index 9fe8640a88eb..6101f955f231 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c | |||
@@ -65,7 +65,6 @@ nfs4_renew_state(struct work_struct *work) | |||
65 | long lease, timeout; | 65 | long lease, timeout; |
66 | unsigned long last, now; | 66 | unsigned long last, now; |
67 | 67 | ||
68 | down_read(&clp->cl_sem); | ||
69 | dprintk("%s: start\n", __func__); | 68 | dprintk("%s: start\n", __func__); |
70 | /* Are there any active superblocks? */ | 69 | /* Are there any active superblocks? */ |
71 | if (list_empty(&clp->cl_superblocks)) | 70 | if (list_empty(&clp->cl_superblocks)) |
@@ -101,11 +100,9 @@ nfs4_renew_state(struct work_struct *work) | |||
101 | schedule_delayed_work(&clp->cl_renewd, timeout); | 100 | schedule_delayed_work(&clp->cl_renewd, timeout); |
102 | spin_unlock(&clp->cl_lock); | 101 | spin_unlock(&clp->cl_lock); |
103 | out: | 102 | out: |
104 | up_read(&clp->cl_sem); | ||
105 | dprintk("%s: done\n", __func__); | 103 | dprintk("%s: done\n", __func__); |
106 | } | 104 | } |
107 | 105 | ||
108 | /* Must be called with clp->cl_sem locked for writes */ | ||
109 | void | 106 | void |
110 | nfs4_schedule_state_renewal(struct nfs_client *clp) | 107 | nfs4_schedule_state_renewal(struct nfs_client *clp) |
111 | { | 108 | { |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 16c9fbdf97b4..ec0cbe00a804 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -305,10 +305,6 @@ nfs4_drop_state_owner(struct nfs4_state_owner *sp) | |||
305 | } | 305 | } |
306 | } | 306 | } |
307 | 307 | ||
308 | /* | ||
309 | * Note: must be called with clp->cl_sem held in order to prevent races | ||
310 | * with reboot recovery! | ||
311 | */ | ||
312 | struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred) | 308 | struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred) |
313 | { | 309 | { |
314 | struct nfs_client *clp = server->nfs_client; | 310 | struct nfs_client *clp = server->nfs_client; |
@@ -337,10 +333,6 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct | |||
337 | return sp; | 333 | return sp; |
338 | } | 334 | } |
339 | 335 | ||
340 | /* | ||
341 | * Must be called with clp->cl_sem held in order to avoid races | ||
342 | * with state recovery... | ||
343 | */ | ||
344 | void nfs4_put_state_owner(struct nfs4_state_owner *sp) | 336 | void nfs4_put_state_owner(struct nfs4_state_owner *sp) |
345 | { | 337 | { |
346 | struct nfs_client *clp = sp->so_client; | 338 | struct nfs_client *clp = sp->so_client; |
@@ -442,10 +434,6 @@ out: | |||
442 | return state; | 434 | return state; |
443 | } | 435 | } |
444 | 436 | ||
445 | /* | ||
446 | * Beware! Caller must be holding exactly one | ||
447 | * reference to clp->cl_sem! | ||
448 | */ | ||
449 | void nfs4_put_open_state(struct nfs4_state *state) | 437 | void nfs4_put_open_state(struct nfs4_state *state) |
450 | { | 438 | { |
451 | struct inode *inode = state->inode; | 439 | struct inode *inode = state->inode; |
@@ -578,7 +566,6 @@ static void nfs4_free_lock_state(struct nfs4_lock_state *lsp) | |||
578 | * Return a compatible lock_state. If no initialized lock_state structure | 566 | * Return a compatible lock_state. If no initialized lock_state structure |
579 | * exists, return an uninitialized one. | 567 | * exists, return an uninitialized one. |
580 | * | 568 | * |
581 | * The caller must be holding clp->cl_sem | ||
582 | */ | 569 | */ |
583 | static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner) | 570 | static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner) |
584 | { | 571 | { |
@@ -1127,7 +1114,6 @@ static int reclaimer(void *ptr) | |||
1127 | allow_signal(SIGKILL); | 1114 | allow_signal(SIGKILL); |
1128 | 1115 | ||
1129 | /* Ensure exclusive access to NFSv4 state */ | 1116 | /* Ensure exclusive access to NFSv4 state */ |
1130 | down_write(&clp->cl_sem); | ||
1131 | while (!list_empty(&clp->cl_superblocks)) { | 1117 | while (!list_empty(&clp->cl_superblocks)) { |
1132 | if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { | 1118 | if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { |
1133 | /* We're going to have to re-establish a clientid */ | 1119 | /* We're going to have to re-establish a clientid */ |
@@ -1149,7 +1135,6 @@ static int reclaimer(void *ptr) | |||
1149 | 1135 | ||
1150 | /* First recover reboot state... */ | 1136 | /* First recover reboot state... */ |
1151 | if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { | 1137 | if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { |
1152 | /* Note: list is protected by exclusive lock on cl->cl_sem */ | ||
1153 | status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops); | 1138 | status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops); |
1154 | if (status == -NFS4ERR_STALE_CLIENTID) | 1139 | if (status == -NFS4ERR_STALE_CLIENTID) |
1155 | continue; | 1140 | continue; |
@@ -1159,7 +1144,6 @@ static int reclaimer(void *ptr) | |||
1159 | 1144 | ||
1160 | /* Now recover expired state... */ | 1145 | /* Now recover expired state... */ |
1161 | if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { | 1146 | if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { |
1162 | /* Note: list is protected by exclusive lock on cl->cl_sem */ | ||
1163 | status = nfs4_do_reclaim(clp, &nfs4_nograce_recovery_ops); | 1147 | status = nfs4_do_reclaim(clp, &nfs4_nograce_recovery_ops); |
1164 | if (status < 0) { | 1148 | if (status < 0) { |
1165 | set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); | 1149 | set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); |
@@ -1175,7 +1159,6 @@ static int reclaimer(void *ptr) | |||
1175 | break; | 1159 | break; |
1176 | } | 1160 | } |
1177 | out: | 1161 | out: |
1178 | up_write(&clp->cl_sem); | ||
1179 | if (test_and_clear_bit(NFS4CLNT_CB_PATH_DOWN, &clp->cl_state)) | 1162 | if (test_and_clear_bit(NFS4CLNT_CB_PATH_DOWN, &clp->cl_state)) |
1180 | nfs_handle_cb_pathdown(clp); | 1163 | nfs_handle_cb_pathdown(clp); |
1181 | nfs4_clear_recover_bit(clp); | 1164 | nfs4_clear_recover_bit(clp); |