~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/nfs/fs_context.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/nfs/fs_context.c (Version linux-6.12-rc7) and /fs/nfs/fs_context.c (Version linux-4.4.302)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * linux/fs/nfs/fs_context.c                      
  4  *                                                
  5  * Copyright (C) 1992 Rick Sladkey                
  6  * Conversion to new mount api Copyright (C) D    
  7  *                                                
  8  * NFS mount handling.                            
  9  *                                                
 10  * Split from fs/nfs/super.c by David Howells     
 11  */                                               
 12                                                   
 13 #include <linux/compat.h>                         
 14 #include <linux/module.h>                         
 15 #include <linux/fs.h>                             
 16 #include <linux/fs_context.h>                     
 17 #include <linux/fs_parser.h>                      
 18 #include <linux/nfs_fs.h>                         
 19 #include <linux/nfs_mount.h>                      
 20 #include <linux/nfs4_mount.h>                     
 21                                                   
 22 #include <net/handshake.h>                        
 23                                                   
 24 #include "nfs.h"                                  
 25 #include "internal.h"                             
 26                                                   
 27 #include "nfstrace.h"                             
 28                                                   
 29 #define NFSDBG_FACILITY         NFSDBG_MOUNT      
 30                                                   
 31 #if IS_ENABLED(CONFIG_NFS_V3)                     
 32 #define NFS_DEFAULT_VERSION 3                     
 33 #else                                             
 34 #define NFS_DEFAULT_VERSION 2                     
 35 #endif                                            
 36                                                   
 37 #define NFS_MAX_CONNECTIONS 16                    
 38                                                   
 39 enum nfs_param {                                  
 40         Opt_ac,                                   
 41         Opt_acdirmax,                             
 42         Opt_acdirmin,                             
 43         Opt_acl,                                  
 44         Opt_acregmax,                             
 45         Opt_acregmin,                             
 46         Opt_actimeo,                              
 47         Opt_addr,                                 
 48         Opt_bg,                                   
 49         Opt_bsize,                                
 50         Opt_clientaddr,                           
 51         Opt_cto,                                  
 52         Opt_alignwrite,                           
 53         Opt_fg,                                   
 54         Opt_fscache,                              
 55         Opt_fscache_flag,                         
 56         Opt_hard,                                 
 57         Opt_intr,                                 
 58         Opt_local_lock,                           
 59         Opt_lock,                                 
 60         Opt_lookupcache,                          
 61         Opt_migration,                            
 62         Opt_minorversion,                         
 63         Opt_mountaddr,                            
 64         Opt_mounthost,                            
 65         Opt_mountport,                            
 66         Opt_mountproto,                           
 67         Opt_mountvers,                            
 68         Opt_namelen,                              
 69         Opt_nconnect,                             
 70         Opt_max_connect,                          
 71         Opt_port,                                 
 72         Opt_posix,                                
 73         Opt_proto,                                
 74         Opt_rdirplus,                             
 75         Opt_rdma,                                 
 76         Opt_resvport,                             
 77         Opt_retrans,                              
 78         Opt_retry,                                
 79         Opt_rsize,                                
 80         Opt_sec,                                  
 81         Opt_sharecache,                           
 82         Opt_sloppy,                               
 83         Opt_soft,                                 
 84         Opt_softerr,                              
 85         Opt_softreval,                            
 86         Opt_source,                               
 87         Opt_tcp,                                  
 88         Opt_timeo,                                
 89         Opt_trunkdiscovery,                       
 90         Opt_udp,                                  
 91         Opt_v,                                    
 92         Opt_vers,                                 
 93         Opt_wsize,                                
 94         Opt_write,                                
 95         Opt_xprtsec,                              
 96 };                                                
 97                                                   
 98 enum {                                            
 99         Opt_local_lock_all,                       
100         Opt_local_lock_flock,                     
101         Opt_local_lock_none,                      
102         Opt_local_lock_posix,                     
103 };                                                
104                                                   
105 static const struct constant_table nfs_param_e    
106         { "all",                Opt_local_lock    
107         { "flock",      Opt_local_lock_flock }    
108         { "posix",      Opt_local_lock_posix }    
109         { "none",               Opt_local_lock    
110         {}                                        
111 };                                                
112                                                   
113 enum {                                            
114         Opt_lookupcache_all,                      
115         Opt_lookupcache_none,                     
116         Opt_lookupcache_positive,                 
117 };                                                
118                                                   
119 static const struct constant_table nfs_param_e    
120         { "all",                Opt_lookupcach    
121         { "none",               Opt_lookupcach    
122         { "pos",                Opt_lookupcach    
123         { "positive",           Opt_lookupcach    
124         {}                                        
125 };                                                
126                                                   
127 enum {                                            
128         Opt_write_lazy,                           
129         Opt_write_eager,                          
130         Opt_write_wait,                           
131 };                                                
132                                                   
133 static const struct constant_table nfs_param_e    
134         { "lazy",               Opt_write_lazy    
135         { "eager",              Opt_write_eage    
136         { "wait",               Opt_write_wait    
137         {}                                        
138 };                                                
139                                                   
140 static const struct fs_parameter_spec nfs_fs_p    
141         fsparam_flag_no("ac",           Opt_ac    
142         fsparam_u32   ("acdirmax",      Opt_ac    
143         fsparam_u32   ("acdirmin",      Opt_ac    
144         fsparam_flag_no("acl",          Opt_ac    
145         fsparam_u32   ("acregmax",      Opt_ac    
146         fsparam_u32   ("acregmin",      Opt_ac    
147         fsparam_u32   ("actimeo",       Opt_ac    
148         fsparam_string("addr",          Opt_ad    
149         fsparam_flag  ("bg",            Opt_bg    
150         fsparam_u32   ("bsize",         Opt_bs    
151         fsparam_string("clientaddr",    Opt_cl    
152         fsparam_flag_no("cto",          Opt_ct    
153         fsparam_flag_no("alignwrite",   Opt_al    
154         fsparam_flag  ("fg",            Opt_fg    
155         fsparam_flag_no("fsc",          Opt_fs    
156         fsparam_string("fsc",           Opt_fs    
157         fsparam_flag  ("hard",          Opt_ha    
158         __fsparam(NULL, "intr",         Opt_in    
159                   fs_param_neg_with_no|fs_para    
160         fsparam_enum  ("local_lock",    Opt_lo    
161         fsparam_flag_no("lock",         Opt_lo    
162         fsparam_enum  ("lookupcache",   Opt_lo    
163         fsparam_flag_no("migration",    Opt_mi    
164         fsparam_u32   ("minorversion",  Opt_mi    
165         fsparam_string("mountaddr",     Opt_mo    
166         fsparam_string("mounthost",     Opt_mo    
167         fsparam_u32   ("mountport",     Opt_mo    
168         fsparam_string("mountproto",    Opt_mo    
169         fsparam_u32   ("mountvers",     Opt_mo    
170         fsparam_u32   ("namlen",        Opt_na    
171         fsparam_u32   ("nconnect",      Opt_nc    
172         fsparam_u32   ("max_connect",   Opt_ma    
173         fsparam_string("nfsvers",       Opt_ve    
174         fsparam_u32   ("port",          Opt_po    
175         fsparam_flag_no("posix",        Opt_po    
176         fsparam_string("proto",         Opt_pr    
177         fsparam_flag_no("rdirplus",     Opt_rd    
178         fsparam_flag  ("rdma",          Opt_rd    
179         fsparam_flag_no("resvport",     Opt_re    
180         fsparam_u32   ("retrans",       Opt_re    
181         fsparam_string("retry",         Opt_re    
182         fsparam_u32   ("rsize",         Opt_rs    
183         fsparam_string("sec",           Opt_se    
184         fsparam_flag_no("sharecache",   Opt_sh    
185         fsparam_flag  ("sloppy",        Opt_sl    
186         fsparam_flag  ("soft",          Opt_so    
187         fsparam_flag  ("softerr",       Opt_so    
188         fsparam_flag  ("softreval",     Opt_so    
189         fsparam_string("source",        Opt_so    
190         fsparam_flag  ("tcp",           Opt_tc    
191         fsparam_u32   ("timeo",         Opt_ti    
192         fsparam_flag_no("trunkdiscovery", Opt_    
193         fsparam_flag  ("udp",           Opt_ud    
194         fsparam_flag  ("v2",            Opt_v)    
195         fsparam_flag  ("v3",            Opt_v)    
196         fsparam_flag  ("v4",            Opt_v)    
197         fsparam_flag  ("v4.0",          Opt_v)    
198         fsparam_flag  ("v4.1",          Opt_v)    
199         fsparam_flag  ("v4.2",          Opt_v)    
200         fsparam_string("vers",          Opt_ve    
201         fsparam_enum  ("write",         Opt_wr    
202         fsparam_u32   ("wsize",         Opt_ws    
203         fsparam_string("xprtsec",       Opt_xp    
204         {}                                        
205 };                                                
206                                                   
207 enum {                                            
208         Opt_vers_2,                               
209         Opt_vers_3,                               
210         Opt_vers_4,                               
211         Opt_vers_4_0,                             
212         Opt_vers_4_1,                             
213         Opt_vers_4_2,                             
214 };                                                
215                                                   
216 static const struct constant_table nfs_vers_to    
217         { "2",          Opt_vers_2 },             
218         { "3",          Opt_vers_3 },             
219         { "4",          Opt_vers_4 },             
220         { "4.0",        Opt_vers_4_0 },           
221         { "4.1",        Opt_vers_4_1 },           
222         { "4.2",        Opt_vers_4_2 },           
223         {}                                        
224 };                                                
225                                                   
226 enum {                                            
227         Opt_xprt_rdma,                            
228         Opt_xprt_rdma6,                           
229         Opt_xprt_tcp,                             
230         Opt_xprt_tcp6,                            
231         Opt_xprt_udp,                             
232         Opt_xprt_udp6,                            
233         nr__Opt_xprt                              
234 };                                                
235                                                   
236 static const struct constant_table nfs_xprt_pr    
237         { "rdma",       Opt_xprt_rdma },          
238         { "rdma6",      Opt_xprt_rdma6 },         
239         { "tcp",        Opt_xprt_tcp },           
240         { "tcp6",       Opt_xprt_tcp6 },          
241         { "udp",        Opt_xprt_udp },           
242         { "udp6",       Opt_xprt_udp6 },          
243         {}                                        
244 };                                                
245                                                   
246 enum {                                            
247         Opt_sec_krb5,                             
248         Opt_sec_krb5i,                            
249         Opt_sec_krb5p,                            
250         Opt_sec_lkey,                             
251         Opt_sec_lkeyi,                            
252         Opt_sec_lkeyp,                            
253         Opt_sec_none,                             
254         Opt_sec_spkm,                             
255         Opt_sec_spkmi,                            
256         Opt_sec_spkmp,                            
257         Opt_sec_sys,                              
258         nr__Opt_sec                               
259 };                                                
260                                                   
261 static const struct constant_table nfs_secflav    
262         { "krb5",       Opt_sec_krb5 },           
263         { "krb5i",      Opt_sec_krb5i },          
264         { "krb5p",      Opt_sec_krb5p },          
265         { "lkey",       Opt_sec_lkey },           
266         { "lkeyi",      Opt_sec_lkeyi },          
267         { "lkeyp",      Opt_sec_lkeyp },          
268         { "none",       Opt_sec_none },           
269         { "null",       Opt_sec_none },           
270         { "spkm3",      Opt_sec_spkm },           
271         { "spkm3i",     Opt_sec_spkmi },          
272         { "spkm3p",     Opt_sec_spkmp },          
273         { "sys",        Opt_sec_sys },            
274         {}                                        
275 };                                                
276                                                   
277 enum {                                            
278         Opt_xprtsec_none,                         
279         Opt_xprtsec_tls,                          
280         Opt_xprtsec_mtls,                         
281         nr__Opt_xprtsec                           
282 };                                                
283                                                   
284 static const struct constant_table nfs_xprtsec    
285         { "none",       Opt_xprtsec_none },       
286         { "tls",        Opt_xprtsec_tls },        
287         { "mtls",       Opt_xprtsec_mtls },       
288         {}                                        
289 };                                                
290                                                   
291 /*                                                
292  * Sanity-check a server address provided by t    
293  *                                                
294  * Address family must be initialized, and add    
295  * the ANY address for that family.               
296  */                                               
297 static int nfs_verify_server_address(struct so    
298 {                                                 
299         switch (addr->ss_family) {                
300         case AF_INET: {                           
301                 struct sockaddr_in *sa = (stru    
302                 return sa->sin_addr.s_addr !=     
303         }                                         
304         case AF_INET6: {                          
305                 struct in6_addr *sa = &((struc    
306                 return !ipv6_addr_any(sa);        
307         }                                         
308         }                                         
309                                                   
310         return 0;                                 
311 }                                                 
312                                                   
313 #ifdef CONFIG_NFS_DISABLE_UDP_SUPPORT             
314 static bool nfs_server_transport_udp_invalid(c    
315 {                                                 
316         return true;                              
317 }                                                 
318 #else                                             
319 static bool nfs_server_transport_udp_invalid(c    
320 {                                                 
321         if (ctx->version == 4)                    
322                 return true;                      
323         return false;                             
324 }                                                 
325 #endif                                            
326                                                   
327 /*                                                
328  * Sanity check the NFS transport protocol.       
329  */                                               
330 static int nfs_validate_transport_protocol(str    
331                                            str    
332 {                                                 
333         switch (ctx->nfs_server.protocol) {       
334         case XPRT_TRANSPORT_UDP:                  
335                 if (nfs_server_transport_udp_i    
336                         goto out_invalid_trans    
337                 break;                            
338         case XPRT_TRANSPORT_TCP:                  
339         case XPRT_TRANSPORT_RDMA:                 
340                 break;                            
341         default:                                  
342                 ctx->nfs_server.protocol = XPR    
343         }                                         
344                                                   
345         if (ctx->xprtsec.policy != RPC_XPRTSEC    
346                 switch (ctx->nfs_server.protoc    
347                 case XPRT_TRANSPORT_TCP:          
348                         ctx->nfs_server.protoc    
349                         break;                    
350                 default:                          
351                         goto out_invalid_xprts    
352         }                                         
353                                                   
354         return 0;                                 
355 out_invalid_transport_udp:                        
356         return nfs_invalf(fc, "NFS: Unsupporte    
357 out_invalid_xprtsec_policy:                       
358         return nfs_invalf(fc, "NFS: Transport     
359 }                                                 
360                                                   
361 /*                                                
362  * For text based NFSv2/v3 mounts, the mount p    
363  * settings should depend upon the specified N    
364  */                                               
365 static void nfs_set_mount_transport_protocol(s    
366 {                                                 
367         if (ctx->mount_server.protocol == XPRT    
368             ctx->mount_server.protocol == XPRT    
369                         return;                   
370         switch (ctx->nfs_server.protocol) {       
371         case XPRT_TRANSPORT_UDP:                  
372                 ctx->mount_server.protocol = X    
373                 break;                            
374         case XPRT_TRANSPORT_TCP:                  
375         case XPRT_TRANSPORT_RDMA:                 
376                 ctx->mount_server.protocol = X    
377         }                                         
378 }                                                 
379                                                   
380 /*                                                
381  * Add 'flavor' to 'auth_info' if not already     
382  * Returns true if 'flavor' ends up in the lis    
383  */                                               
384 static int nfs_auth_info_add(struct fs_context    
385                              struct nfs_auth_i    
386                              rpc_authflavor_t     
387 {                                                 
388         unsigned int i;                           
389         unsigned int max_flavor_len = ARRAY_SI    
390                                                   
391         /* make sure this flavor isn't already    
392         for (i = 0; i < auth_info->flavor_len;    
393                 if (flavor == auth_info->flavo    
394                         return 0;                 
395         }                                         
396                                                   
397         if (auth_info->flavor_len + 1 >= max_f    
398                 return nfs_invalf(fc, "NFS: to    
399                                                   
400         auth_info->flavors[auth_info->flavor_l    
401         return 0;                                 
402 }                                                 
403                                                   
404 /*                                                
405  * Parse the value of the 'sec=' option.          
406  */                                               
407 static int nfs_parse_security_flavors(struct f    
408                                       struct f    
409 {                                                 
410         struct nfs_fs_context *ctx = nfs_fc2co    
411         rpc_authflavor_t pseudoflavor;            
412         char *string = param->string, *p;         
413         int ret;                                  
414                                                   
415         trace_nfs_mount_assign(param->key, str    
416                                                   
417         while ((p = strsep(&string, ":")) != N    
418                 if (!*p)                          
419                         continue;                 
420                 switch (lookup_constant(nfs_se    
421                 case Opt_sec_none:                
422                         pseudoflavor = RPC_AUT    
423                         break;                    
424                 case Opt_sec_sys:                 
425                         pseudoflavor = RPC_AUT    
426                         break;                    
427                 case Opt_sec_krb5:                
428                         pseudoflavor = RPC_AUT    
429                         break;                    
430                 case Opt_sec_krb5i:               
431                         pseudoflavor = RPC_AUT    
432                         break;                    
433                 case Opt_sec_krb5p:               
434                         pseudoflavor = RPC_AUT    
435                         break;                    
436                 case Opt_sec_lkey:                
437                         pseudoflavor = RPC_AUT    
438                         break;                    
439                 case Opt_sec_lkeyi:               
440                         pseudoflavor = RPC_AUT    
441                         break;                    
442                 case Opt_sec_lkeyp:               
443                         pseudoflavor = RPC_AUT    
444                         break;                    
445                 case Opt_sec_spkm:                
446                         pseudoflavor = RPC_AUT    
447                         break;                    
448                 case Opt_sec_spkmi:               
449                         pseudoflavor = RPC_AUT    
450                         break;                    
451                 case Opt_sec_spkmp:               
452                         pseudoflavor = RPC_AUT    
453                         break;                    
454                 default:                          
455                         return nfs_invalf(fc,     
456                 }                                 
457                                                   
458                 ret = nfs_auth_info_add(fc, &c    
459                 if (ret < 0)                      
460                         return ret;               
461         }                                         
462                                                   
463         return 0;                                 
464 }                                                 
465                                                   
466 static int nfs_parse_xprtsec_policy(struct fs_    
467                                     struct fs_    
468 {                                                 
469         struct nfs_fs_context *ctx = nfs_fc2co    
470                                                   
471         trace_nfs_mount_assign(param->key, par    
472                                                   
473         switch (lookup_constant(nfs_xprtsec_po    
474         case Opt_xprtsec_none:                    
475                 ctx->xprtsec.policy = RPC_XPRT    
476                 break;                            
477         case Opt_xprtsec_tls:                     
478                 ctx->xprtsec.policy = RPC_XPRT    
479                 break;                            
480         case Opt_xprtsec_mtls:                    
481                 ctx->xprtsec.policy = RPC_XPRT    
482                 break;                            
483         default:                                  
484                 return nfs_invalf(fc, "NFS: Un    
485         }                                         
486         return 0;                                 
487 }                                                 
488                                                   
489 static int nfs_parse_version_string(struct fs_    
490                                     const char    
491 {                                                 
492         struct nfs_fs_context *ctx = nfs_fc2co    
493                                                   
494         ctx->flags &= ~NFS_MOUNT_VER3;            
495         switch (lookup_constant(nfs_vers_token    
496         case Opt_vers_2:                          
497                 ctx->version = 2;                 
498                 break;                            
499         case Opt_vers_3:                          
500                 ctx->flags |= NFS_MOUNT_VER3;     
501                 ctx->version = 3;                 
502                 break;                            
503         case Opt_vers_4:                          
504                 /* Backward compatibility opti    
505                  * the mount program should al    
506                  * a NFSv4 minor version numbe    
507                  */                               
508                 ctx->version = 4;                 
509                 break;                            
510         case Opt_vers_4_0:                        
511                 ctx->version = 4;                 
512                 ctx->minorversion = 0;            
513                 break;                            
514         case Opt_vers_4_1:                        
515                 ctx->version = 4;                 
516                 ctx->minorversion = 1;            
517                 break;                            
518         case Opt_vers_4_2:                        
519                 ctx->version = 4;                 
520                 ctx->minorversion = 2;            
521                 break;                            
522         default:                                  
523                 return nfs_invalf(fc, "NFS: Un    
524         }                                         
525         return 0;                                 
526 }                                                 
527                                                   
528 /*                                                
529  * Parse a single mount parameter.                
530  */                                               
531 static int nfs_fs_context_parse_param(struct f    
532                                       struct f    
533 {                                                 
534         struct fs_parse_result result;            
535         struct nfs_fs_context *ctx = nfs_fc2co    
536         unsigned short protofamily, mountfamil    
537         unsigned int len;                         
538         int ret, opt;                             
539                                                   
540         trace_nfs_mount_option(param);            
541                                                   
542         opt = fs_parse(fc, nfs_fs_parameters,     
543         if (opt < 0)                              
544                 return (opt == -ENOPARAM && ct    
545                                                   
546         if (fc->security)                         
547                 ctx->has_sec_mnt_opts = 1;        
548                                                   
549         switch (opt) {                            
550         case Opt_source:                          
551                 if (fc->source)                   
552                         return nfs_invalf(fc,     
553                 fc->source = param->string;       
554                 param->string = NULL;             
555                 break;                            
556                                                   
557                 /*                                
558                  * boolean options:  foo/nofoo    
559                  */                               
560         case Opt_soft:                            
561                 ctx->flags |= NFS_MOUNT_SOFT;     
562                 ctx->flags &= ~NFS_MOUNT_SOFTE    
563                 break;                            
564         case Opt_softerr:                         
565                 ctx->flags |= NFS_MOUNT_SOFTER    
566                 ctx->flags &= ~NFS_MOUNT_SOFT;    
567                 break;                            
568         case Opt_hard:                            
569                 ctx->flags &= ~(NFS_MOUNT_SOFT    
570                                 NFS_MOUNT_SOFT    
571                                 NFS_MOUNT_SOFT    
572                 break;                            
573         case Opt_softreval:                       
574                 if (result.negated)               
575                         ctx->flags &= ~NFS_MOU    
576                 else                              
577                         ctx->flags |= NFS_MOUN    
578                 break;                            
579         case Opt_posix:                           
580                 if (result.negated)               
581                         ctx->flags &= ~NFS_MOU    
582                 else                              
583                         ctx->flags |= NFS_MOUN    
584                 break;                            
585         case Opt_cto:                             
586                 if (result.negated)               
587                         ctx->flags |= NFS_MOUN    
588                 else                              
589                         ctx->flags &= ~NFS_MOU    
590                 break;                            
591         case Opt_trunkdiscovery:                  
592                 if (result.negated)               
593                         ctx->flags &= ~NFS_MOU    
594                 else                              
595                         ctx->flags |= NFS_MOUN    
596                 break;                            
597         case Opt_alignwrite:                      
598                 if (result.negated)               
599                         ctx->flags |= NFS_MOUN    
600                 else                              
601                         ctx->flags &= ~NFS_MOU    
602                 break;                            
603         case Opt_ac:                              
604                 if (result.negated)               
605                         ctx->flags |= NFS_MOUN    
606                 else                              
607                         ctx->flags &= ~NFS_MOU    
608                 break;                            
609         case Opt_lock:                            
610                 if (result.negated) {             
611                         ctx->lock_status = NFS    
612                         ctx->flags |= NFS_MOUN    
613                         ctx->flags |= (NFS_MOU    
614                 } else {                          
615                         ctx->lock_status = NFS    
616                         ctx->flags &= ~NFS_MOU    
617                         ctx->flags &= ~(NFS_MO    
618                 }                                 
619                 break;                            
620         case Opt_udp:                             
621                 ctx->flags &= ~NFS_MOUNT_TCP;     
622                 ctx->nfs_server.protocol = XPR    
623                 break;                            
624         case Opt_tcp:                             
625         case Opt_rdma:                            
626                 ctx->flags |= NFS_MOUNT_TCP; /    
627                 ret = xprt_find_transport_iden    
628                 if (ret < 0)                      
629                         goto out_bad_transport    
630                 ctx->nfs_server.protocol = ret    
631                 break;                            
632         case Opt_acl:                             
633                 if (result.negated)               
634                         ctx->flags |= NFS_MOUN    
635                 else                              
636                         ctx->flags &= ~NFS_MOU    
637                 break;                            
638         case Opt_rdirplus:                        
639                 if (result.negated)               
640                         ctx->flags |= NFS_MOUN    
641                 else                              
642                         ctx->flags &= ~NFS_MOU    
643                 break;                            
644         case Opt_sharecache:                      
645                 if (result.negated)               
646                         ctx->flags |= NFS_MOUN    
647                 else                              
648                         ctx->flags &= ~NFS_MOU    
649                 break;                            
650         case Opt_resvport:                        
651                 if (result.negated)               
652                         ctx->flags |= NFS_MOUN    
653                 else                              
654                         ctx->flags &= ~NFS_MOU    
655                 break;                            
656         case Opt_fscache_flag:                    
657                 if (result.negated)               
658                         ctx->options &= ~NFS_O    
659                 else                              
660                         ctx->options |= NFS_OP    
661                 kfree(ctx->fscache_uniq);         
662                 ctx->fscache_uniq = NULL;         
663                 break;                            
664         case Opt_fscache:                         
665                 trace_nfs_mount_assign(param->    
666                 ctx->options |= NFS_OPTION_FSC    
667                 kfree(ctx->fscache_uniq);         
668                 ctx->fscache_uniq = param->str    
669                 param->string = NULL;             
670                 break;                            
671         case Opt_migration:                       
672                 if (result.negated)               
673                         ctx->options &= ~NFS_O    
674                 else                              
675                         ctx->options |= NFS_OP    
676                 break;                            
677                                                   
678                 /*                                
679                  * options that take numeric v    
680                  */                               
681         case Opt_port:                            
682                 if (result.uint_32 > USHRT_MAX    
683                         goto out_of_bounds;       
684                 ctx->nfs_server.port = result.    
685                 break;                            
686         case Opt_rsize:                           
687                 ctx->rsize = result.uint_32;      
688                 break;                            
689         case Opt_wsize:                           
690                 ctx->wsize = result.uint_32;      
691                 break;                            
692         case Opt_bsize:                           
693                 ctx->bsize = result.uint_32;      
694                 break;                            
695         case Opt_timeo:                           
696                 if (result.uint_32 < 1 || resu    
697                         goto out_of_bounds;       
698                 ctx->timeo = result.uint_32;      
699                 break;                            
700         case Opt_retrans:                         
701                 if (result.uint_32 > INT_MAX)     
702                         goto out_of_bounds;       
703                 ctx->retrans = result.uint_32;    
704                 break;                            
705         case Opt_acregmin:                        
706                 ctx->acregmin = result.uint_32    
707                 break;                            
708         case Opt_acregmax:                        
709                 ctx->acregmax = result.uint_32    
710                 break;                            
711         case Opt_acdirmin:                        
712                 ctx->acdirmin = result.uint_32    
713                 break;                            
714         case Opt_acdirmax:                        
715                 ctx->acdirmax = result.uint_32    
716                 break;                            
717         case Opt_actimeo:                         
718                 ctx->acregmin = result.uint_32    
719                 ctx->acregmax = result.uint_32    
720                 ctx->acdirmin = result.uint_32    
721                 ctx->acdirmax = result.uint_32    
722                 break;                            
723         case Opt_namelen:                         
724                 ctx->namlen = result.uint_32;     
725                 break;                            
726         case Opt_mountport:                       
727                 if (result.uint_32 > USHRT_MAX    
728                         goto out_of_bounds;       
729                 ctx->mount_server.port = resul    
730                 break;                            
731         case Opt_mountvers:                       
732                 if (result.uint_32 < NFS_MNT_V    
733                     result.uint_32 > NFS_MNT3_    
734                         goto out_of_bounds;       
735                 ctx->mount_server.version = re    
736                 break;                            
737         case Opt_minorversion:                    
738                 if (result.uint_32 > NFS4_MAX_    
739                         goto out_of_bounds;       
740                 ctx->minorversion = result.uin    
741                 break;                            
742                                                   
743                 /*                                
744                  * options that take text valu    
745                  */                               
746         case Opt_v:                               
747                 ret = nfs_parse_version_string    
748                 if (ret < 0)                      
749                         return ret;               
750                 break;                            
751         case Opt_vers:                            
752                 if (!param->string)               
753                         goto out_invalid_value    
754                 trace_nfs_mount_assign(param->    
755                 ret = nfs_parse_version_string    
756                 if (ret < 0)                      
757                         return ret;               
758                 break;                            
759         case Opt_sec:                             
760                 ret = nfs_parse_security_flavo    
761                 if (ret < 0)                      
762                         return ret;               
763                 break;                            
764         case Opt_xprtsec:                         
765                 ret = nfs_parse_xprtsec_policy    
766                 if (ret < 0)                      
767                         return ret;               
768                 break;                            
769                                                   
770         case Opt_proto:                           
771                 if (!param->string)               
772                         goto out_invalid_value    
773                 trace_nfs_mount_assign(param->    
774                 protofamily = AF_INET;            
775                 switch (lookup_constant(nfs_xp    
776                 case Opt_xprt_udp6:               
777                         protofamily = AF_INET6    
778                         fallthrough;              
779                 case Opt_xprt_udp:                
780                         ctx->flags &= ~NFS_MOU    
781                         ctx->nfs_server.protoc    
782                         break;                    
783                 case Opt_xprt_tcp6:               
784                         protofamily = AF_INET6    
785                         fallthrough;              
786                 case Opt_xprt_tcp:                
787                         ctx->flags |= NFS_MOUN    
788                         ctx->nfs_server.protoc    
789                         break;                    
790                 case Opt_xprt_rdma6:              
791                         protofamily = AF_INET6    
792                         fallthrough;              
793                 case Opt_xprt_rdma:               
794                         /* vector side protoco    
795                         ctx->flags |= NFS_MOUN    
796                         ret = xprt_find_transp    
797                         if (ret < 0)              
798                                 goto out_bad_t    
799                         ctx->nfs_server.protoc    
800                         break;                    
801                 default:                          
802                         goto out_bad_transport    
803                 }                                 
804                                                   
805                 ctx->protofamily = protofamily    
806                 break;                            
807                                                   
808         case Opt_mountproto:                      
809                 if (!param->string)               
810                         goto out_invalid_value    
811                 trace_nfs_mount_assign(param->    
812                 mountfamily = AF_INET;            
813                 switch (lookup_constant(nfs_xp    
814                 case Opt_xprt_udp6:               
815                         mountfamily = AF_INET6    
816                         fallthrough;              
817                 case Opt_xprt_udp:                
818                         ctx->mount_server.prot    
819                         break;                    
820                 case Opt_xprt_tcp6:               
821                         mountfamily = AF_INET6    
822                         fallthrough;              
823                 case Opt_xprt_tcp:                
824                         ctx->mount_server.prot    
825                         break;                    
826                 case Opt_xprt_rdma: /* not use    
827                 default:                          
828                         goto out_bad_transport    
829                 }                                 
830                 ctx->mountfamily = mountfamily    
831                 break;                            
832                                                   
833         case Opt_addr:                            
834                 trace_nfs_mount_assign(param->    
835                 len = rpc_pton(fc->net_ns, par    
836                                &ctx->nfs_serve    
837                                sizeof(ctx->nfs    
838                 if (len == 0)                     
839                         goto out_invalid_addre    
840                 ctx->nfs_server.addrlen = len;    
841                 break;                            
842         case Opt_clientaddr:                      
843                 trace_nfs_mount_assign(param->    
844                 kfree(ctx->client_address);       
845                 ctx->client_address = param->s    
846                 param->string = NULL;             
847                 break;                            
848         case Opt_mounthost:                       
849                 trace_nfs_mount_assign(param->    
850                 kfree(ctx->mount_server.hostna    
851                 ctx->mount_server.hostname = p    
852                 param->string = NULL;             
853                 break;                            
854         case Opt_mountaddr:                       
855                 trace_nfs_mount_assign(param->    
856                 len = rpc_pton(fc->net_ns, par    
857                                &ctx->mount_ser    
858                                sizeof(ctx->mou    
859                 if (len == 0)                     
860                         goto out_invalid_addre    
861                 ctx->mount_server.addrlen = le    
862                 break;                            
863         case Opt_nconnect:                        
864                 trace_nfs_mount_assign(param->    
865                 if (result.uint_32 < 1 || resu    
866                         goto out_of_bounds;       
867                 ctx->nfs_server.nconnect = res    
868                 break;                            
869         case Opt_max_connect:                     
870                 trace_nfs_mount_assign(param->    
871                 if (result.uint_32 < 1 || resu    
872                         goto out_of_bounds;       
873                 ctx->nfs_server.max_connect =     
874                 break;                            
875         case Opt_lookupcache:                     
876                 trace_nfs_mount_assign(param->    
877                 switch (result.uint_32) {         
878                 case Opt_lookupcache_all:         
879                         ctx->flags &= ~(NFS_MO    
880                         break;                    
881                 case Opt_lookupcache_positive:    
882                         ctx->flags &= ~NFS_MOU    
883                         ctx->flags |= NFS_MOUN    
884                         break;                    
885                 case Opt_lookupcache_none:        
886                         ctx->flags |= NFS_MOUN    
887                         break;                    
888                 default:                          
889                         goto out_invalid_value    
890                 }                                 
891                 break;                            
892         case Opt_local_lock:                      
893                 trace_nfs_mount_assign(param->    
894                 switch (result.uint_32) {         
895                 case Opt_local_lock_all:          
896                         ctx->flags |= (NFS_MOU    
897                                        NFS_MOU    
898                         break;                    
899                 case Opt_local_lock_flock:        
900                         ctx->flags |= NFS_MOUN    
901                         break;                    
902                 case Opt_local_lock_posix:        
903                         ctx->flags |= NFS_MOUN    
904                         break;                    
905                 case Opt_local_lock_none:         
906                         ctx->flags &= ~(NFS_MO    
907                                         NFS_MO    
908                         break;                    
909                 default:                          
910                         goto out_invalid_value    
911                 }                                 
912                 break;                            
913         case Opt_write:                           
914                 trace_nfs_mount_assign(param->    
915                 switch (result.uint_32) {         
916                 case Opt_write_lazy:              
917                         ctx->flags &=             
918                                 ~(NFS_MOUNT_WR    
919                         break;                    
920                 case Opt_write_eager:             
921                         ctx->flags |= NFS_MOUN    
922                         ctx->flags &= ~NFS_MOU    
923                         break;                    
924                 case Opt_write_wait:              
925                         ctx->flags |=             
926                                 NFS_MOUNT_WRIT    
927                         break;                    
928                 default:                          
929                         goto out_invalid_value    
930                 }                                 
931                 break;                            
932                                                   
933                 /*                                
934                  * Special options                
935                  */                               
936         case Opt_sloppy:                          
937                 ctx->sloppy = true;               
938                 break;                            
939         }                                         
940                                                   
941         return 0;                                 
942                                                   
943 out_invalid_value:                                
944         return nfs_invalf(fc, "NFS: Bad mount     
945 out_invalid_address:                              
946         return nfs_invalf(fc, "NFS: Bad IP add    
947 out_of_bounds:                                    
948         return nfs_invalf(fc, "NFS: Value for     
949 out_bad_transport:                                
950         return nfs_invalf(fc, "NFS: Unrecogniz    
951 }                                                 
952                                                   
953 /*                                                
954  * Split fc->source into "hostname:export_path    
955  *                                                
956  * The leftmost colon demarks the split betwee    
957  * and the export path.  If the hostname start    
958  * bracket, then it may contain colons.           
959  *                                                
960  * Note: caller frees hostname and export path    
961  */                                               
962 static int nfs_parse_source(struct fs_context     
963                             size_t maxnamlen,     
964 {                                                 
965         struct nfs_fs_context *ctx = nfs_fc2co    
966         const char *dev_name = fc->source;        
967         size_t len;                               
968         const char *end;                          
969                                                   
970         if (unlikely(!dev_name || !*dev_name))    
971                 return -EINVAL;                   
972                                                   
973         /* Is the host name protected with squ    
974         if (*dev_name == '[') {                   
975                 end = strchr(++dev_name, ']');    
976                 if (end == NULL || end[1] != '    
977                         goto out_bad_devname;     
978                                                   
979                 len = end - dev_name;             
980                 end++;                            
981         } else {                                  
982                 const char *comma;                
983                                                   
984                 end = strchr(dev_name, ':');      
985                 if (end == NULL)                  
986                         goto out_bad_devname;     
987                 len = end - dev_name;             
988                                                   
989                 /* kill possible hostname list    
990                 comma = memchr(dev_name, ',',     
991                 if (comma)                        
992                         len = comma - dev_name    
993         }                                         
994                                                   
995         if (len > maxnamlen)                      
996                 goto out_hostname;                
997                                                   
998         kfree(ctx->nfs_server.hostname);          
999                                                   
1000         /* N.B. caller will free nfs_server.h    
1001         ctx->nfs_server.hostname = kmemdup_nu    
1002         if (!ctx->nfs_server.hostname)           
1003                 goto out_nomem;                  
1004         len = strlen(++end);                     
1005         if (len > maxpathlen)                    
1006                 goto out_path;                   
1007         ctx->nfs_server.export_path = kmemdup    
1008         if (!ctx->nfs_server.export_path)        
1009                 goto out_nomem;                  
1010                                                  
1011         trace_nfs_mount_path(ctx->nfs_server.    
1012         return 0;                                
1013                                                  
1014 out_bad_devname:                                 
1015         return nfs_invalf(fc, "NFS: device na    
1016 out_nomem:                                       
1017         nfs_errorf(fc, "NFS: not enough memor    
1018         return -ENOMEM;                          
1019 out_hostname:                                    
1020         nfs_errorf(fc, "NFS: server hostname     
1021         return -ENAMETOOLONG;                    
1022 out_path:                                        
1023         nfs_errorf(fc, "NFS: export pathname     
1024         return -ENAMETOOLONG;                    
1025 }                                                
1026                                                  
1027 static inline bool is_remount_fc(struct fs_co    
1028 {                                                
1029         return fc->root != NULL;                 
1030 }                                                
1031                                                  
1032 /*                                               
1033  * Parse monolithic NFS2/NFS3 mount data         
1034  * - fills in the mount root filehandle          
1035  *                                               
1036  * For option strings, user space handles the    
1037  *                                               
1038  * + DNS: mapping server host name to IP addr    
1039  *                                               
1040  * + failure mode: how to behave if a mount r    
1041  *   immediately ("fg/bg" option)                
1042  *                                               
1043  * + retry: how often to retry a mount reques    
1044  *                                               
1045  * + breaking back: trying proto=udp after pr    
1046  *   mountproto=tcp after mountproto=udp, and    
1047  */                                              
1048 static int nfs23_parse_monolithic(struct fs_c    
1049                                   struct nfs_    
1050 {                                                
1051         struct nfs_fs_context *ctx = nfs_fc2c    
1052         struct nfs_fh *mntfh = ctx->mntfh;       
1053         struct sockaddr_storage *sap = &ctx->    
1054         int extra_flags = NFS_MOUNT_LEGACY_IN    
1055         int ret;                                 
1056                                                  
1057         if (data == NULL)                        
1058                 goto out_no_data;                
1059                                                  
1060         ctx->version = NFS_DEFAULT_VERSION;      
1061         switch (data->version) {                 
1062         case 1:                                  
1063                 data->namlen = 0;                
1064                 fallthrough;                     
1065         case 2:                                  
1066                 data->bsize = 0;                 
1067                 fallthrough;                     
1068         case 3:                                  
1069                 if (data->flags & NFS_MOUNT_V    
1070                         goto out_no_v3;          
1071                 data->root.size = NFS2_FHSIZE    
1072                 memcpy(data->root.data, data-    
1073                 /* Turn off security negotiat    
1074                 extra_flags |= NFS_MOUNT_SECF    
1075                 fallthrough;                     
1076         case 4:                                  
1077                 if (data->flags & NFS_MOUNT_S    
1078                         goto out_no_sec;         
1079                 fallthrough;                     
1080         case 5:                                  
1081                 memset(data->context, 0, size    
1082                 fallthrough;                     
1083         case 6:                                  
1084                 if (data->flags & NFS_MOUNT_V    
1085                         if (data->root.size >    
1086                                 goto out_inva    
1087                         mntfh->size = data->r    
1088                         ctx->version = 3;        
1089                 } else {                         
1090                         mntfh->size = NFS2_FH    
1091                         ctx->version = 2;        
1092                 }                                
1093                                                  
1094                                                  
1095                 memcpy(mntfh->data, data->roo    
1096                 if (mntfh->size < sizeof(mntf    
1097                         memset(mntfh->data +     
1098                                sizeof(mntfh->    
1099                                                  
1100                 /*                               
1101                  * for proto == XPRT_TRANSPOR    
1102                  * to_exponential, implying s    
1103                  * to BITS_PER_LONG (majortim    
1104                  */                              
1105                 if (!(data->flags & NFS_MOUNT    
1106                         if (data->retrans >=     
1107                                 goto out_inva    
1108                                                  
1109                 /*                               
1110                  * Translate to nfs_fs_contex    
1111                  * can deal with.                
1112                  */                              
1113                 ctx->flags      = data->flags    
1114                 ctx->flags      |= extra_flag    
1115                 ctx->rsize      = data->rsize    
1116                 ctx->wsize      = data->wsize    
1117                 ctx->timeo      = data->timeo    
1118                 ctx->retrans    = data->retra    
1119                 ctx->acregmin   = data->acreg    
1120                 ctx->acregmax   = data->acreg    
1121                 ctx->acdirmin   = data->acdir    
1122                 ctx->acdirmax   = data->acdir    
1123                 ctx->need_mount = false;         
1124                                                  
1125                 if (!is_remount_fc(fc)) {        
1126                         memcpy(sap, &data->ad    
1127                         ctx->nfs_server.addrl    
1128                         ctx->nfs_server.port     
1129                 }                                
1130                                                  
1131                 if (sap->ss_family != AF_INET    
1132                     !nfs_verify_server_addres    
1133                         goto out_no_address;     
1134                                                  
1135                 if (!(data->flags & NFS_MOUNT    
1136                         ctx->nfs_server.proto    
1137                 /* N.B. caller will free nfs_    
1138                 ctx->nfs_server.hostname = ks    
1139                 if (!ctx->nfs_server.hostname    
1140                         goto out_nomem;          
1141                                                  
1142                 ctx->namlen             = dat    
1143                 ctx->bsize              = dat    
1144                                                  
1145                 if (data->flags & NFS_MOUNT_S    
1146                         ctx->selected_flavor     
1147                 else                             
1148                         ctx->selected_flavor     
1149                                                  
1150                 if (!(data->flags & NFS_MOUNT    
1151                         ctx->flags &= ~(NFS_M    
1152                                          NFS_    
1153                 else                             
1154                         ctx->flags |= (NFS_MO    
1155                                         NFS_M    
1156                                                  
1157                 /*                               
1158                  * The legacy version 6 binar    
1159                  * field used only to transpo    
1160                  * kernel.  To continue to su    
1161                  * have a touch of selinux kn    
1162                  * userspace code converted c    
1163                  * converting back to the ful    
1164                  */                              
1165                 if (data->context[0]){           
1166 #ifdef CONFIG_SECURITY_SELINUX                   
1167                         int ret;                 
1168                                                  
1169                         data->context[NFS_MAX    
1170                         ret = vfs_parse_fs_st    
1171                                                  
1172                         if (ret < 0)             
1173                                 return ret;      
1174 #else                                            
1175                         return -EINVAL;          
1176 #endif                                           
1177                 }                                
1178                                                  
1179                 break;                           
1180         default:                                 
1181                 goto generic;                    
1182         }                                        
1183                                                  
1184         ret = nfs_validate_transport_protocol    
1185         if (ret)                                 
1186                 return ret;                      
1187                                                  
1188         ctx->skip_reconfig_option_check = tru    
1189         return 0;                                
1190                                                  
1191 generic:                                         
1192         return generic_parse_monolithic(fc, d    
1193                                                  
1194 out_no_data:                                     
1195         if (is_remount_fc(fc)) {                 
1196                 ctx->skip_reconfig_option_che    
1197                 return 0;                        
1198         }                                        
1199         return nfs_invalf(fc, "NFS: mount pro    
1200                                                  
1201 out_no_v3:                                       
1202         return nfs_invalf(fc, "NFS: nfs_mount    
1203                                                  
1204 out_no_sec:                                      
1205         return nfs_invalf(fc, "NFS: nfs_mount    
1206                                                  
1207 out_nomem:                                       
1208         return -ENOMEM;                          
1209                                                  
1210 out_no_address:                                  
1211         return nfs_invalf(fc, "NFS: mount pro    
1212                                                  
1213 out_invalid_fh:                                  
1214         return nfs_invalf(fc, "NFS: invalid r    
1215                                                  
1216 out_invalid_data:                                
1217         return nfs_invalf(fc, "NFS: invalid b    
1218 }                                                
1219                                                  
1220 #if IS_ENABLED(CONFIG_NFS_V4)                    
1221 struct compat_nfs_string {                       
1222         compat_uint_t len;                       
1223         compat_uptr_t data;                      
1224 };                                               
1225                                                  
1226 static inline void compat_nfs_string(struct n    
1227                                      struct c    
1228 {                                                
1229         dst->data = compat_ptr(src->data);       
1230         dst->len = src->len;                     
1231 }                                                
1232                                                  
1233 struct compat_nfs4_mount_data_v1 {               
1234         compat_int_t version;                    
1235         compat_int_t flags;                      
1236         compat_int_t rsize;                      
1237         compat_int_t wsize;                      
1238         compat_int_t timeo;                      
1239         compat_int_t retrans;                    
1240         compat_int_t acregmin;                   
1241         compat_int_t acregmax;                   
1242         compat_int_t acdirmin;                   
1243         compat_int_t acdirmax;                   
1244         struct compat_nfs_string client_addr;    
1245         struct compat_nfs_string mnt_path;       
1246         struct compat_nfs_string hostname;       
1247         compat_uint_t host_addrlen;              
1248         compat_uptr_t host_addr;                 
1249         compat_int_t proto;                      
1250         compat_int_t auth_flavourlen;            
1251         compat_uptr_t auth_flavours;             
1252 };                                               
1253                                                  
1254 static void nfs4_compat_mount_data_conv(struc    
1255 {                                                
1256         struct compat_nfs4_mount_data_v1 *com    
1257                         (struct compat_nfs4_m    
1258                                                  
1259         /* copy the fields backwards */          
1260         data->auth_flavours = compat_ptr(comp    
1261         data->auth_flavourlen = compat->auth_    
1262         data->proto = compat->proto;             
1263         data->host_addr = compat_ptr(compat->    
1264         data->host_addrlen = compat->host_add    
1265         compat_nfs_string(&data->hostname, &c    
1266         compat_nfs_string(&data->mnt_path, &c    
1267         compat_nfs_string(&data->client_addr,    
1268         data->acdirmax = compat->acdirmax;       
1269         data->acdirmin = compat->acdirmin;       
1270         data->acregmax = compat->acregmax;       
1271         data->acregmin = compat->acregmin;       
1272         data->retrans = compat->retrans;         
1273         data->timeo = compat->timeo;             
1274         data->wsize = compat->wsize;             
1275         data->rsize = compat->rsize;             
1276         data->flags = compat->flags;             
1277         data->version = compat->version;         
1278 }                                                
1279                                                  
1280 /*                                               
1281  * Validate NFSv4 mount options                  
1282  */                                              
1283 static int nfs4_parse_monolithic(struct fs_co    
1284                                  struct nfs4_    
1285 {                                                
1286         struct nfs_fs_context *ctx = nfs_fc2c    
1287         struct sockaddr_storage *sap = &ctx->    
1288         int ret;                                 
1289         char *c;                                 
1290                                                  
1291         if (!data) {                             
1292                 if (is_remount_fc(fc))           
1293                         goto done;               
1294                 return nfs_invalf(fc,            
1295                         "NFS4: mount program     
1296         }                                        
1297                                                  
1298         ctx->version = 4;                        
1299                                                  
1300         if (data->version != 1)                  
1301                 return generic_parse_monolith    
1302                                                  
1303         if (in_compat_syscall())                 
1304                 nfs4_compat_mount_data_conv(d    
1305                                                  
1306         if (data->host_addrlen > sizeof(ctx->    
1307                 goto out_no_address;             
1308         if (data->host_addrlen == 0)             
1309                 goto out_no_address;             
1310         ctx->nfs_server.addrlen = data->host_    
1311         if (copy_from_user(sap, data->host_ad    
1312                 return -EFAULT;                  
1313         if (!nfs_verify_server_address(sap))     
1314                 goto out_no_address;             
1315         ctx->nfs_server.port = ntohs(((struct    
1316                                                  
1317         if (data->auth_flavourlen) {             
1318                 rpc_authflavor_t pseudoflavor    
1319                                                  
1320                 if (data->auth_flavourlen > 1    
1321                         goto out_inval_auth;     
1322                 if (copy_from_user(&pseudofla    
1323                                    sizeof(pse    
1324                         return -EFAULT;          
1325                 ctx->selected_flavor = pseudo    
1326         } else {                                 
1327                 ctx->selected_flavor = RPC_AU    
1328         }                                        
1329                                                  
1330         c = strndup_user(data->hostname.data,    
1331         if (IS_ERR(c))                           
1332                 return PTR_ERR(c);               
1333         ctx->nfs_server.hostname = c;            
1334                                                  
1335         c = strndup_user(data->mnt_path.data,    
1336         if (IS_ERR(c))                           
1337                 return PTR_ERR(c);               
1338         ctx->nfs_server.export_path = c;         
1339         trace_nfs_mount_path(c);                 
1340                                                  
1341         c = strndup_user(data->client_addr.da    
1342         if (IS_ERR(c))                           
1343                 return PTR_ERR(c);               
1344         ctx->client_address = c;                 
1345                                                  
1346         /*                                       
1347          * Translate to nfs_fs_context, which    
1348          * can deal with.                        
1349          */                                      
1350                                                  
1351         ctx->flags      = data->flags & NFS4_    
1352         ctx->rsize      = data->rsize;           
1353         ctx->wsize      = data->wsize;           
1354         ctx->timeo      = data->timeo;           
1355         ctx->retrans    = data->retrans;         
1356         ctx->acregmin   = data->acregmin;        
1357         ctx->acregmax   = data->acregmax;        
1358         ctx->acdirmin   = data->acdirmin;        
1359         ctx->acdirmax   = data->acdirmax;        
1360         ctx->nfs_server.protocol = data->prot    
1361         ret = nfs_validate_transport_protocol    
1362         if (ret)                                 
1363                 return ret;                      
1364 done:                                            
1365         ctx->skip_reconfig_option_check = tru    
1366         return 0;                                
1367                                                  
1368 out_inval_auth:                                  
1369         return nfs_invalf(fc, "NFS4: Invalid     
1370                       data->auth_flavourlen);    
1371                                                  
1372 out_no_address:                                  
1373         return nfs_invalf(fc, "NFS4: mount pr    
1374 }                                                
1375 #endif                                           
1376                                                  
1377 /*                                               
1378  * Parse a monolithic block of data from sys_    
1379  */                                              
1380 static int nfs_fs_context_parse_monolithic(st    
1381                                            vo    
1382 {                                                
1383         if (fc->fs_type == &nfs_fs_type)         
1384                 return nfs23_parse_monolithic    
1385                                                  
1386 #if IS_ENABLED(CONFIG_NFS_V4)                    
1387         if (fc->fs_type == &nfs4_fs_type)        
1388                 return nfs4_parse_monolithic(    
1389 #endif                                           
1390                                                  
1391         return nfs_invalf(fc, "NFS: Unsupport    
1392 }                                                
1393                                                  
1394 /*                                               
1395  * Validate the preparsed information in the     
1396  */                                              
1397 static int nfs_fs_context_validate(struct fs_    
1398 {                                                
1399         struct nfs_fs_context *ctx = nfs_fc2c    
1400         struct nfs_subversion *nfs_mod;          
1401         struct sockaddr_storage *sap = &ctx->    
1402         int max_namelen = PAGE_SIZE;             
1403         int max_pathlen = NFS_MAXPATHLEN;        
1404         int port = 0;                            
1405         int ret;                                 
1406                                                  
1407         if (!fc->source)                         
1408                 goto out_no_device_name;         
1409                                                  
1410         /* Check for sanity first. */            
1411         if (ctx->minorversion && ctx->version    
1412                 goto out_minorversion_mismatc    
1413                                                  
1414         if (ctx->options & NFS_OPTION_MIGRATI    
1415             (ctx->version != 4 || ctx->minorv    
1416                 goto out_migration_misuse;       
1417                                                  
1418         /* Verify that any proto=/mountproto=    
1419          * families in the addr=/mountaddr= o    
1420          */                                      
1421         if (ctx->protofamily != AF_UNSPEC &&     
1422             ctx->protofamily != ctx->nfs_serv    
1423                 goto out_proto_mismatch;         
1424                                                  
1425         if (ctx->mountfamily != AF_UNSPEC) {     
1426                 if (ctx->mount_server.addrlen    
1427                         if (ctx->mountfamily     
1428                                 goto out_moun    
1429                 } else {                         
1430                         if (ctx->mountfamily     
1431                                 goto out_moun    
1432                 }                                
1433         }                                        
1434                                                  
1435         if (!nfs_verify_server_address(sap))     
1436                 goto out_no_address;             
1437                                                  
1438         ret = nfs_validate_transport_protocol    
1439         if (ret)                                 
1440                 return ret;                      
1441                                                  
1442         if (ctx->version == 4) {                 
1443                 if (IS_ENABLED(CONFIG_NFS_V4)    
1444                         if (ctx->nfs_server.p    
1445                                 port = NFS_RD    
1446                         else                     
1447                                 port = NFS_PO    
1448                         max_namelen = NFS4_MA    
1449                         max_pathlen = NFS4_MA    
1450                         ctx->flags &= ~(NFS_M    
1451                                         NFS_M    
1452                                         NFS_M    
1453                 } else {                         
1454                         goto out_v4_not_compi    
1455                 }                                
1456         } else {                                 
1457                 nfs_set_mount_transport_proto    
1458                 if (ctx->nfs_server.protocol     
1459                         port = NFS_RDMA_PORT;    
1460         }                                        
1461                                                  
1462         nfs_set_port(sap, &ctx->nfs_server.po    
1463                                                  
1464         ret = nfs_parse_source(fc, max_namele    
1465         if (ret < 0)                             
1466                 return ret;                      
1467                                                  
1468         /* Load the NFS protocol module if we    
1469         if (!ctx->nfs_mod) {                     
1470                 nfs_mod = get_nfs_version(ctx    
1471                 if (IS_ERR(nfs_mod)) {           
1472                         ret = PTR_ERR(nfs_mod    
1473                         goto out_version_unav    
1474                 }                                
1475                 ctx->nfs_mod = nfs_mod;          
1476         }                                        
1477                                                  
1478         /* Ensure the filesystem context has     
1479         if (fc->fs_type != ctx->nfs_mod->nfs_    
1480                 module_put(fc->fs_type->owner    
1481                 __module_get(ctx->nfs_mod->nf    
1482                 fc->fs_type = ctx->nfs_mod->n    
1483         }                                        
1484         return 0;                                
1485                                                  
1486 out_no_device_name:                              
1487         return nfs_invalf(fc, "NFS: Device na    
1488 out_v4_not_compiled:                             
1489         nfs_errorf(fc, "NFS: NFSv4 is not com    
1490         return -EPROTONOSUPPORT;                 
1491 out_no_address:                                  
1492         return nfs_invalf(fc, "NFS: mount pro    
1493 out_mountproto_mismatch:                         
1494         return nfs_invalf(fc, "NFS: Mount ser    
1495 out_proto_mismatch:                              
1496         return nfs_invalf(fc, "NFS: Server ad    
1497 out_minorversion_mismatch:                       
1498         return nfs_invalf(fc, "NFS: Mount opt    
1499                           ctx->version, ctx->    
1500 out_migration_misuse:                            
1501         return nfs_invalf(fc, "NFS: 'Migratio    
1502 out_version_unavailable:                         
1503         nfs_errorf(fc, "NFS: Version unavaila    
1504         return ret;                              
1505 }                                                
1506                                                  
1507 /*                                               
1508  * Create an NFS superblock by the appropriat    
1509  */                                              
1510 static int nfs_get_tree(struct fs_context *fc    
1511 {                                                
1512         struct nfs_fs_context *ctx = nfs_fc2c    
1513         int err = nfs_fs_context_validate(fc)    
1514                                                  
1515         if (err)                                 
1516                 return err;                      
1517         if (!ctx->internal)                      
1518                 return ctx->nfs_mod->rpc_ops-    
1519         else                                     
1520                 return nfs_get_tree_common(fc    
1521 }                                                
1522                                                  
1523 /*                                               
1524  * Handle duplication of a configuration.  Th    
1525  * it can't deal with resource pointers in th    
1526  * to do that.  We need to clear pointers, co    
1527  * appropriate.                                  
1528  */                                              
1529 static int nfs_fs_context_dup(struct fs_conte    
1530 {                                                
1531         struct nfs_fs_context *src = nfs_fc2c    
1532                                                  
1533         ctx = kmemdup(src, sizeof(struct nfs_    
1534         if (!ctx)                                
1535                 return -ENOMEM;                  
1536                                                  
1537         ctx->mntfh = nfs_alloc_fhandle();        
1538         if (!ctx->mntfh) {                       
1539                 kfree(ctx);                      
1540                 return -ENOMEM;                  
1541         }                                        
1542         nfs_copy_fh(ctx->mntfh, src->mntfh);     
1543                                                  
1544         __module_get(ctx->nfs_mod->owner);       
1545         ctx->client_address             = NUL    
1546         ctx->mount_server.hostname      = NUL    
1547         ctx->nfs_server.export_path     = NUL    
1548         ctx->nfs_server.hostname        = NUL    
1549         ctx->fscache_uniq               = NUL    
1550         ctx->clone_data.fattr           = NUL    
1551         fc->fs_private = ctx;                    
1552         return 0;                                
1553 }                                                
1554                                                  
1555 static void nfs_fs_context_free(struct fs_con    
1556 {                                                
1557         struct nfs_fs_context *ctx = nfs_fc2c    
1558                                                  
1559         if (ctx) {                               
1560                 if (ctx->server)                 
1561                         nfs_free_server(ctx->    
1562                 if (ctx->nfs_mod)                
1563                         put_nfs_version(ctx->    
1564                 kfree(ctx->client_address);      
1565                 kfree(ctx->mount_server.hostn    
1566                 kfree(ctx->nfs_server.export_    
1567                 kfree(ctx->nfs_server.hostnam    
1568                 kfree(ctx->fscache_uniq);        
1569                 nfs_free_fhandle(ctx->mntfh);    
1570                 nfs_free_fattr(ctx->clone_dat    
1571                 kfree(ctx);                      
1572         }                                        
1573 }                                                
1574                                                  
1575 static const struct fs_context_operations nfs    
1576         .free                   = nfs_fs_cont    
1577         .dup                    = nfs_fs_cont    
1578         .parse_param            = nfs_fs_cont    
1579         .parse_monolithic       = nfs_fs_cont    
1580         .get_tree               = nfs_get_tre    
1581         .reconfigure            = nfs_reconfi    
1582 };                                               
1583                                                  
1584 /*                                               
1585  * Prepare superblock configuration.  We use     
1586  * context.  This may be the current process'    
1587  * container's namespaces.                       
1588  */                                              
1589 static int nfs_init_fs_context(struct fs_cont    
1590 {                                                
1591         struct nfs_fs_context *ctx;              
1592                                                  
1593         ctx = kzalloc(sizeof(struct nfs_fs_co    
1594         if (unlikely(!ctx))                      
1595                 return -ENOMEM;                  
1596                                                  
1597         ctx->mntfh = nfs_alloc_fhandle();        
1598         if (unlikely(!ctx->mntfh)) {             
1599                 kfree(ctx);                      
1600                 return -ENOMEM;                  
1601         }                                        
1602                                                  
1603         ctx->protofamily        = AF_UNSPEC;     
1604         ctx->mountfamily        = AF_UNSPEC;     
1605         ctx->mount_server.port  = NFS_UNSPEC_    
1606                                                  
1607         if (fc->root) {                          
1608                 /* reconfigure, start with th    
1609                 struct nfs_server *nfss = fc-    
1610                 struct net *net = nfss->nfs_c    
1611                                                  
1612                 ctx->flags              = nfs    
1613                 ctx->rsize              = nfs    
1614                 ctx->wsize              = nfs    
1615                 ctx->retrans            = nfs    
1616                 ctx->selected_flavor    = nfs    
1617                 ctx->acregmin           = nfs    
1618                 ctx->acregmax           = nfs    
1619                 ctx->acdirmin           = nfs    
1620                 ctx->acdirmax           = nfs    
1621                 ctx->timeo              = 10U    
1622                 ctx->nfs_server.port    = nfs    
1623                 ctx->nfs_server.addrlen = nfs    
1624                 ctx->version            = nfs    
1625                 ctx->minorversion       = nfs    
1626                                                  
1627                 memcpy(&ctx->nfs_server._addr    
1628                         ctx->nfs_server.addrl    
1629                                                  
1630                 if (fc->net_ns != net) {         
1631                         put_net(fc->net_ns);     
1632                         fc->net_ns = get_net(    
1633                 }                                
1634                                                  
1635                 ctx->nfs_mod = nfss->nfs_clie    
1636                 __module_get(ctx->nfs_mod->ow    
1637         } else {                                 
1638                 /* defaults */                   
1639                 ctx->timeo              = NFS    
1640                 ctx->retrans            = NFS    
1641                 ctx->acregmin           = NFS    
1642                 ctx->acregmax           = NFS    
1643                 ctx->acdirmin           = NFS    
1644                 ctx->acdirmax           = NFS    
1645                 ctx->nfs_server.port    = NFS    
1646                 ctx->nfs_server.protocol = XP    
1647                 ctx->selected_flavor    = RPC    
1648                 ctx->minorversion       = 0;     
1649                 ctx->need_mount         = tru    
1650                 ctx->xprtsec.policy     = RPC    
1651                 ctx->xprtsec.cert_serial         
1652                 ctx->xprtsec.privkey_serial      
1653                                                  
1654                 fc->s_iflags            |= SB    
1655         }                                        
1656         fc->fs_private = ctx;                    
1657         fc->ops = &nfs_fs_context_ops;           
1658         return 0;                                
1659 }                                                
1660                                                  
1661 struct file_system_type nfs_fs_type = {          
1662         .owner                  = THIS_MODULE    
1663         .name                   = "nfs",         
1664         .init_fs_context        = nfs_init_fs    
1665         .parameters             = nfs_fs_para    
1666         .kill_sb                = nfs_kill_su    
1667         .fs_flags               = FS_RENAME_D    
1668 };                                               
1669 MODULE_ALIAS_FS("nfs");                          
1670 EXPORT_SYMBOL_GPL(nfs_fs_type);                  
1671                                                  
1672 #if IS_ENABLED(CONFIG_NFS_V4)                    
1673 struct file_system_type nfs4_fs_type = {         
1674         .owner                  = THIS_MODULE    
1675         .name                   = "nfs4",        
1676         .init_fs_context        = nfs_init_fs    
1677         .parameters             = nfs_fs_para    
1678         .kill_sb                = nfs_kill_su    
1679         .fs_flags               = FS_RENAME_D    
1680 };                                               
1681 MODULE_ALIAS_FS("nfs4");                         
1682 MODULE_ALIAS("nfs4");                            
1683 EXPORT_SYMBOL_GPL(nfs4_fs_type);                 
1684 #endif /* CONFIG_NFS_V4 */                       
1685                                                  

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php