aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-12-23 15:21:45 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-12-23 15:21:45 -0500
commit95d35cb4c473c754824967c0b069bbeb7efa4847 (patch)
treebd46a5b0e4d35f9256cf44ca2706493fc3dd2819
parent19e03c570e6099ffaf24e5628d4fe1a8acbe820d (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>
-rw-r--r--fs/nfs/client.c1
-rw-r--r--fs/nfs/delegation.c5
-rw-r--r--fs/nfs/nfs4proc.c20
-rw-r--r--fs/nfs/nfs4renewd.c3
-rw-r--r--fs/nfs/nfs4state.c17
-rw-r--r--include/linux/nfs_fs_sb.h6
6 files changed, 1 insertions, 51 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 */
244static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation) 244static 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;
1178err_opendata_put: 1171err_opendata_put:
1179 nfs4_opendata_put(opendata); 1172 nfs4_opendata_put(opendata);
1180err_release_rwsem:
1181 up_read(&clp->cl_sem);
1182err_put_state_owner: 1173err_put_state_owner:
1183 nfs4_put_state_owner(sp); 1174 nfs4_put_state_owner(sp);
1184out_err: 1175out_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);
3118out: 3108out:
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
3274static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request) 3263static 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
3519static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) 3504static 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__);
3550out_unlock: 3533out_unlock:
3551 up_read(&nfsi->rwsem); 3534 up_read(&nfsi->rwsem);
3552 up_read(&clp->cl_sem);
3553out: 3535out:
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);
103out: 102out:
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 */
109void 106void
110nfs4_schedule_state_renewal(struct nfs_client *clp) 107nfs4_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 */
312struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred) 308struct 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 */
344void nfs4_put_state_owner(struct nfs4_state_owner *sp) 336void 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 */
449void nfs4_put_open_state(struct nfs4_state *state) 437void 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 */
583static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner) 570static 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 }
1177out: 1161out:
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);
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 4e477ae58699..9bb81aec91cf 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -42,12 +42,6 @@ struct nfs_client {
42 struct rb_root cl_openowner_id; 42 struct rb_root cl_openowner_id;
43 struct rb_root cl_lockowner_id; 43 struct rb_root cl_lockowner_id;
44 44
45 /*
46 * The following rwsem ensures exclusive access to the server
47 * while we recover the state following a lease expiration.
48 */
49 struct rw_semaphore cl_sem;
50
51 struct list_head cl_delegations; 45 struct list_head cl_delegations;
52 struct rb_root cl_state_owners; 46 struct rb_root cl_state_owners;
53 spinlock_t cl_lock; 47 spinlock_t cl_lock;