diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4state.c | 46 |
1 files changed, 16 insertions, 30 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 4ebf4df7f191..f2148376f1a7 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #include <linux/smp_lock.h> | 43 | #include <linux/smp_lock.h> |
44 | #include <linux/nfs_fs.h> | 44 | #include <linux/nfs_fs.h> |
45 | #include <linux/nfs_idmap.h> | 45 | #include <linux/nfs_idmap.h> |
46 | #include <linux/kthread.h> | ||
47 | #include <linux/module.h> | ||
46 | #include <linux/workqueue.h> | 48 | #include <linux/workqueue.h> |
47 | #include <linux/bitops.h> | 49 | #include <linux/bitops.h> |
48 | 50 | ||
@@ -57,8 +59,6 @@ const nfs4_stateid zero_stateid; | |||
57 | static DEFINE_SPINLOCK(state_spinlock); | 59 | static DEFINE_SPINLOCK(state_spinlock); |
58 | static LIST_HEAD(nfs4_clientid_list); | 60 | static LIST_HEAD(nfs4_clientid_list); |
59 | 61 | ||
60 | static void nfs4_recover_state(void *); | ||
61 | |||
62 | void | 62 | void |
63 | init_nfsv4_state(struct nfs_server *server) | 63 | init_nfsv4_state(struct nfs_server *server) |
64 | { | 64 | { |
@@ -103,7 +103,6 @@ nfs4_alloc_client(struct in_addr *addr) | |||
103 | INIT_LIST_HEAD(&clp->cl_unused); | 103 | INIT_LIST_HEAD(&clp->cl_unused); |
104 | spin_lock_init(&clp->cl_lock); | 104 | spin_lock_init(&clp->cl_lock); |
105 | atomic_set(&clp->cl_count, 1); | 105 | atomic_set(&clp->cl_count, 1); |
106 | INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp); | ||
107 | INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); | 106 | INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); |
108 | INIT_LIST_HEAD(&clp->cl_superblocks); | 107 | INIT_LIST_HEAD(&clp->cl_superblocks); |
109 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); | 108 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); |
@@ -734,10 +733,6 @@ out: | |||
734 | } | 733 | } |
735 | 734 | ||
736 | static int reclaimer(void *); | 735 | static int reclaimer(void *); |
737 | struct reclaimer_args { | ||
738 | struct nfs4_client *clp; | ||
739 | struct completion complete; | ||
740 | }; | ||
741 | 736 | ||
742 | static inline void nfs4_clear_recover_bit(struct nfs4_client *clp) | 737 | static inline void nfs4_clear_recover_bit(struct nfs4_client *clp) |
743 | { | 738 | { |
@@ -751,35 +746,30 @@ static inline void nfs4_clear_recover_bit(struct nfs4_client *clp) | |||
751 | /* | 746 | /* |
752 | * State recovery routine | 747 | * State recovery routine |
753 | */ | 748 | */ |
754 | void | 749 | static void nfs4_recover_state(struct nfs4_client *clp) |
755 | nfs4_recover_state(void *data) | ||
756 | { | 750 | { |
757 | struct nfs4_client *clp = (struct nfs4_client *)data; | 751 | struct task_struct *task; |
758 | struct reclaimer_args args = { | ||
759 | .clp = clp, | ||
760 | }; | ||
761 | might_sleep(); | ||
762 | |||
763 | init_completion(&args.complete); | ||
764 | 752 | ||
765 | if (kernel_thread(reclaimer, &args, CLONE_KERNEL) < 0) | 753 | __module_get(THIS_MODULE); |
766 | goto out_failed_clear; | 754 | atomic_inc(&clp->cl_count); |
767 | wait_for_completion(&args.complete); | 755 | task = kthread_run(reclaimer, clp, "%u.%u.%u.%u-reclaim", |
768 | return; | 756 | NIPQUAD(clp->cl_addr)); |
769 | out_failed_clear: | 757 | if (!IS_ERR(task)) |
758 | return; | ||
770 | nfs4_clear_recover_bit(clp); | 759 | nfs4_clear_recover_bit(clp); |
760 | nfs4_put_client(clp); | ||
761 | module_put(THIS_MODULE); | ||
771 | } | 762 | } |
772 | 763 | ||
773 | /* | 764 | /* |
774 | * Schedule a state recovery attempt | 765 | * Schedule a state recovery attempt |
775 | */ | 766 | */ |
776 | void | 767 | void nfs4_schedule_state_recovery(struct nfs4_client *clp) |
777 | nfs4_schedule_state_recovery(struct nfs4_client *clp) | ||
778 | { | 768 | { |
779 | if (!clp) | 769 | if (!clp) |
780 | return; | 770 | return; |
781 | if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) | 771 | if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) |
782 | schedule_work(&clp->cl_recoverd); | 772 | nfs4_recover_state(clp); |
783 | } | 773 | } |
784 | 774 | ||
785 | static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_state *state) | 775 | static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_state *state) |
@@ -895,18 +885,13 @@ static void nfs4_state_mark_reclaim(struct nfs4_client *clp) | |||
895 | 885 | ||
896 | static int reclaimer(void *ptr) | 886 | static int reclaimer(void *ptr) |
897 | { | 887 | { |
898 | struct reclaimer_args *args = (struct reclaimer_args *)ptr; | 888 | struct nfs4_client *clp = ptr; |
899 | struct nfs4_client *clp = args->clp; | ||
900 | struct nfs4_state_owner *sp; | 889 | struct nfs4_state_owner *sp; |
901 | struct nfs4_state_recovery_ops *ops; | 890 | struct nfs4_state_recovery_ops *ops; |
902 | int status = 0; | 891 | int status = 0; |
903 | 892 | ||
904 | daemonize("%u.%u.%u.%u-reclaim", NIPQUAD(clp->cl_addr)); | ||
905 | allow_signal(SIGKILL); | 893 | allow_signal(SIGKILL); |
906 | 894 | ||
907 | atomic_inc(&clp->cl_count); | ||
908 | complete(&args->complete); | ||
909 | |||
910 | /* Ensure exclusive access to NFSv4 state */ | 895 | /* Ensure exclusive access to NFSv4 state */ |
911 | lock_kernel(); | 896 | lock_kernel(); |
912 | down_write(&clp->cl_sem); | 897 | down_write(&clp->cl_sem); |
@@ -954,6 +939,7 @@ out: | |||
954 | nfs_handle_cb_pathdown(clp); | 939 | nfs_handle_cb_pathdown(clp); |
955 | nfs4_clear_recover_bit(clp); | 940 | nfs4_clear_recover_bit(clp); |
956 | nfs4_put_client(clp); | 941 | nfs4_put_client(clp); |
942 | module_put_and_exit(0); | ||
957 | return 0; | 943 | return 0; |
958 | out_error: | 944 | out_error: |
959 | printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %u.%u.%u.%u with error %d\n", | 945 | printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %u.%u.%u.%u with error %d\n", |