linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] cleanup parse_options() of fatfs (3/4)
@ 2002-05-25 11:56 OGAWA Hirofumi
  2002-05-25 17:45 ` Alexander Viro
  0 siblings, 1 reply; 3+ messages in thread
From: OGAWA Hirofumi @ 2002-05-25 11:56 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel

This patch merges the parse_options() of vfat and fat. And, added the
(borrowed from ext3) code for reporting the error of specified
options.

Please apply.
-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

diff -urN fat_utf8_oops-2.5.18/fs/fat/inode.c fat_parse_opt-2.5.18/fs/fat/inode.c
--- fat_utf8_oops-2.5.18/fs/fat/inode.c	Sat May 25 17:14:49 2002
+++ fat_parse_opt-2.5.18/fs/fat/inode.c	Sat May 25 17:19:33 2002
@@ -201,163 +201,256 @@
 	kfree(sbi);
 }
 
+static int invalid_option(char *value, char *option)
+{
+	printk(KERN_NOTICE "FAT: Invalid %s option: %s\n", option, value);
+	return -EINVAL;
+}
+
+static int want_value(char *value, char *option)
+{
+	if (!value || !*value) {
+		printk(KERN_NOTICE "FAT: the %s option needs an argument\n",
+		       option);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int
+__want_numeric(char *value, char *option, unsigned long *number, int base)
+{
+	char *endp;
+	if (want_value(value, option))
+		return -EINVAL;
+	*number = simple_strtoul(value, &endp, base);
+	if (*endp) {
+		printk(KERN_NOTICE "FAT: Invalid %s argument: %s\n",
+		       option, value);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static inline int want_numeric(char *value, char *option, unsigned long *number)
+{
+	return __want_numeric(value, option, number, 0);
+}
+
+static inline int want_oct(char *value, char *option, unsigned long *number)
+{
+	return __want_numeric(value, option, number, 8);
+}
+
+static int want_bool(char *v, char *option, unsigned long *setval)
+{
+	if (v == NULL) {
+		*setval = 1;
+		return 0;
+	}
 
-static int parse_options(char *options, int *debug,
+	if (want_value(v, option))
+		return -EINVAL;
+	if (!strcmp(v, "1") || !strcmp(v, "yes") || !strcmp(v, "true"))
+		*setval = 1;
+	else if (!strcmp(v, "0") || !strcmp(v, "no") || !strcmp(v, "false"))
+		*setval = 0;
+	else {
+		invalid_option(v, option);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int parse_options(char *options, int is_vfat, int *debug,
 			 struct fat_mount_options *opts,
 			 char *cvf_format, char *cvf_options)
 {
-	char *this_char,*value,save,*savep;
-	char *p;
-	int ret = 1, len;
+	char *this_char, *value;
+	unsigned long val;
 
-	opts->name_check = 'n';
-	opts->conversion = 'b';
 	opts->fs_uid = current->uid;
 	opts->fs_gid = current->gid;
 	opts->fs_umask = current->fs->umask;
-	opts->quiet = opts->sys_immutable = opts->dotsOK = opts->showexec = 0;
 	opts->codepage = 0;
-	opts->nocase = 0;
-	opts->shortname = 0;
-	opts->utf8 = 0;
 	opts->iocharset = NULL;
+	opts->shortname = 0;
+	if (is_vfat)
+		opts->shortname = VFAT_SFN_DISPLAY_LOWER|VFAT_SFN_CREATE_WIN95;
+	opts->name_check = 'n';
+	opts->conversion = 'b';
+	opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK =  0;
+	opts->isvfat = is_vfat;
+	opts->utf8 = opts->unicode_xlate = opts->posixfs = 0;
+	opts->numtail = 1;
+	opts->nocase = 0;
 	*debug = 0;
 
 	if (!options)
-		goto out;
-	save = 0;
-	savep = NULL;
-	while ((this_char = strsep(&options,",")) != NULL) {
+		return 0;
+	while ((this_char = strsep(&options, ",")) != NULL) {
 		if (!*this_char)
 			continue;
-		if ((value = strchr(this_char,'=')) != NULL) {
-			save = *value;
-			savep = value;
+		if ((value = strchr(this_char, '=')) != NULL)
 			*value++ = 0;
-		}
-		if (!strcmp(this_char,"check") && value) {
-			if (value[0] && !value[1] && strchr("rns",*value))
+
+		if (!strcmp(this_char, "debug"))
+			*debug = 1;
+		else if (!strcmp(this_char, "uid")) {
+			if (want_numeric(value, "uid", &val))
+				goto error;
+			opts->fs_uid = val;
+		}
+		else if (!strcmp(this_char, "gid")) {
+			if (want_numeric(value, "gid", &val))
+				goto error;
+			opts->fs_gid = val;
+		}
+		else if (!strcmp(this_char, "umask")) {
+			if (want_oct(value, "umask", &val))
+				goto error;
+			opts->fs_umask = val & S_IRWXUGO;
+		}
+		else if (!strcmp(this_char, "codepage")) {
+			if (want_numeric(value, "codepage", &val))
+				goto error;
+			opts->codepage = val;
+		}
+		else if (!strcmp(this_char, "check")) {
+			if (want_value(value, "check"))
+				goto error;
+			if (!value[1] && strchr("rns", *value))
 				opts->name_check = *value;
-			else if (!strcmp(value,"relaxed"))
+			else if (!strcmp(value, "relaxed"))
 				opts->name_check = 'r';
-			else if (!strcmp(value,"normal"))
+			else if (!strcmp(value, "normal"))
 				opts->name_check = 'n';
-			else if (!strcmp(value,"strict"))
+			else if (!strcmp(value, "strict"))
 				opts->name_check = 's';
-			else ret = 0;
+			else
+				return invalid_option(value, "check");
 		}
-		else if (!strcmp(this_char,"conv") && value) {
-			if (value[0] && !value[1] && strchr("bta",*value))
+		else if (!strcmp(this_char, "conv")) {
+			if (want_value(value, "conv"))
+				goto error;
+			if (!value[1] && strchr("bta", *value))
 				opts->conversion = *value;
-			else if (!strcmp(value,"binary"))
+			else if (!strcmp(value, "binary"))
 				opts->conversion = 'b';
-			else if (!strcmp(value,"text"))
+			else if (!strcmp(value, "text"))
 				opts->conversion = 't';
-			else if (!strcmp(value,"auto"))
+			else if (!strcmp(value, "auto"))
 				opts->conversion = 'a';
-			else ret = 0;
+			else
+				return invalid_option(value, "conv");
 		}
-		else if (!strcmp(this_char,"dots")) {
-			opts->dotsOK = 1;
-		}
-		else if (!strcmp(this_char,"nocase")) {
-			opts->nocase = 1;
-		}
-		else if (!strcmp(this_char,"nodots")) {
-			opts->dotsOK = 0;
-		}
-		else if (!strcmp(this_char,"showexec")) {
+		else if (!strcmp(this_char, "quiet"))
+			opts->quiet = 1;
+		else if (!strcmp(this_char, "showexec"))
 			opts->showexec = 1;
-		}
-		else if (!strcmp(this_char,"dotsOK") && value) {
-			if (!strcmp(value,"yes")) opts->dotsOK = 1;
-			else if (!strcmp(value,"no")) opts->dotsOK = 0;
-			else ret = 0;
-		}
-		else if (!strcmp(this_char,"uid")) {
-			if (!value || !*value) ret = 0;
-			else {
-				opts->fs_uid = simple_strtoul(value,&value,0);
-				if (*value) ret = 0;
-			}
-		}
-		else if (!strcmp(this_char,"gid")) {
-			if (!value || !*value) ret= 0;
-			else {
-				opts->fs_gid = simple_strtoul(value,&value,0);
-				if (*value) ret = 0;
-			}
-		}
-		else if (!strcmp(this_char,"umask")) {
-			if (!value || !*value) ret = 0;
+		else if (!strcmp(this_char,"sys_immutable"))
+			opts->sys_immutable = 1;
+		else if (!strcmp(this_char, "nocase")) {
+			if (!is_vfat)
+				opts->nocase = 1;
 			else {
-				opts->fs_umask = simple_strtoul(value,&value,8);
-				if (*value) ret = 0;
+				/* for backward compatible */
+				opts->shortname = VFAT_SFN_DISPLAY_WIN95
+					| VFAT_SFN_CREATE_WIN95;
 			}
 		}
-		else if (!strcmp(this_char,"debug")) {
-			if (value) ret = 0;
-			else *debug = 1;
-		}
-		else if (!strcmp(this_char,"fat")) {
-			printk("FAT: fat option is obsolete, "
+		else if (!strcmp(this_char, "fat")) {
+			printk(KERN_NOTICE "FAT: fat option is obsolete, "
 			       "not supported now\n");
 		}
-		else if (!strcmp(this_char,"quiet")) {
-			if (value) ret = 0;
-			else opts->quiet = 1;
-		}
-		else if (!strcmp(this_char,"blocksize")) {
-			printk("FAT: blocksize option is obsolete, "
+		else if (!strcmp(this_char, "blocksize")) {
+			printk(KERN_NOTICE "FAT: blocksize option is obsolete, "
 			       "not supported now\n");
 		}
-		else if (!strcmp(this_char,"sys_immutable")) {
-			if (value) ret = 0;
-			else opts->sys_immutable = 1;
-		}
-		else if (!strcmp(this_char,"codepage") && value) {
-			opts->codepage = simple_strtoul(value,&value,0);
-			if (*value) ret = 0;
-		}
-		else if (!strcmp(this_char,"iocharset") && value) {
-			p = value;
-			while (*value && *value != ',')
-				value++;
-			len = value - p;
-			if (len) {
-				char *buffer;
-
-				if (opts->iocharset != NULL) {
-					kfree(opts->iocharset);
-					opts->iocharset = NULL;
-				}
-				buffer = kmalloc(len + 1, GFP_KERNEL);
-				if (buffer != NULL) {
-					opts->iocharset = buffer;
-					memcpy(buffer, p, len);
-					buffer[len] = 0;
-				} else
-					ret = 0;
-			}
-		}
-		else if (!strcmp(this_char,"cvf_format")) {
-			if (!value)
-				return 0;
-			strncpy(cvf_format,value,20);
-		}
-		else if (!strcmp(this_char,"cvf_options")) {
-			if (!value)
-				return 0;
-			strncpy(cvf_options,value,100);
+		else if (!strcmp(this_char, "cvf_format")) {
+			if (want_value(value, "cvf_format"))
+				goto error;
+			strncpy(cvf_format, value, 20);
+			cvf_format[19] = '\0';
+		}
+		else if (!strcmp(this_char, "cvf_options")) {
+			if (want_value(value, "cvf_options"))
+				goto error;
+			strncpy(cvf_options, value, 100);
+			cvf_options[99] = '\0';
 		}
 
-		if (this_char != options) *(this_char-1) = ',';
-		if (value) *savep = save;
-		if (ret == 0)
-			break;
+		/* msdos specific */
+		else if (!is_vfat && !strcmp(this_char, "dots"))
+			opts->dotsOK = 1;
+		else if (!is_vfat && !strcmp(this_char, "nodots"))
+			opts->dotsOK = 0;
+		else if (!is_vfat && !strcmp(this_char, "dotsOK")) {
+			if (want_bool(value, "dotsOK", &val))
+				goto error;
+			opts->dotsOK = val;
+		}
+
+		/* vfat specific */
+		else if (is_vfat && !strcmp(this_char, "iocharset")) {
+			if (want_value(value, "iocharset"))
+				goto error;
+			if (opts->iocharset != NULL)
+				kfree(opts->iocharset);
+			opts->iocharset = kmalloc(strlen(value)+1, GFP_KERNEL);
+			if (opts->iocharset == NULL)
+				return -ENOMEM;
+			strcpy(opts->iocharset, value);
+		}
+		else if (is_vfat && !strcmp(this_char, "utf8")) {
+			if (want_bool(value, "utf8", &val))
+				goto error;
+			opts->utf8 = val;
+		} else if (is_vfat && !strcmp(this_char, "uni_xlate")) {
+			if (want_bool(value, "uni_xlate", &val))
+				goto error;
+			opts->unicode_xlate = val;
+		} else if (is_vfat && !strcmp(this_char, "posix")) {
+			if (want_bool(value, "posix", &val))
+				goto error;
+			opts->posixfs = val;
+		} else if (is_vfat && !strcmp(this_char,"nonumtail")) {
+			if (want_bool(value, "nonumtail", &val))
+				goto error;
+			opts->numtail = !val;
+		} else if (is_vfat && !strcmp(this_char, "shortname")) {
+			if (want_value(value, "shortname"))
+				goto error;
+			if (!strcmp(value, "lower"))
+				opts->shortname = VFAT_SFN_DISPLAY_LOWER
+					| VFAT_SFN_CREATE_WIN95;
+			else if (!strcmp(value, "win95"))
+				opts->shortname = VFAT_SFN_DISPLAY_WIN95
+					| VFAT_SFN_CREATE_WIN95;
+			else if (!strcmp(value, "winnt"))
+				opts->shortname = VFAT_SFN_DISPLAY_WINNT
+					| VFAT_SFN_CREATE_WINNT;
+			else if (!strcmp(value, "mixed"))
+				opts->shortname = VFAT_SFN_DISPLAY_WINNT
+					| VFAT_SFN_CREATE_WIN95;
+			else
+				return invalid_option(value, "shortname");
+		} else {
+			printk(KERN_NOTICE
+			       "FAT: Unrecognized mount option %s\n",
+			       this_char);
+			goto error;
+		}
 	}
-out:
-	return ret;
+
+	if (opts->posixfs)
+		opts->name_check = 's';
+	if (opts->unicode_xlate)
+		opts->utf8 = 0;
+	
+	return 0;
+error:
+	return -EINVAL;
 }
 
 static int fat_calc_dir_size(struct inode *inode)
@@ -641,7 +734,7 @@
 	int logical_sector_size, fat_clusters, debug, cp, first;
 	unsigned int total_sectors, rootdir_sectors;
 	unsigned char media;
-	long error = -EIO;
+	long error;
 	char buf[50];
 	int i;
 	char cvf_format[21];
@@ -660,18 +753,19 @@
 	sb->s_magic = MSDOS_SUPER_MAGIC;
 	sb->s_op = &fat_sops;
 	sb->s_export_op = &fat_export_ops;
-	sbi->options.isvfat = isvfat;
 	sbi->dir_ops = fs_dir_inode_ops;
 	sbi->cvf_format = &default_cvf;
 
-	if (!parse_options((char *)data, &debug, &sbi->options,
-			   cvf_format, cvf_options))
+	error = parse_options((char *)data, isvfat, &debug, &sbi->options,
+			      cvf_format, cvf_options);
+	if (error < 0)
 		goto out_fail;
 
 	fat_cache_init();
 	/* set up enough so that it can read an inode */
 	init_MUTEX(&sbi->fat_lock);
 
+	error = -EIO;
 	sb_min_blocksize(sb, 512);
 	bh = sb_bread(sb, 0);
 	if (bh == NULL) {
@@ -848,13 +942,14 @@
 		goto out_invalid;
 	}
 
+	error = -EINVAL;
 	if (!strcmp(cvf_format, "none"))
 		i = -1;
 	else
 		i = detect_cvf(sb, cvf_format);
 	if (i >= 0) {
 		if (cvf_formats[i]->mount_cvf(sb, cvf_options))
-			goto out_invalid;
+			goto out_fail;
 	}
 
 	cp = sbi->options.codepage ? sbi->options.codepage : 437;
@@ -912,6 +1007,9 @@
 
 out_invalid:
 	error = -EINVAL;
+	if (!silent)
+		printk(KERN_INFO "VFS: Can't find a valid FAT filesystem"
+		       " on dev %s.\n", sb->s_id);
 
 out_fail:
 	if (root_inode)
diff -urN fat_utf8_oops-2.5.18/fs/msdos/namei.c fat_parse_opt-2.5.18/fs/msdos/namei.c
--- fat_utf8_oops-2.5.18/fs/msdos/namei.c	Sat May 25 17:09:22 2002
+++ fat_parse_opt-2.5.18/fs/msdos/namei.c	Sat May 25 17:19:33 2002
@@ -604,12 +604,8 @@
 	int res;
 
 	res = fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, 0);
-	if (res) {
-		if (res == -EINVAL && !silent)
-			printk(KERN_INFO "VFS: Can't find a valid"
-			       " MSDOS filesystem on dev %s.\n", sb->s_id);
+	if (res)
 		return res;
-	}
 
 	sb->s_root->d_op = &msdos_dentry_operations;
 	return 0;
diff -urN fat_utf8_oops-2.5.18/fs/vfat/namei.c fat_parse_opt-2.5.18/fs/vfat/namei.c
--- fat_utf8_oops-2.5.18/fs/vfat/namei.c	Sat May 25 17:09:22 2002
+++ fat_parse_opt-2.5.18/fs/vfat/namei.c	Sat May 25 17:19:33 2002
@@ -80,95 +80,6 @@
 	return 0;
 }
 
-static int simple_getbool(char *s, int *setval)
-{
-	if (s) {
-		if (!strcmp(s,"1") || !strcmp(s,"yes") || !strcmp(s,"true")) {
-			*setval = 1;
-		} else if (!strcmp(s,"0") || !strcmp(s,"no") || !strcmp(s,"false")) {
-			*setval = 0;
-		} else {
-			return 0;
-		}
-	} else {
-		*setval = 1;
-	}
-	return 1;
-}
-
-static int parse_options(char *options,	struct fat_mount_options *opts)
-{
-	char *this_char,*value,save,*savep;
-	int ret, val;
-
-	opts->unicode_xlate = opts->posixfs = 0;
-	opts->numtail = 1;
-	opts->utf8 = 0;
-	opts->shortname = VFAT_SFN_DISPLAY_LOWER | VFAT_SFN_CREATE_WIN95;
-	/* for backward compatible */
-	if (opts->nocase) {
-		opts->nocase = 0;
-		opts->shortname = VFAT_SFN_DISPLAY_WIN95
-		  		| VFAT_SFN_CREATE_WIN95;
-	}
-
-	if (!options) return 1;
-	save = 0;
-	savep = NULL;
-	ret = 1;
-	while ((this_char = strsep(&options,",")) != NULL) {
-		if (!*this_char)
-			continue;
-		if ((value = strchr(this_char,'=')) != NULL) {
-			save = *value;
-			savep = value;
-			*value++ = 0;
-		}
-		if (!strcmp(this_char,"utf8")) {
-			ret = simple_getbool(value, &val);
-			if (ret) opts->utf8 = val;
-		} else if (!strcmp(this_char,"uni_xlate")) {
-			ret = simple_getbool(value, &val);
-			if (ret) opts->unicode_xlate = val;
-		} else if (!strcmp(this_char,"posix")) {
-			ret = simple_getbool(value, &val);
-			if (ret) opts->posixfs = val;
-		} else if (!strcmp(this_char,"nonumtail")) {
-			ret = simple_getbool(value, &val);
-			if (ret) {
-				opts->numtail = !val;
-			}
-		} else if (!strcmp(this_char, "shortname")) {
-			if (!strcmp(value, "lower"))
-				opts->shortname = VFAT_SFN_DISPLAY_LOWER
-						| VFAT_SFN_CREATE_WIN95;
-			else if (!strcmp(value, "win95"))
-				opts->shortname = VFAT_SFN_DISPLAY_WIN95
-						| VFAT_SFN_CREATE_WIN95;
-			else if (!strcmp(value, "winnt"))
-				opts->shortname = VFAT_SFN_DISPLAY_WINNT
-						| VFAT_SFN_CREATE_WINNT;
-			else if (!strcmp(value, "mixed"))
-				opts->shortname = VFAT_SFN_DISPLAY_WINNT
-						| VFAT_SFN_CREATE_WIN95;
-			else
-				ret = 0;
-		}
-		if (this_char != options)
-			*(this_char-1) = ',';
-		if (value) {
-			*savep = save;
-		}
-		if (ret == 0) {
-			return 0;
-		}
-	}
-	if (opts->unicode_xlate) {
-		opts->utf8 = 0;
-	}
-	return 1;
-}
-
 static inline unsigned char
 vfat_tolower(struct nls_table *t, unsigned char c)
 {
@@ -1296,25 +1207,14 @@
 	struct msdos_sb_info *sbi;
   
 	res = fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, 1);
-	if (res) {
-		if (res == -EINVAL && !silent)
-			printk(KERN_INFO "VFS: Can't find a valid"
-			       " VFAT filesystem on dev %s.\n", sb->s_id);
+	if (res)
 		return res;
-	}
 
 	sbi = MSDOS_SB(sb);
-
-	if (parse_options((char *) data, &(sbi->options))) {
-		sbi->options.dotsOK = 0;
-		if (sbi->options.posixfs) {
-			sbi->options.name_check = 's';
-		}
-	}
-	if (sbi->options.name_check != 's') {
+	if (sbi->options.name_check != 's')
 		sb->s_root->d_op = &vfat_dentry_ops[0];
-	} else {
+	else
 		sb->s_root->d_op = &vfat_dentry_ops[2];
-	}
+
 	return 0;
 }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] cleanup parse_options() of fatfs (3/4)
  2002-05-25 11:56 [PATCH] cleanup parse_options() of fatfs (3/4) OGAWA Hirofumi
@ 2002-05-25 17:45 ` Alexander Viro
  2002-05-25 19:07   ` OGAWA Hirofumi
  0 siblings, 1 reply; 3+ messages in thread
From: Alexander Viro @ 2002-05-25 17:45 UTC (permalink / raw)
  To: OGAWA Hirofumi; +Cc: Linus Torvalds, linux-kernel



On Sat, 25 May 2002, OGAWA Hirofumi wrote:

> This patch merges the parse_options() of vfat and fat. And, added the
> (borrowed from ext3) code for reporting the error of specified
> options.
> 
> Please apply.

Please, hold on.  If we are going to do that, we'd better do it right...
I'll resurrect and post the options-parser patch - it covers all that
stuff with less ad-hackery.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] cleanup parse_options() of fatfs (3/4)
  2002-05-25 17:45 ` Alexander Viro
@ 2002-05-25 19:07   ` OGAWA Hirofumi
  0 siblings, 0 replies; 3+ messages in thread
From: OGAWA Hirofumi @ 2002-05-25 19:07 UTC (permalink / raw)
  To: Alexander Viro; +Cc: Linus Torvalds, linux-kernel

Alexander Viro <viro@math.psu.edu> writes:

> On Sat, 25 May 2002, OGAWA Hirofumi wrote:
> 
> > This patch merges the parse_options() of vfat and fat. And, added the
> > (borrowed from ext3) code for reporting the error of specified
> > options.
> > 
> > Please apply.
> 
> Please, hold on.  If we are going to do that, we'd better do it right...
> I'll resurrect and post the options-parser patch - it covers all that
> stuff with less ad-hackery.

Good. I was actually waiting for it.
Please post that patch.
-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-05-25 19:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-25 11:56 [PATCH] cleanup parse_options() of fatfs (3/4) OGAWA Hirofumi
2002-05-25 17:45 ` Alexander Viro
2002-05-25 19:07   ` OGAWA Hirofumi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).