diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
| -rw-r--r-- | fs/nfs/nfs4state.c | 73 |
1 files changed, 29 insertions, 44 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 848f6853c59e..a043f618cd5a 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
| @@ -787,33 +787,36 @@ void nfs4_close_sync(struct nfs4_state *state, fmode_t fmode) | |||
| 787 | * that is compatible with current->files | 787 | * that is compatible with current->files |
| 788 | */ | 788 | */ |
| 789 | static struct nfs4_lock_state * | 789 | static struct nfs4_lock_state * |
| 790 | __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type) | 790 | __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) |
| 791 | { | 791 | { |
| 792 | struct nfs4_lock_state *pos; | 792 | struct nfs4_lock_state *pos; |
| 793 | list_for_each_entry(pos, &state->lock_states, ls_locks) { | 793 | list_for_each_entry(pos, &state->lock_states, ls_locks) { |
| 794 | if (type != NFS4_ANY_LOCK_TYPE && pos->ls_owner.lo_type != type) | 794 | if (pos->ls_owner != fl_owner) |
| 795 | continue; | 795 | continue; |
| 796 | switch (pos->ls_owner.lo_type) { | ||
| 797 | case NFS4_POSIX_LOCK_TYPE: | ||
| 798 | if (pos->ls_owner.lo_u.posix_owner != fl_owner) | ||
| 799 | continue; | ||
| 800 | break; | ||
| 801 | case NFS4_FLOCK_LOCK_TYPE: | ||
| 802 | if (pos->ls_owner.lo_u.flock_owner != fl_pid) | ||
| 803 | continue; | ||
| 804 | } | ||
| 805 | atomic_inc(&pos->ls_count); | 796 | atomic_inc(&pos->ls_count); |
| 806 | return pos; | 797 | return pos; |
| 807 | } | 798 | } |
| 808 | return NULL; | 799 | return NULL; |
| 809 | } | 800 | } |
| 810 | 801 | ||
| 802 | static void | ||
| 803 | free_lock_state_work(struct work_struct *work) | ||
| 804 | { | ||
| 805 | struct nfs4_lock_state *lsp = container_of(work, | ||
| 806 | struct nfs4_lock_state, ls_release); | ||
| 807 | struct nfs4_state *state = lsp->ls_state; | ||
| 808 | struct nfs_server *server = state->owner->so_server; | ||
| 809 | struct nfs_client *clp = server->nfs_client; | ||
| 810 | |||
| 811 | clp->cl_mvops->free_lock_state(server, lsp); | ||
| 812 | } | ||
| 813 | |||
| 811 | /* | 814 | /* |
| 812 | * Return a compatible lock_state. If no initialized lock_state structure | 815 | * Return a compatible lock_state. If no initialized lock_state structure |
| 813 | * exists, return an uninitialized one. | 816 | * exists, return an uninitialized one. |
| 814 | * | 817 | * |
| 815 | */ | 818 | */ |
| 816 | static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type) | 819 | static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) |
| 817 | { | 820 | { |
| 818 | struct nfs4_lock_state *lsp; | 821 | struct nfs4_lock_state *lsp; |
| 819 | struct nfs_server *server = state->owner->so_server; | 822 | struct nfs_server *server = state->owner->so_server; |
| @@ -824,21 +827,12 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f | |||
| 824 | nfs4_init_seqid_counter(&lsp->ls_seqid); | 827 | nfs4_init_seqid_counter(&lsp->ls_seqid); |
| 825 | atomic_set(&lsp->ls_count, 1); | 828 | atomic_set(&lsp->ls_count, 1); |
| 826 | lsp->ls_state = state; | 829 | lsp->ls_state = state; |
| 827 | lsp->ls_owner.lo_type = type; | 830 | lsp->ls_owner = fl_owner; |
| 828 | switch (lsp->ls_owner.lo_type) { | ||
| 829 | case NFS4_FLOCK_LOCK_TYPE: | ||
| 830 | lsp->ls_owner.lo_u.flock_owner = fl_pid; | ||
| 831 | break; | ||
| 832 | case NFS4_POSIX_LOCK_TYPE: | ||
| 833 | lsp->ls_owner.lo_u.posix_owner = fl_owner; | ||
| 834 | break; | ||
| 835 | default: | ||
| 836 | goto out_free; | ||
| 837 | } | ||
| 838 | lsp->ls_seqid.owner_id = ida_simple_get(&server->lockowner_id, 0, 0, GFP_NOFS); | 831 | lsp->ls_seqid.owner_id = ida_simple_get(&server->lockowner_id, 0, 0, GFP_NOFS); |
| 839 | if (lsp->ls_seqid.owner_id < 0) | 832 | if (lsp->ls_seqid.owner_id < 0) |
| 840 | goto out_free; | 833 | goto out_free; |
| 841 | INIT_LIST_HEAD(&lsp->ls_locks); | 834 | INIT_LIST_HEAD(&lsp->ls_locks); |
| 835 | INIT_WORK(&lsp->ls_release, free_lock_state_work); | ||
| 842 | return lsp; | 836 | return lsp; |
| 843 | out_free: | 837 | out_free: |
| 844 | kfree(lsp); | 838 | kfree(lsp); |
| @@ -857,13 +851,13 @@ void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp | |||
| 857 | * exists, return an uninitialized one. | 851 | * exists, return an uninitialized one. |
| 858 | * | 852 | * |
| 859 | */ | 853 | */ |
| 860 | static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner, pid_t pid, unsigned int type) | 854 | static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner) |
| 861 | { | 855 | { |
| 862 | struct nfs4_lock_state *lsp, *new = NULL; | 856 | struct nfs4_lock_state *lsp, *new = NULL; |
| 863 | 857 | ||
| 864 | for(;;) { | 858 | for(;;) { |
| 865 | spin_lock(&state->state_lock); | 859 | spin_lock(&state->state_lock); |
| 866 | lsp = __nfs4_find_lock_state(state, owner, pid, type); | 860 | lsp = __nfs4_find_lock_state(state, owner); |
| 867 | if (lsp != NULL) | 861 | if (lsp != NULL) |
| 868 | break; | 862 | break; |
| 869 | if (new != NULL) { | 863 | if (new != NULL) { |
| @@ -874,7 +868,7 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_ | |||
| 874 | break; | 868 | break; |
| 875 | } | 869 | } |
| 876 | spin_unlock(&state->state_lock); | 870 | spin_unlock(&state->state_lock); |
| 877 | new = nfs4_alloc_lock_state(state, owner, pid, type); | 871 | new = nfs4_alloc_lock_state(state, owner); |
| 878 | if (new == NULL) | 872 | if (new == NULL) |
| 879 | return NULL; | 873 | return NULL; |
| 880 | } | 874 | } |
| @@ -902,13 +896,12 @@ void nfs4_put_lock_state(struct nfs4_lock_state *lsp) | |||
| 902 | if (list_empty(&state->lock_states)) | 896 | if (list_empty(&state->lock_states)) |
| 903 | clear_bit(LK_STATE_IN_USE, &state->flags); | 897 | clear_bit(LK_STATE_IN_USE, &state->flags); |
| 904 | spin_unlock(&state->state_lock); | 898 | spin_unlock(&state->state_lock); |
| 905 | server = state->owner->so_server; | 899 | if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) |
| 906 | if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) { | 900 | queue_work(nfsiod_workqueue, &lsp->ls_release); |
| 907 | struct nfs_client *clp = server->nfs_client; | 901 | else { |
| 908 | 902 | server = state->owner->so_server; | |
| 909 | clp->cl_mvops->free_lock_state(server, lsp); | ||
| 910 | } else | ||
| 911 | nfs4_free_lock_state(server, lsp); | 903 | nfs4_free_lock_state(server, lsp); |
| 904 | } | ||
| 912 | } | 905 | } |
| 913 | 906 | ||
| 914 | static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src) | 907 | static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src) |
| @@ -935,13 +928,7 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl) | |||
| 935 | 928 | ||
| 936 | if (fl->fl_ops != NULL) | 929 | if (fl->fl_ops != NULL) |
| 937 | return 0; | 930 | return 0; |
| 938 | if (fl->fl_flags & FL_POSIX) | 931 | lsp = nfs4_get_lock_state(state, fl->fl_owner); |
| 939 | lsp = nfs4_get_lock_state(state, fl->fl_owner, 0, NFS4_POSIX_LOCK_TYPE); | ||
| 940 | else if (fl->fl_flags & FL_FLOCK) | ||
| 941 | lsp = nfs4_get_lock_state(state, NULL, fl->fl_pid, | ||
| 942 | NFS4_FLOCK_LOCK_TYPE); | ||
| 943 | else | ||
| 944 | return -EINVAL; | ||
| 945 | if (lsp == NULL) | 932 | if (lsp == NULL) |
| 946 | return -ENOMEM; | 933 | return -ENOMEM; |
| 947 | fl->fl_u.nfs4_fl.owner = lsp; | 934 | fl->fl_u.nfs4_fl.owner = lsp; |
| @@ -955,7 +942,6 @@ static int nfs4_copy_lock_stateid(nfs4_stateid *dst, | |||
| 955 | { | 942 | { |
| 956 | struct nfs4_lock_state *lsp; | 943 | struct nfs4_lock_state *lsp; |
| 957 | fl_owner_t fl_owner; | 944 | fl_owner_t fl_owner; |
| 958 | pid_t fl_pid; | ||
| 959 | int ret = -ENOENT; | 945 | int ret = -ENOENT; |
| 960 | 946 | ||
| 961 | 947 | ||
| @@ -966,9 +952,8 @@ static int nfs4_copy_lock_stateid(nfs4_stateid *dst, | |||
| 966 | goto out; | 952 | goto out; |
| 967 | 953 | ||
| 968 | fl_owner = lockowner->l_owner; | 954 | fl_owner = lockowner->l_owner; |
| 969 | fl_pid = lockowner->l_pid; | ||
| 970 | spin_lock(&state->state_lock); | 955 | spin_lock(&state->state_lock); |
| 971 | lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE); | 956 | lsp = __nfs4_find_lock_state(state, fl_owner); |
| 972 | if (lsp && test_bit(NFS_LOCK_LOST, &lsp->ls_flags)) | 957 | if (lsp && test_bit(NFS_LOCK_LOST, &lsp->ls_flags)) |
| 973 | ret = -EIO; | 958 | ret = -EIO; |
| 974 | else if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) { | 959 | else if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) { |
| @@ -1251,8 +1236,8 @@ int nfs4_wait_clnt_recover(struct nfs_client *clp) | |||
| 1251 | might_sleep(); | 1236 | might_sleep(); |
| 1252 | 1237 | ||
| 1253 | atomic_inc(&clp->cl_count); | 1238 | atomic_inc(&clp->cl_count); |
| 1254 | res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING, | 1239 | res = wait_on_bit_action(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING, |
| 1255 | nfs_wait_bit_killable, TASK_KILLABLE); | 1240 | nfs_wait_bit_killable, TASK_KILLABLE); |
| 1256 | if (res) | 1241 | if (res) |
| 1257 | goto out; | 1242 | goto out; |
| 1258 | if (clp->cl_cons_state < 0) | 1243 | if (clp->cl_cons_state < 0) |
