nfs4state.c (49a4bda22e186c4d0eb07f4a36b5b1a378f9398d) nfs4state.c (743162013d40ca612b4cb53d3a200dff2d9ab26e)
1/*
2 * fs/nfs/nfs4state.c
3 *
4 * Client-side XDR for NFSv4.
5 *
6 * Copyright (c) 2002 The Regents of the University of Michigan.
7 * All rights reserved.
8 *

--- 773 unchanged lines hidden (view full) ---

782 __nfs4_close(state, fmode, GFP_KERNEL, 1);
783}
784
785/*
786 * Search the state->lock_states for an existing lock_owner
787 * that is compatible with current->files
788 */
789static struct nfs4_lock_state *
1/*
2 * fs/nfs/nfs4state.c
3 *
4 * Client-side XDR for NFSv4.
5 *
6 * Copyright (c) 2002 The Regents of the University of Michigan.
7 * All rights reserved.
8 *

--- 773 unchanged lines hidden (view full) ---

782 __nfs4_close(state, fmode, GFP_KERNEL, 1);
783}
784
785/*
786 * Search the state->lock_states for an existing lock_owner
787 * that is compatible with current->files
788 */
789static struct nfs4_lock_state *
790__nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
790__nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type)
791{
792 struct nfs4_lock_state *pos;
793 list_for_each_entry(pos, &state->lock_states, ls_locks) {
791{
792 struct nfs4_lock_state *pos;
793 list_for_each_entry(pos, &state->lock_states, ls_locks) {
794 if (pos->ls_owner != fl_owner)
794 if (type != NFS4_ANY_LOCK_TYPE && pos->ls_owner.lo_type != type)
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 }
796 atomic_inc(&pos->ls_count);
797 return pos;
798 }
799 return NULL;
800}
801
805 atomic_inc(&pos->ls_count);
806 return pos;
807 }
808 return NULL;
809}
810
802static void
803free_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
814/*
815 * Return a compatible lock_state. If no initialized lock_state structure
816 * exists, return an uninitialized one.
817 *
818 */
811/*
812 * Return a compatible lock_state. If no initialized lock_state structure
813 * exists, return an uninitialized one.
814 *
815 */
819static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
816static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type)
820{
821 struct nfs4_lock_state *lsp;
822 struct nfs_server *server = state->owner->so_server;
823
824 lsp = kzalloc(sizeof(*lsp), GFP_NOFS);
825 if (lsp == NULL)
826 return NULL;
827 nfs4_init_seqid_counter(&lsp->ls_seqid);
828 atomic_set(&lsp->ls_count, 1);
829 lsp->ls_state = state;
817{
818 struct nfs4_lock_state *lsp;
819 struct nfs_server *server = state->owner->so_server;
820
821 lsp = kzalloc(sizeof(*lsp), GFP_NOFS);
822 if (lsp == NULL)
823 return NULL;
824 nfs4_init_seqid_counter(&lsp->ls_seqid);
825 atomic_set(&lsp->ls_count, 1);
826 lsp->ls_state = state;
830 lsp->ls_owner = fl_owner;
827 lsp->ls_owner.lo_type = type;
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 }
831 lsp->ls_seqid.owner_id = ida_simple_get(&server->lockowner_id, 0, 0, GFP_NOFS);
832 if (lsp->ls_seqid.owner_id < 0)
833 goto out_free;
834 INIT_LIST_HEAD(&lsp->ls_locks);
838 lsp->ls_seqid.owner_id = ida_simple_get(&server->lockowner_id, 0, 0, GFP_NOFS);
839 if (lsp->ls_seqid.owner_id < 0)
840 goto out_free;
841 INIT_LIST_HEAD(&lsp->ls_locks);
835 INIT_WORK(&lsp->ls_release, free_lock_state_work);
836 return lsp;
837out_free:
838 kfree(lsp);
839 return NULL;
840}
841
842void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
843{
844 ida_simple_remove(&server->lockowner_id, lsp->ls_seqid.owner_id);
845 nfs4_destroy_seqid_counter(&lsp->ls_seqid);
846 kfree(lsp);
847}
848
849/*
850 * Return a compatible lock_state. If no initialized lock_state structure
851 * exists, return an uninitialized one.
852 *
853 */
842 return lsp;
843out_free:
844 kfree(lsp);
845 return NULL;
846}
847
848void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
849{
850 ida_simple_remove(&server->lockowner_id, lsp->ls_seqid.owner_id);
851 nfs4_destroy_seqid_counter(&lsp->ls_seqid);
852 kfree(lsp);
853}
854
855/*
856 * Return a compatible lock_state. If no initialized lock_state structure
857 * exists, return an uninitialized one.
858 *
859 */
854static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
860static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner, pid_t pid, unsigned int type)
855{
856 struct nfs4_lock_state *lsp, *new = NULL;
857
858 for(;;) {
859 spin_lock(&state->state_lock);
861{
862 struct nfs4_lock_state *lsp, *new = NULL;
863
864 for(;;) {
865 spin_lock(&state->state_lock);
860 lsp = __nfs4_find_lock_state(state, owner);
866 lsp = __nfs4_find_lock_state(state, owner, pid, type);
861 if (lsp != NULL)
862 break;
863 if (new != NULL) {
864 list_add(&new->ls_locks, &state->lock_states);
865 set_bit(LK_STATE_IN_USE, &state->flags);
866 lsp = new;
867 new = NULL;
868 break;
869 }
870 spin_unlock(&state->state_lock);
867 if (lsp != NULL)
868 break;
869 if (new != NULL) {
870 list_add(&new->ls_locks, &state->lock_states);
871 set_bit(LK_STATE_IN_USE, &state->flags);
872 lsp = new;
873 new = NULL;
874 break;
875 }
876 spin_unlock(&state->state_lock);
871 new = nfs4_alloc_lock_state(state, owner);
877 new = nfs4_alloc_lock_state(state, owner, pid, type);
872 if (new == NULL)
873 return NULL;
874 }
875 spin_unlock(&state->state_lock);
876 if (new != NULL)
877 nfs4_free_lock_state(state->owner->so_server, new);
878 return lsp;
879}

--- 11 unchanged lines hidden (view full) ---

891 return;
892 state = lsp->ls_state;
893 if (!atomic_dec_and_lock(&lsp->ls_count, &state->state_lock))
894 return;
895 list_del(&lsp->ls_locks);
896 if (list_empty(&state->lock_states))
897 clear_bit(LK_STATE_IN_USE, &state->flags);
898 spin_unlock(&state->state_lock);
878 if (new == NULL)
879 return NULL;
880 }
881 spin_unlock(&state->state_lock);
882 if (new != NULL)
883 nfs4_free_lock_state(state->owner->so_server, new);
884 return lsp;
885}

