aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-03 03:55:26 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-06 14:58:47 -0500
commit286d7d6a0cb38d3d4316a1dfea9b0c0fc5a6455b (patch)
tree844ea8a14db8261a3977ae4d460e227402a4a426 /fs/nfs
parentb4454fe1a7cb76a248d0641c9d68a44a1b8d9a1f (diff)
NFSv4: Remove requirement for machine creds for the "setclientid" operation
Use a cred from the nfs4_client->cl_state_owners list. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/inode.c14
-rw-r--r--fs/nfs/nfs4_fs.h6
-rw-r--r--fs/nfs/nfs4proc.c10
-rw-r--r--fs/nfs/nfs4state.c71
4 files changed, 52 insertions, 49 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 432f41cd75e6..740d3cd40246 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1822,23 +1822,9 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1822 clnt->cl_softrtry = 1; 1822 clnt->cl_softrtry = 1;
1823 clnt->cl_chatty = 1; 1823 clnt->cl_chatty = 1;
1824 clp->cl_rpcclient = clnt; 1824 clp->cl_rpcclient = clnt;
1825 clp->cl_cred = rpcauth_lookupcred(clnt->cl_auth, 0);
1826 if (IS_ERR(clp->cl_cred)) {
1827 up_write(&clp->cl_sem);
1828 err = PTR_ERR(clp->cl_cred);
1829 clp->cl_cred = NULL;
1830 goto out_fail;
1831 }
1832 memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); 1825 memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));
1833 nfs_idmap_new(clp); 1826 nfs_idmap_new(clp);
1834 } 1827 }
1835 if (list_empty(&clp->cl_superblocks)) {
1836 err = nfs4_init_client(clp);
1837 if (err != 0) {
1838 up_write(&clp->cl_sem);
1839 goto out_fail;
1840 }
1841 }
1842 list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); 1828 list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
1843 clnt = rpc_clone_client(clp->cl_rpcclient); 1829 clnt = rpc_clone_client(clp->cl_rpcclient);
1844 if (!IS_ERR(clnt)) 1830 if (!IS_ERR(clnt))
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 4a9c53e0793c..0f5e4e7cddec 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -68,7 +68,6 @@ struct nfs4_client {
68 atomic_t cl_count; 68 atomic_t cl_count;
69 69
70 struct rpc_clnt * cl_rpcclient; 70 struct rpc_clnt * cl_rpcclient;
71 struct rpc_cred * cl_cred;
72 71
73 struct list_head cl_superblocks; /* List of nfs_server structs */ 72 struct list_head cl_superblocks; /* List of nfs_server structs */
74 73
@@ -211,8 +210,8 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
211 210
212/* nfs4proc.c */ 211/* nfs4proc.c */
213extern int nfs4_map_errors(int err); 212extern int nfs4_map_errors(int err);
214extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short); 213extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short, struct rpc_cred *);
215extern int nfs4_proc_setclientid_confirm(struct nfs4_client *); 214extern int nfs4_proc_setclientid_confirm(struct nfs4_client *, struct rpc_cred *);
216extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *); 215extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *);
217extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *); 216extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *);
218extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); 217extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state);
@@ -238,7 +237,6 @@ extern void init_nfsv4_state(struct nfs_server *);
238extern void destroy_nfsv4_state(struct nfs_server *); 237extern void destroy_nfsv4_state(struct nfs_server *);
239extern struct nfs4_client *nfs4_get_client(struct in_addr *); 238extern struct nfs4_client *nfs4_get_client(struct in_addr *);
240extern void nfs4_put_client(struct nfs4_client *clp); 239extern void nfs4_put_client(struct nfs4_client *clp);
241extern int nfs4_init_client(struct nfs4_client *clp);
242extern struct nfs4_client *nfs4_find_client(struct in_addr *); 240extern struct nfs4_client *nfs4_find_client(struct in_addr *);
243struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp); 241struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp);
244extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *); 242extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index e38401931291..b3349154994b 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2846,7 +2846,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct
2846 return nfs4_map_errors(ret); 2846 return nfs4_map_errors(ret);
2847} 2847}
2848 2848
2849int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port) 2849int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
2850{ 2850{
2851 nfs4_verifier sc_verifier; 2851 nfs4_verifier sc_verifier;
2852 struct nfs4_setclientid setclientid = { 2852 struct nfs4_setclientid setclientid = {
@@ -2857,7 +2857,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p
2857 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], 2857 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
2858 .rpc_argp = &setclientid, 2858 .rpc_argp = &setclientid,
2859 .rpc_resp = clp, 2859 .rpc_resp = clp,
2860 .rpc_cred = clp->cl_cred, 2860 .rpc_cred = cred,
2861 }; 2861 };
2862 u32 *p; 2862 u32 *p;
2863 int loop = 0; 2863 int loop = 0;
@@ -2871,7 +2871,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p
2871 setclientid.sc_name_len = scnprintf(setclientid.sc_name, 2871 setclientid.sc_name_len = scnprintf(setclientid.sc_name,
2872 sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", 2872 sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u",
2873 clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr), 2873 clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr),
2874 clp->cl_cred->cr_ops->cr_name, 2874 cred->cr_ops->cr_name,
2875 clp->cl_id_uniquifier); 2875 clp->cl_id_uniquifier);
2876 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, 2876 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
2877 sizeof(setclientid.sc_netid), "tcp"); 2877 sizeof(setclientid.sc_netid), "tcp");
@@ -2894,14 +2894,14 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p
2894} 2894}
2895 2895
2896int 2896int
2897nfs4_proc_setclientid_confirm(struct nfs4_client *clp) 2897nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred)
2898{ 2898{
2899 struct nfs_fsinfo fsinfo; 2899 struct nfs_fsinfo fsinfo;
2900 struct rpc_message msg = { 2900 struct rpc_message msg = {
2901 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], 2901 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
2902 .rpc_argp = clp, 2902 .rpc_argp = clp,
2903 .rpc_resp = &fsinfo, 2903 .rpc_resp = &fsinfo,
2904 .rpc_cred = clp->cl_cred, 2904 .rpc_cred = cred,
2905 }; 2905 };
2906 unsigned long now; 2906 unsigned long now;
2907 int status; 2907 int status;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 18f6ed1a0b54..afad0255e7db 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -91,11 +91,10 @@ nfs4_alloc_client(struct in_addr *addr)
91 91
92 if (nfs_callback_up() < 0) 92 if (nfs_callback_up() < 0)
93 return NULL; 93 return NULL;
94 if ((clp = kmalloc(sizeof(*clp), GFP_KERNEL)) == NULL) { 94 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) {
95 nfs_callback_down(); 95 nfs_callback_down();
96 return NULL; 96 return NULL;
97 } 97 }
98 memset(clp, 0, sizeof(*clp));
99 memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr)); 98 memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr));
100 init_rwsem(&clp->cl_sem); 99 init_rwsem(&clp->cl_sem);
101 INIT_LIST_HEAD(&clp->cl_delegations); 100 INIT_LIST_HEAD(&clp->cl_delegations);
@@ -108,7 +107,7 @@ nfs4_alloc_client(struct in_addr *addr)
108 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); 107 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
109 clp->cl_rpcclient = ERR_PTR(-EINVAL); 108 clp->cl_rpcclient = ERR_PTR(-EINVAL);
110 clp->cl_boot_time = CURRENT_TIME; 109 clp->cl_boot_time = CURRENT_TIME;
111 clp->cl_state = 0; 110 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
112 return clp; 111 return clp;
113} 112}
114 113
@@ -125,8 +124,6 @@ nfs4_free_client(struct nfs4_client *clp)
125 kfree(sp); 124 kfree(sp);
126 } 125 }
127 BUG_ON(!list_empty(&clp->cl_state_owners)); 126 BUG_ON(!list_empty(&clp->cl_state_owners));
128 if (clp->cl_cred)
129 put_rpccred(clp->cl_cred);
130 nfs_idmap_delete(clp); 127 nfs_idmap_delete(clp);
131 if (!IS_ERR(clp->cl_rpcclient)) 128 if (!IS_ERR(clp->cl_rpcclient))
132 rpc_shutdown_client(clp->cl_rpcclient); 129 rpc_shutdown_client(clp->cl_rpcclient);
@@ -196,21 +193,17 @@ nfs4_put_client(struct nfs4_client *clp)
196 nfs4_free_client(clp); 193 nfs4_free_client(clp);
197} 194}
198 195
199static int __nfs4_init_client(struct nfs4_client *clp) 196static int nfs4_init_client(struct nfs4_client *clp, struct rpc_cred *cred)
200{ 197{
201 int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, nfs_callback_tcpport); 198 int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK,
199 nfs_callback_tcpport, cred);
202 if (status == 0) 200 if (status == 0)
203 status = nfs4_proc_setclientid_confirm(clp); 201 status = nfs4_proc_setclientid_confirm(clp, cred);
204 if (status == 0) 202 if (status == 0)
205 nfs4_schedule_state_renewal(clp); 203 nfs4_schedule_state_renewal(clp);
206 return status; 204 return status;
207} 205}
208 206
209int nfs4_init_client(struct nfs4_client *clp)
210{
211 return nfs4_map_errors(__nfs4_init_client(clp));
212}
213
214u32 207u32
215nfs4_alloc_lockowner_id(struct nfs4_client *clp) 208nfs4_alloc_lockowner_id(struct nfs4_client *clp)
216{ 209{
@@ -246,6 +239,18 @@ struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp)
246 return cred; 239 return cred;
247} 240}
248 241
242struct rpc_cred *nfs4_get_setclientid_cred(struct nfs4_client *clp)
243{
244 struct nfs4_state_owner *sp;
245
246 if (!list_empty(&clp->cl_state_owners)) {
247 sp = list_entry(clp->cl_state_owners.next,
248 struct nfs4_state_owner, so_list);
249 return get_rpccred(sp->so_cred);
250 }
251 return NULL;
252}
253
249static struct nfs4_state_owner * 254static struct nfs4_state_owner *
250nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred) 255nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred)
251{ 256{
@@ -902,6 +907,7 @@ static int reclaimer(void *ptr)
902 struct nfs4_client *clp = ptr; 907 struct nfs4_client *clp = ptr;
903 struct nfs4_state_owner *sp; 908 struct nfs4_state_owner *sp;
904 struct nfs4_state_recovery_ops *ops; 909 struct nfs4_state_recovery_ops *ops;
910 struct rpc_cred *cred;
905 int status = 0; 911 int status = 0;
906 912
907 allow_signal(SIGKILL); 913 allow_signal(SIGKILL);
@@ -913,20 +919,33 @@ static int reclaimer(void *ptr)
913 if (list_empty(&clp->cl_superblocks)) 919 if (list_empty(&clp->cl_superblocks))
914 goto out; 920 goto out;
915restart_loop: 921restart_loop:
916 status = nfs4_proc_renew(clp, clp->cl_cred); 922 ops = &nfs4_network_partition_recovery_ops;
917 switch (status) { 923 /* Are there any open files on this volume? */
918 case 0: 924 cred = nfs4_get_renew_cred(clp);
919 case -NFS4ERR_CB_PATH_DOWN: 925 if (cred != NULL) {
920 goto out; 926 /* Yes there are: try to renew the old lease */
921 case -NFS4ERR_STALE_CLIENTID: 927 status = nfs4_proc_renew(clp, cred);
922 case -NFS4ERR_LEASE_MOVED: 928 switch (status) {
923 ops = &nfs4_reboot_recovery_ops; 929 case 0:
924 break; 930 case -NFS4ERR_CB_PATH_DOWN:
925 default: 931 put_rpccred(cred);
926 ops = &nfs4_network_partition_recovery_ops; 932 goto out;
927 }; 933 case -NFS4ERR_STALE_CLIENTID:
934 case -NFS4ERR_LEASE_MOVED:
935 ops = &nfs4_reboot_recovery_ops;
936 }
937 } else {
938 /* "reboot" to ensure we clear all state on the server */
939 clp->cl_boot_time = CURRENT_TIME;
940 cred = nfs4_get_setclientid_cred(clp);
941 }
942 /* We're going to have to re-establish a clientid */
928 nfs4_state_mark_reclaim(clp); 943 nfs4_state_mark_reclaim(clp);
929 status = __nfs4_init_client(clp); 944 status = -ENOENT;
945 if (cred != NULL) {
946 status = nfs4_init_client(clp, cred);
947 put_rpccred(cred);
948 }
930 if (status) 949 if (status)
931 goto out_error; 950 goto out_error;
932 /* Mark all delegations for reclaim */ 951 /* Mark all delegations for reclaim */