diff options
-rw-r--r-- | fs/nfs/nfs4_fs.h | 6 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 18 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 15 |
3 files changed, 4 insertions, 35 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 6ac6708484f5..d4fcb5d0ce6c 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -125,16 +125,11 @@ static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status | |||
125 | * NFS4 state_owners and lock_owners are simply labels for ordered | 125 | * NFS4 state_owners and lock_owners are simply labels for ordered |
126 | * sequences of RPC calls. Their sole purpose is to provide once-only | 126 | * sequences of RPC calls. Their sole purpose is to provide once-only |
127 | * semantics by allowing the server to identify replayed requests. | 127 | * semantics by allowing the server to identify replayed requests. |
128 | * | ||
129 | * The ->so_sema is held during all state_owner seqid-mutating operations: | ||
130 | * OPEN, OPEN_DOWNGRADE, and CLOSE. Its purpose is to properly serialize | ||
131 | * so_seqid. | ||
132 | */ | 128 | */ |
133 | struct nfs4_state_owner { | 129 | struct nfs4_state_owner { |
134 | struct list_head so_list; /* per-clientid list of state_owners */ | 130 | struct list_head so_list; /* per-clientid list of state_owners */ |
135 | struct nfs4_client *so_client; | 131 | struct nfs4_client *so_client; |
136 | u32 so_id; /* 32-bit identifier, unique */ | 132 | u32 so_id; /* 32-bit identifier, unique */ |
137 | struct semaphore so_sema; | ||
138 | atomic_t so_count; | 133 | atomic_t so_count; |
139 | 134 | ||
140 | struct rpc_cred *so_cred; /* Associated cred */ | 135 | struct rpc_cred *so_cred; /* Associated cred */ |
@@ -183,7 +178,6 @@ struct nfs4_state { | |||
183 | struct inode *inode; /* Pointer to the inode */ | 178 | struct inode *inode; /* Pointer to the inode */ |
184 | 179 | ||
185 | unsigned long flags; /* Do we hold any locks? */ | 180 | unsigned long flags; /* Do we hold any locks? */ |
186 | struct semaphore lock_sema; /* Serializes file locking operations */ | ||
187 | spinlock_t state_lock; /* Protects the lock_states list */ | 181 | spinlock_t state_lock; /* Protects the lock_states list */ |
188 | 182 | ||
189 | nfs4_stateid stateid; | 183 | nfs4_stateid stateid; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 5154ddf6d9a5..25bab6032dfe 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -224,7 +224,6 @@ static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, | |||
224 | /* | 224 | /* |
225 | * OPEN_RECLAIM: | 225 | * OPEN_RECLAIM: |
226 | * reclaim state on the server after a reboot. | 226 | * reclaim state on the server after a reboot. |
227 | * Assumes caller is holding the sp->so_sem | ||
228 | */ | 227 | */ |
229 | static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state) | 228 | static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state) |
230 | { | 229 | { |
@@ -322,7 +321,6 @@ static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state | |||
322 | }; | 321 | }; |
323 | int status = 0; | 322 | int status = 0; |
324 | 323 | ||
325 | down(&sp->so_sema); | ||
326 | if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) | 324 | if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) |
327 | goto out; | 325 | goto out; |
328 | if (state->state == 0) | 326 | if (state->state == 0) |
@@ -342,7 +340,6 @@ static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state | |||
342 | } | 340 | } |
343 | nfs_free_seqid(arg.seqid); | 341 | nfs_free_seqid(arg.seqid); |
344 | out: | 342 | out: |
345 | up(&sp->so_sema); | ||
346 | dput(parent); | 343 | dput(parent); |
347 | return status; | 344 | return status; |
348 | } | 345 | } |
@@ -595,7 +592,6 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred | |||
595 | dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__); | 592 | dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__); |
596 | goto out_err; | 593 | goto out_err; |
597 | } | 594 | } |
598 | down(&sp->so_sema); | ||
599 | state = nfs4_get_open_state(inode, sp); | 595 | state = nfs4_get_open_state(inode, sp); |
600 | if (state == NULL) | 596 | if (state == NULL) |
601 | goto out_err; | 597 | goto out_err; |
@@ -620,7 +616,6 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred | |||
620 | set_bit(NFS_DELEGATED_STATE, &state->flags); | 616 | set_bit(NFS_DELEGATED_STATE, &state->flags); |
621 | update_open_stateid(state, &delegation->stateid, open_flags); | 617 | update_open_stateid(state, &delegation->stateid, open_flags); |
622 | out_ok: | 618 | out_ok: |
623 | up(&sp->so_sema); | ||
624 | nfs4_put_state_owner(sp); | 619 | nfs4_put_state_owner(sp); |
625 | up_read(&nfsi->rwsem); | 620 | up_read(&nfsi->rwsem); |
626 | up_read(&clp->cl_sem); | 621 | up_read(&clp->cl_sem); |
@@ -631,7 +626,6 @@ out_err: | |||
631 | if (sp != NULL) { | 626 | if (sp != NULL) { |
632 | if (state != NULL) | 627 | if (state != NULL) |
633 | nfs4_put_open_state(state); | 628 | nfs4_put_open_state(state); |
634 | up(&sp->so_sema); | ||
635 | nfs4_put_state_owner(sp); | 629 | nfs4_put_state_owner(sp); |
636 | } | 630 | } |
637 | up_read(&nfsi->rwsem); | 631 | up_read(&nfsi->rwsem); |
@@ -696,7 +690,6 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st | |||
696 | } else | 690 | } else |
697 | o_arg.u.attrs = sattr; | 691 | o_arg.u.attrs = sattr; |
698 | /* Serialization for the sequence id */ | 692 | /* Serialization for the sequence id */ |
699 | down(&sp->so_sema); | ||
700 | 693 | ||
701 | o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); | 694 | o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); |
702 | if (o_arg.seqid == NULL) | 695 | if (o_arg.seqid == NULL) |
@@ -716,7 +709,6 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st | |||
716 | if (o_res.delegation_type != 0) | 709 | if (o_res.delegation_type != 0) |
717 | nfs_inode_set_delegation(inode, cred, &o_res); | 710 | nfs_inode_set_delegation(inode, cred, &o_res); |
718 | nfs_free_seqid(o_arg.seqid); | 711 | nfs_free_seqid(o_arg.seqid); |
719 | up(&sp->so_sema); | ||
720 | nfs4_put_state_owner(sp); | 712 | nfs4_put_state_owner(sp); |
721 | up_read(&clp->cl_sem); | 713 | up_read(&clp->cl_sem); |
722 | *res = state; | 714 | *res = state; |
@@ -726,7 +718,6 @@ out_err: | |||
726 | if (state != NULL) | 718 | if (state != NULL) |
727 | nfs4_put_open_state(state); | 719 | nfs4_put_open_state(state); |
728 | nfs_free_seqid(o_arg.seqid); | 720 | nfs_free_seqid(o_arg.seqid); |
729 | up(&sp->so_sema); | ||
730 | nfs4_put_state_owner(sp); | 721 | nfs4_put_state_owner(sp); |
731 | } | 722 | } |
732 | /* Note: clp->cl_sem must be released before nfs4_put_open_state()! */ | 723 | /* Note: clp->cl_sem must be released before nfs4_put_open_state()! */ |
@@ -833,7 +824,6 @@ static void nfs4_free_closedata(struct nfs4_closedata *calldata) | |||
833 | 824 | ||
834 | nfs4_put_open_state(calldata->state); | 825 | nfs4_put_open_state(calldata->state); |
835 | nfs_free_seqid(calldata->arg.seqid); | 826 | nfs_free_seqid(calldata->arg.seqid); |
836 | up(&sp->so_sema); | ||
837 | nfs4_put_state_owner(sp); | 827 | nfs4_put_state_owner(sp); |
838 | up_read(&server->nfs4_state->cl_sem); | 828 | up_read(&server->nfs4_state->cl_sem); |
839 | kfree(calldata); | 829 | kfree(calldata); |
@@ -2702,7 +2692,6 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock | |||
2702 | 2692 | ||
2703 | down_read(&clp->cl_sem); | 2693 | down_read(&clp->cl_sem); |
2704 | nlo.clientid = clp->cl_clientid; | 2694 | nlo.clientid = clp->cl_clientid; |
2705 | down(&state->lock_sema); | ||
2706 | status = nfs4_set_lock_state(state, request); | 2695 | status = nfs4_set_lock_state(state, request); |
2707 | if (status != 0) | 2696 | if (status != 0) |
2708 | goto out; | 2697 | goto out; |
@@ -2729,7 +2718,6 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock | |||
2729 | status = 0; | 2718 | status = 0; |
2730 | } | 2719 | } |
2731 | out: | 2720 | out: |
2732 | up(&state->lock_sema); | ||
2733 | up_read(&clp->cl_sem); | 2721 | up_read(&clp->cl_sem); |
2734 | return status; | 2722 | return status; |
2735 | } | 2723 | } |
@@ -2791,7 +2779,6 @@ static int _nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock | |||
2791 | int status; | 2779 | int status; |
2792 | 2780 | ||
2793 | down_read(&clp->cl_sem); | 2781 | down_read(&clp->cl_sem); |
2794 | down(&state->lock_sema); | ||
2795 | status = nfs4_set_lock_state(state, request); | 2782 | status = nfs4_set_lock_state(state, request); |
2796 | if (status != 0) | 2783 | if (status != 0) |
2797 | goto out; | 2784 | goto out; |
@@ -2813,7 +2800,6 @@ static int _nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock | |||
2813 | sizeof(lsp->ls_stateid.data)); | 2800 | sizeof(lsp->ls_stateid.data)); |
2814 | nfs_free_seqid(luargs.seqid); | 2801 | nfs_free_seqid(luargs.seqid); |
2815 | out: | 2802 | out: |
2816 | up(&state->lock_sema); | ||
2817 | if (status == 0) | 2803 | if (status == 0) |
2818 | do_vfs_lock(request->fl_file, request); | 2804 | do_vfs_lock(request->fl_file, request); |
2819 | up_read(&clp->cl_sem); | 2805 | up_read(&clp->cl_sem); |
@@ -2877,7 +2863,6 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r | |||
2877 | largs.u.open_lock = &otl; | 2863 | largs.u.open_lock = &otl; |
2878 | largs.new_lock_owner = 1; | 2864 | largs.new_lock_owner = 1; |
2879 | arg.u.lock = &largs; | 2865 | arg.u.lock = &largs; |
2880 | down(&owner->so_sema); | ||
2881 | otl.open_seqid = nfs_alloc_seqid(&owner->so_seqid); | 2866 | otl.open_seqid = nfs_alloc_seqid(&owner->so_seqid); |
2882 | if (otl.open_seqid != NULL) { | 2867 | if (otl.open_seqid != NULL) { |
2883 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); | 2868 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); |
@@ -2885,7 +2870,6 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r | |||
2885 | nfs_increment_open_seqid(status, otl.open_seqid); | 2870 | nfs_increment_open_seqid(status, otl.open_seqid); |
2886 | nfs_free_seqid(otl.open_seqid); | 2871 | nfs_free_seqid(otl.open_seqid); |
2887 | } | 2872 | } |
2888 | up(&owner->so_sema); | ||
2889 | if (status == 0) | 2873 | if (status == 0) |
2890 | nfs_confirm_seqid(&lsp->ls_seqid, 0); | 2874 | nfs_confirm_seqid(&lsp->ls_seqid, 0); |
2891 | } else { | 2875 | } else { |
@@ -2944,11 +2928,9 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock | |||
2944 | int status; | 2928 | int status; |
2945 | 2929 | ||
2946 | down_read(&clp->cl_sem); | 2930 | down_read(&clp->cl_sem); |
2947 | down(&state->lock_sema); | ||
2948 | status = nfs4_set_lock_state(state, request); | 2931 | status = nfs4_set_lock_state(state, request); |
2949 | if (status == 0) | 2932 | if (status == 0) |
2950 | status = _nfs4_do_setlk(state, cmd, request, 0); | 2933 | status = _nfs4_do_setlk(state, cmd, request, 0); |
2951 | up(&state->lock_sema); | ||
2952 | if (status == 0) { | 2934 | if (status == 0) { |
2953 | /* Note: we always want to sleep here! */ | 2935 | /* Note: we always want to sleep here! */ |
2954 | request->fl_flags |= FL_SLEEP; | 2936 | request->fl_flags |= FL_SLEEP; |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 59c93f37e1b2..86c08c165ce7 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -267,7 +267,6 @@ nfs4_alloc_state_owner(void) | |||
267 | sp = kzalloc(sizeof(*sp),GFP_KERNEL); | 267 | sp = kzalloc(sizeof(*sp),GFP_KERNEL); |
268 | if (!sp) | 268 | if (!sp) |
269 | return NULL; | 269 | return NULL; |
270 | init_MUTEX(&sp->so_sema); | ||
271 | INIT_LIST_HEAD(&sp->so_states); | 270 | INIT_LIST_HEAD(&sp->so_states); |
272 | INIT_LIST_HEAD(&sp->so_delegations); | 271 | INIT_LIST_HEAD(&sp->so_delegations); |
273 | rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue"); | 272 | rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue"); |
@@ -362,7 +361,6 @@ nfs4_alloc_open_state(void) | |||
362 | memset(state->stateid.data, 0, sizeof(state->stateid.data)); | 361 | memset(state->stateid.data, 0, sizeof(state->stateid.data)); |
363 | atomic_set(&state->count, 1); | 362 | atomic_set(&state->count, 1); |
364 | INIT_LIST_HEAD(&state->lock_states); | 363 | INIT_LIST_HEAD(&state->lock_states); |
365 | init_MUTEX(&state->lock_sema); | ||
366 | spin_lock_init(&state->state_lock); | 364 | spin_lock_init(&state->state_lock); |
367 | return state; | 365 | return state; |
368 | } | 366 | } |
@@ -444,7 +442,6 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner) | |||
444 | state = __nfs4_find_state_byowner(inode, owner); | 442 | state = __nfs4_find_state_byowner(inode, owner); |
445 | if (state == NULL && new != NULL) { | 443 | if (state == NULL && new != NULL) { |
446 | state = new; | 444 | state = new; |
447 | /* Caller *must* be holding owner->so_sem */ | ||
448 | /* Note: The reclaim code dictates that we add stateless | 445 | /* Note: The reclaim code dictates that we add stateless |
449 | * and read-only stateids to the end of the list */ | 446 | * and read-only stateids to the end of the list */ |
450 | list_add_tail(&state->open_states, &owner->so_states); | 447 | list_add_tail(&state->open_states, &owner->so_states); |
@@ -464,7 +461,7 @@ out: | |||
464 | 461 | ||
465 | /* | 462 | /* |
466 | * Beware! Caller must be holding exactly one | 463 | * Beware! Caller must be holding exactly one |
467 | * reference to clp->cl_sem and owner->so_sema! | 464 | * reference to clp->cl_sem! |
468 | */ | 465 | */ |
469 | void nfs4_put_open_state(struct nfs4_state *state) | 466 | void nfs4_put_open_state(struct nfs4_state *state) |
470 | { | 467 | { |
@@ -485,7 +482,6 @@ void nfs4_put_open_state(struct nfs4_state *state) | |||
485 | 482 | ||
486 | /* | 483 | /* |
487 | * Beware! Caller must be holding no references to clp->cl_sem! | 484 | * Beware! Caller must be holding no references to clp->cl_sem! |
488 | * of owner->so_sema! | ||
489 | */ | 485 | */ |
490 | void nfs4_close_state(struct nfs4_state *state, mode_t mode) | 486 | void nfs4_close_state(struct nfs4_state *state, mode_t mode) |
491 | { | 487 | { |
@@ -496,7 +492,6 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode) | |||
496 | 492 | ||
497 | atomic_inc(&owner->so_count); | 493 | atomic_inc(&owner->so_count); |
498 | down_read(&clp->cl_sem); | 494 | down_read(&clp->cl_sem); |
499 | down(&owner->so_sema); | ||
500 | /* Protect against nfs4_find_state() */ | 495 | /* Protect against nfs4_find_state() */ |
501 | spin_lock(&inode->i_lock); | 496 | spin_lock(&inode->i_lock); |
502 | if (mode & FMODE_READ) | 497 | if (mode & FMODE_READ) |
@@ -527,7 +522,6 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode) | |||
527 | } | 522 | } |
528 | out: | 523 | out: |
529 | nfs4_put_open_state(state); | 524 | nfs4_put_open_state(state); |
530 | up(&owner->so_sema); | ||
531 | nfs4_put_state_owner(owner); | 525 | nfs4_put_state_owner(owner); |
532 | up_read(&clp->cl_sem); | 526 | up_read(&clp->cl_sem); |
533 | } | 527 | } |
@@ -553,7 +547,6 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) | |||
553 | * Return a compatible lock_state. If no initialized lock_state structure | 547 | * Return a compatible lock_state. If no initialized lock_state structure |
554 | * exists, return an uninitialized one. | 548 | * exists, return an uninitialized one. |
555 | * | 549 | * |
556 | * The caller must be holding state->lock_sema | ||
557 | */ | 550 | */ |
558 | static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) | 551 | static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) |
559 | { | 552 | { |
@@ -577,7 +570,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f | |||
577 | * Return a compatible lock_state. If no initialized lock_state structure | 570 | * Return a compatible lock_state. If no initialized lock_state structure |
578 | * exists, return an uninitialized one. | 571 | * exists, return an uninitialized one. |
579 | * | 572 | * |
580 | * The caller must be holding state->lock_sema and clp->cl_sem | 573 | * The caller must be holding clp->cl_sem |
581 | */ | 574 | */ |
582 | static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner) | 575 | static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner) |
583 | { | 576 | { |
@@ -711,7 +704,7 @@ void nfs_free_seqid(struct nfs_seqid *seqid) | |||
711 | } | 704 | } |
712 | 705 | ||
713 | /* | 706 | /* |
714 | * Called with sp->so_sema and clp->cl_sem held. | 707 | * Called with clp->cl_sem held. |
715 | * | 708 | * |
716 | * Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or | 709 | * Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or |
717 | * failed with a seqid incrementing error - | 710 | * failed with a seqid incrementing error - |
@@ -750,7 +743,7 @@ void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid) | |||
750 | } | 743 | } |
751 | 744 | ||
752 | /* | 745 | /* |
753 | * Called with ls->lock_sema and clp->cl_sem held. | 746 | * Called with clp->cl_sem held. |
754 | * | 747 | * |
755 | * Increment the seqid if the LOCK/LOCKU succeeded, or | 748 | * Increment the seqid if the LOCK/LOCKU succeeded, or |
756 | * failed with a seqid incrementing error - | 749 | * failed with a seqid incrementing error - |