--- 11 unchanged lines hidden (view full) ---

897 return;
898 state = lsp->ls_state;
899 if (!atomic_dec_and_lock(&lsp->ls_count, &state->state_lock))
900 return;
901 list_del(&lsp->ls_locks);
902 if (list_empty(&state->lock_states))
903 clear_bit(LK_STATE_IN_USE, &state->flags);
904 spin_unlock(&state->state_lock);
899 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags))
900 queue_work(nfsiod_workqueue, &lsp->ls_release);
901 else {
902 server = state->owner->so_server;
905 server = state->owner->so_server;
906 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
907 struct nfs_client *clp = server->nfs_client;
908
909 clp->cl_mvops->free_lock_state(server, lsp);
910 } else
903 nfs4_free_lock_state(server, lsp);
911 nfs4_free_lock_state(server, lsp);
904 }
905}
906
907static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
908{
909 struct nfs4_lock_state *lsp = src->fl_u.nfs4_fl.owner;
910
911 dst->fl_u.nfs4_fl.owner = lsp;
912 atomic_inc(&lsp->ls_count);

--- 10 unchanged lines hidden (view full) ---

923};
924
925int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
926{
927 struct nfs4_lock_state *lsp;
928
929 if (fl->fl_ops != NULL)
930 return 0;
912}
913
914static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
915{
916 struct nfs4_lock_state *lsp = src->fl_u.nfs4_fl.owner;
917
918 dst->fl_u.nfs4_fl.owner = lsp;
919 atomic_inc(&lsp->ls_count);

--- 10 unchanged lines hidden (view full) ---

930};
931
932int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
933{
934 struct nfs4_lock_state *lsp;
935
936 if (fl->fl_ops != NULL)
937 return 0;
931 lsp = nfs4_get_lock_state(state, fl->fl_owner);
938 if (fl->fl_flags & FL_POSIX)
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;
932 if (lsp == NULL)
933 return -ENOMEM;
934 fl->fl_u.nfs4_fl.owner = lsp;
935 fl->fl_ops = &nfs4_fl_lock_ops;
936 return 0;
937}
938
939static int nfs4_copy_lock_stateid(nfs4_stateid *dst,
940 struct nfs4_state *state,
941 const struct nfs_lockowner *lockowner)
942{
943 struct nfs4_lock_state *lsp;
944 fl_owner_t fl_owner;
945 if (lsp == NULL)
946 return -ENOMEM;
947 fl->fl_u.nfs4_fl.owner = lsp;
948 fl->fl_ops = &nfs4_fl_lock_ops;
949 return 0;
950}
951
952static int nfs4_copy_lock_stateid(nfs4_stateid *dst,
953 struct nfs4_state *state,
954 const struct nfs_lockowner *lockowner)
955{
956 struct nfs4_lock_state *lsp;
957 fl_owner_t fl_owner;
958 pid_t fl_pid;
945 int ret = -ENOENT;
946
947
948 if (lockowner == NULL)
949 goto out;
950
951 if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
952 goto out;
953
954 fl_owner = lockowner->l_owner;
959 int ret = -ENOENT;
960
961
962 if (lockowner == NULL)
963 goto out;
964
965 if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
966 goto out;
967
968 fl_owner = lockowner->l_owner;
969 fl_pid = lockowner->l_pid;
955 spin_lock(&state->state_lock);
970 spin_lock(&state->state_lock);
956 lsp = __nfs4_find_lock_state(state, fl_owner);
971 lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE);
957 if (lsp && test_bit(NFS_LOCK_LOST, &lsp->ls_flags))
958 ret = -EIO;
959 else if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) {
960 nfs4_stateid_copy(dst, &lsp->ls_stateid);
961 ret = 0;
962 }
963 spin_unlock(&state->state_lock);
964 nfs4_put_lock_state(lsp);

