46
46
#include <linux/nfs4.h>
47
47
#include <linux/nfs_fs.h>
48
48
#include <linux/nfs_page.h>
49
+ #include <linux/nfs_mount.h>
49
50
#include <linux/namei.h>
50
51
#include <linux/mount.h>
51
52
#include <linux/module.h>
@@ -443,8 +444,8 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
443
444
if (res -> sr_status == 1 )
444
445
res -> sr_status = NFS_OK ;
445
446
446
- /* -ERESTARTSYS can result in skipping nfs41_sequence_setup */
447
- if (!res -> sr_slot )
447
+ /* don't increment the sequence number if the task wasn't sent */
448
+ if (!RPC_WAS_SENT ( task ) )
448
449
goto out ;
449
450
450
451
/* Check the SEQUENCE operation status */
@@ -2185,9 +2186,14 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
2185
2186
struct nfs4_exception exception = { };
2186
2187
int err ;
2187
2188
do {
2188
- err = nfs4_handle_exception (server ,
2189
- _nfs4_lookup_root (server , fhandle , info ),
2190
- & exception );
2189
+ err = _nfs4_lookup_root (server , fhandle , info );
2190
+ switch (err ) {
2191
+ case 0 :
2192
+ case - NFS4ERR_WRONGSEC :
2193
+ break ;
2194
+ default :
2195
+ err = nfs4_handle_exception (server , err , & exception );
2196
+ }
2191
2197
} while (exception .retry );
2192
2198
return err ;
2193
2199
}
@@ -2208,25 +2214,47 @@ static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandl
2208
2214
return ret ;
2209
2215
}
2210
2216
2211
- /*
2212
- * get the file handle for the "/" directory on the server
2213
- */
2214
- static int nfs4_proc_get_root (struct nfs_server * server , struct nfs_fh * fhandle ,
2217
+ static int nfs4_find_root_sec (struct nfs_server * server , struct nfs_fh * fhandle ,
2215
2218
struct nfs_fsinfo * info )
2216
2219
{
2217
2220
int i , len , status = 0 ;
2218
- rpc_authflavor_t flav_array [NFS_MAX_SECFLAVORS + 2 ];
2221
+ rpc_authflavor_t flav_array [NFS_MAX_SECFLAVORS ];
2219
2222
2220
- flav_array [0 ] = RPC_AUTH_UNIX ;
2221
- len = gss_mech_list_pseudoflavors (& flav_array [1 ]);
2222
- flav_array [1 + len ] = RPC_AUTH_NULL ;
2223
- len += 2 ;
2223
+ len = gss_mech_list_pseudoflavors (& flav_array [0 ]);
2224
+ flav_array [len ] = RPC_AUTH_NULL ;
2225
+ len += 1 ;
2224
2226
2225
2227
for (i = 0 ; i < len ; i ++ ) {
2226
2228
status = nfs4_lookup_root_sec (server , fhandle , info , flav_array [i ]);
2227
- if (status != - EPERM )
2228
- break ;
2229
+ if (status == - NFS4ERR_WRONGSEC || status == - EACCES )
2230
+ continue ;
2231
+ break ;
2229
2232
}
2233
+ /*
2234
+ * -EACCESS could mean that the user doesn't have correct permissions
2235
+ * to access the mount. It could also mean that we tried to mount
2236
+ * with a gss auth flavor, but rpc.gssd isn't running. Either way,
2237
+ * existing mount programs don't handle -EACCES very well so it should
2238
+ * be mapped to -EPERM instead.
2239
+ */
2240
+ if (status == - EACCES )
2241
+ status = - EPERM ;
2242
+ return status ;
2243
+ }
2244
+
2245
+ /*
2246
+ * get the file handle for the "/" directory on the server
2247
+ */
2248
+ static int nfs4_proc_get_root (struct nfs_server * server , struct nfs_fh * fhandle ,
2249
+ struct nfs_fsinfo * info )
2250
+ {
2251
+ int status = nfs4_lookup_root (server , fhandle , info );
2252
+ if ((status == - NFS4ERR_WRONGSEC ) && !(server -> flags & NFS_MOUNT_SECFLAVOUR ))
2253
+ /*
2254
+ * A status of -NFS4ERR_WRONGSEC will be mapped to -EPERM
2255
+ * by nfs4_map_errors() as this function exits.
2256
+ */
2257
+ status = nfs4_find_root_sec (server , fhandle , info );
2230
2258
if (status == 0 )
2231
2259
status = nfs4_server_capabilities (server , fhandle );
2232
2260
if (status == 0 )
@@ -3723,21 +3751,20 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
3723
3751
sizeof (setclientid .sc_uaddr ), "%s.%u.%u" ,
3724
3752
clp -> cl_ipaddr , port >> 8 , port & 255 );
3725
3753
3726
- status = rpc_call_sync (clp -> cl_rpcclient , & msg , 0 );
3754
+ status = rpc_call_sync (clp -> cl_rpcclient , & msg , RPC_TASK_TIMEOUT );
3727
3755
if (status != - NFS4ERR_CLID_INUSE )
3728
3756
break ;
3729
- if (signalled ())
3757
+ if (loop != 0 ) {
3758
+ ++ clp -> cl_id_uniquifier ;
3730
3759
break ;
3731
- if (loop ++ & 1 )
3732
- ssleep (clp -> cl_lease_time / HZ + 1 );
3733
- else
3734
- if (++ clp -> cl_id_uniquifier == 0 )
3735
- break ;
3760
+ }
3761
+ ++ loop ;
3762
+ ssleep (clp -> cl_lease_time / HZ + 1 );
3736
3763
}
3737
3764
return status ;
3738
3765
}
3739
3766
3740
- static int _nfs4_proc_setclientid_confirm (struct nfs_client * clp ,
3767
+ int nfs4_proc_setclientid_confirm (struct nfs_client * clp ,
3741
3768
struct nfs4_setclientid_res * arg ,
3742
3769
struct rpc_cred * cred )
3743
3770
{
@@ -3752,7 +3779,7 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp,
3752
3779
int status ;
3753
3780
3754
3781
now = jiffies ;
3755
- status = rpc_call_sync (clp -> cl_rpcclient , & msg , 0 );
3782
+ status = rpc_call_sync (clp -> cl_rpcclient , & msg , RPC_TASK_TIMEOUT );
3756
3783
if (status == 0 ) {
3757
3784
spin_lock (& clp -> cl_lock );
3758
3785
clp -> cl_lease_time = fsinfo .lease_time * HZ ;
@@ -3762,26 +3789,6 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp,
3762
3789
return status ;
3763
3790
}
3764
3791
3765
- int nfs4_proc_setclientid_confirm (struct nfs_client * clp ,
3766
- struct nfs4_setclientid_res * arg ,
3767
- struct rpc_cred * cred )
3768
- {
3769
- long timeout = 0 ;
3770
- int err ;
3771
- do {
3772
- err = _nfs4_proc_setclientid_confirm (clp , arg , cred );
3773
- switch (err ) {
3774
- case 0 :
3775
- return err ;
3776
- case - NFS4ERR_RESOURCE :
3777
- /* The IBM lawyers misread another document! */
3778
- case - NFS4ERR_DELAY :
3779
- err = nfs4_delay (clp -> cl_rpcclient , & timeout );
3780
- }
3781
- } while (err == 0 );
3782
- return err ;
3783
- }
3784
-
3785
3792
struct nfs4_delegreturndata {
3786
3793
struct nfs4_delegreturnargs args ;
3787
3794
struct nfs4_delegreturnres res ;
@@ -4786,7 +4793,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4786
4793
init_utsname ()-> domainname ,
4787
4794
clp -> cl_rpcclient -> cl_auth -> au_flavor );
4788
4795
4789
- status = rpc_call_sync (clp -> cl_rpcclient , & msg , 0 );
4796
+ status = rpc_call_sync (clp -> cl_rpcclient , & msg , RPC_TASK_TIMEOUT );
4790
4797
if (!status )
4791
4798
status = nfs4_check_cl_exchange_flags (clp -> cl_exchange_flags );
4792
4799
dprintk ("<-- %s status= %d\n" , __func__ , status );
@@ -4869,7 +4876,8 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
4869
4876
.rpc_client = clp -> cl_rpcclient ,
4870
4877
.rpc_message = & msg ,
4871
4878
.callback_ops = & nfs4_get_lease_time_ops ,
4872
- .callback_data = & data
4879
+ .callback_data = & data ,
4880
+ .flags = RPC_TASK_TIMEOUT ,
4873
4881
};
4874
4882
int status ;
4875
4883
@@ -5171,7 +5179,7 @@ static int _nfs4_proc_create_session(struct nfs_client *clp)
5171
5179
nfs4_init_channel_attrs (& args );
5172
5180
args .flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN );
5173
5181
5174
- status = rpc_call_sync (session -> clp -> cl_rpcclient , & msg , 0 );
5182
+ status = rpc_call_sync (session -> clp -> cl_rpcclient , & msg , RPC_TASK_TIMEOUT );
5175
5183
5176
5184
if (!status )
5177
5185
/* Verify the session's negotiated channel_attrs values */
@@ -5194,20 +5202,10 @@ int nfs4_proc_create_session(struct nfs_client *clp)
5194
5202
int status ;
5195
5203
unsigned * ptr ;
5196
5204
struct nfs4_session * session = clp -> cl_session ;
5197
- long timeout = 0 ;
5198
- int err ;
5199
5205
5200
5206
dprintk ("--> %s clp=%p session=%p\n" , __func__ , clp , session );
5201
5207
5202
- do {
5203
- status = _nfs4_proc_create_session (clp );
5204
- if (status == - NFS4ERR_DELAY ) {
5205
- err = nfs4_delay (clp -> cl_rpcclient , & timeout );
5206
- if (err )
5207
- status = err ;
5208
- }
5209
- } while (status == - NFS4ERR_DELAY );
5210
-
5208
+ status = _nfs4_proc_create_session (clp );
5211
5209
if (status )
5212
5210
goto out ;
5213
5211
@@ -5248,7 +5246,7 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
5248
5246
msg .rpc_argp = session ;
5249
5247
msg .rpc_resp = NULL ;
5250
5248
msg .rpc_cred = NULL ;
5251
- status = rpc_call_sync (session -> clp -> cl_rpcclient , & msg , 0 );
5249
+ status = rpc_call_sync (session -> clp -> cl_rpcclient , & msg , RPC_TASK_TIMEOUT );
5252
5250
5253
5251
if (status )
5254
5252
printk (KERN_WARNING
0 commit comments