@@ -1051,10 +1051,28 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
10511051/*
10521052 * Validate the NFS2/NFS3 mount data
10531053 * - fills in the mount root filehandle
1054+ *
1055+ * For option strings, user space handles the following behaviors:
1056+ *
1057+ * + DNS: mapping server host name to IP address ("addr=" option)
1058+ *
1059+ * + failure mode: how to behave if a mount request can't be handled
1060+ * immediately ("fg/bg" option)
1061+ *
1062+ * + retry: how often to retry a mount request ("retry=" option)
1063+ *
1064+ * + breaking back: trying proto=udp after proto=tcp, v2 after v3,
1065+ * mountproto=tcp after mountproto=udp, and so on
1066+ *
1067+ * XXX: as far as I can tell, changing the NFS program number is not
1068+ * supported in the NFS client.
10541069 */
1055- static int nfs_validate_mount_data (struct nfs_mount_data * data ,
1056- struct nfs_fh * mntfh )
1070+ static int nfs_validate_mount_data (struct nfs_mount_data * * options ,
1071+ struct nfs_fh * mntfh ,
1072+ const char * dev_name )
10571073{
1074+ struct nfs_mount_data * data = * options ;
1075+
10581076 if (data == NULL )
10591077 goto out_no_data ;
10601078
@@ -1087,8 +1105,78 @@ static int nfs_validate_mount_data(struct nfs_mount_data *data,
10871105 memset (mntfh -> data + mntfh -> size , 0 ,
10881106 sizeof (mntfh -> data ) - mntfh -> size );
10891107 break ;
1090- default :
1091- goto out_bad_version ;
1108+ default : {
1109+ unsigned int len ;
1110+ char * c ;
1111+ int status ;
1112+ struct nfs_parsed_mount_data args = {
1113+ .flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP ),
1114+ .rsize = NFS_MAX_FILE_IO_SIZE ,
1115+ .wsize = NFS_MAX_FILE_IO_SIZE ,
1116+ .timeo = 600 ,
1117+ .retrans = 2 ,
1118+ .acregmin = 3 ,
1119+ .acregmax = 60 ,
1120+ .acdirmin = 30 ,
1121+ .acdirmax = 60 ,
1122+ .mount_server .protocol = IPPROTO_UDP ,
1123+ .mount_server .program = NFS_MNT_PROGRAM ,
1124+ .nfs_server .protocol = IPPROTO_TCP ,
1125+ .nfs_server .program = NFS_PROGRAM ,
1126+ };
1127+
1128+ if (nfs_parse_mount_options ((char * ) * options , & args ) == 0 )
1129+ return - EINVAL ;
1130+
1131+ data = kzalloc (sizeof (* data ), GFP_KERNEL );
1132+ if (data == NULL )
1133+ return - ENOMEM ;
1134+
1135+ /*
1136+ * NB: after this point, caller will free "data"
1137+ * if we return an error
1138+ */
1139+ * options = data ;
1140+
1141+ c = strchr (dev_name , ':' );
1142+ if (c == NULL )
1143+ return - EINVAL ;
1144+ len = c - dev_name - 1 ;
1145+ if (len > sizeof (data -> hostname ))
1146+ return - EINVAL ;
1147+ strncpy (data -> hostname , dev_name , len );
1148+ args .nfs_server .hostname = data -> hostname ;
1149+
1150+ c ++ ;
1151+ if (strlen (c ) > NFS_MAXPATHLEN )
1152+ return - EINVAL ;
1153+ args .nfs_server .export_path = c ;
1154+
1155+ status = nfs_try_mount (& args , mntfh );
1156+ if (status )
1157+ return - EINVAL ;
1158+
1159+ /*
1160+ * Translate to nfs_mount_data, which nfs_fill_super
1161+ * can deal with.
1162+ */
1163+ data -> version = 6 ;
1164+ data -> flags = args .flags ;
1165+ data -> rsize = args .rsize ;
1166+ data -> wsize = args .wsize ;
1167+ data -> timeo = args .timeo ;
1168+ data -> retrans = args .retrans ;
1169+ data -> acregmin = args .acregmin ;
1170+ data -> acregmax = args .acregmax ;
1171+ data -> acdirmin = args .acdirmin ;
1172+ data -> acdirmax = args .acdirmax ;
1173+ data -> addr = args .nfs_server .address ;
1174+ data -> namlen = args .namlen ;
1175+ data -> bsize = args .bsize ;
1176+ data -> pseudoflavor = args .auth_flavors [0 ];
1177+
1178+ break ;
1179+ }
10921180 }
10931181
10941182 if (!(data -> flags & NFS_MOUNT_SECFLAVOUR ))
@@ -1117,11 +1205,6 @@ static int nfs_validate_mount_data(struct nfs_mount_data *data,
11171205 dfprintk (MOUNT , "NFS: nfs_mount_data version supports only AUTH_SYS\n" );
11181206 return - EINVAL ;
11191207
1120- out_bad_version :
1121- dfprintk (MOUNT , "NFS: bad nfs_mount_data version %d\n" ,
1122- data -> version );
1123- return - EINVAL ;
1124-
11251208#ifndef CONFIG_NFS_V3
11261209out_v3_not_compiled :
11271210 dfprintk (MOUNT , "NFS: NFSv3 is not compiled into kernel\n" );
@@ -1242,7 +1325,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
12421325 int error ;
12431326
12441327 /* Validate the mount data */
1245- error = nfs_validate_mount_data (data , & mntfh );
1328+ error = nfs_validate_mount_data (& data , & mntfh , dev_name );
12461329 if (error < 0 )
12471330 goto out ;
12481331
@@ -1283,6 +1366,8 @@ static int nfs_get_sb(struct file_system_type *fs_type,
12831366 error = 0 ;
12841367
12851368out :
1369+ if (data != raw_data )
1370+ kfree (data );
12861371 return error ;
12871372
12881373out_err_nosb :
0 commit comments