--- 266 unchanged lines hidden (view full) ---

1231
1232int nfs4_wait_clnt_recover(struct nfs_client *clp)
1233{
1234 int res;
1235
1236 might_sleep();
1237
1238 atomic_inc(&clp->cl_count);
972 if (lsp && test_bit(NFS_LOCK_LOST, &lsp->ls_flags))
973 ret = -EIO;
974 else if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) {
975 nfs4_stateid_copy(dst, &lsp->ls_stateid);
976 ret = 0;
977 }
978 spin_unlock(&state->state_lock);
979 nfs4_put_lock_state(lsp);

--- 266 unchanged lines hidden (view full) ---

1246
1247int nfs4_wait_clnt_recover(struct nfs_client *clp)
1248{
1249 int res;
1250
1251 might_sleep();
1252
1253 atomic_inc(&clp->cl_count);
1239 res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING,
1240 nfs_wait_bit_killable, TASK_KILLABLE);
1254 res = wait_on_bit_action(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING,
1255 nfs_wait_bit_killable, TASK_KILLABLE);
1241 if (res)
1242 goto out;
1243 if (clp->cl_cons_state < 0)
1244 res = clp->cl_cons_state;
1245out:
1246 nfs_put_client(clp);
1247 return res;
1248}

--- 1196 unchanged lines hidden ---
1256 if (res)
1257 goto out;
1258 if (clp->cl_cons_state < 0)
1259 res = clp->cl_cons_state;
1260out:
1261 nfs_put_client(clp);
1262 return res;
1263}

--- 1196 unchanged lines hidden ---