This is the core patch of the proposed interface. It basically consists of an option parser much like the one some filesystems, like for instance the ext family, ships. It does, however, have two fundamental differences: * Since it is generic, it does not operate on a super block. Rather, a mountpoint, which is a file-system independent entity, is its argument. Per-mntpoint options are expected to be tweaked here. * It modifies the option string to remove whatever option it handled. This allow us to chain this parser with whatever parser the underlying filesystem may have. Its first option is vfs_dcache_size. It specifies how many dentries are allowed to exist at any given time in the dentry group that lives in this mount point. --- fs/namespace.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mount.h | 2 + 2 files changed, 67 insertions(+), 0 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index dffe6f4..3ccd264 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -33,6 +33,7 @@ #include <linux/fsnotify.h> #include <asm/uaccess.h> #include <asm/unistd.h> +#include <linux/parser.h> #include "pnode.h" #include "internal.h" @@ -2190,6 +2191,70 @@ int copy_mount_string(const void __user *data, char **where) return 0; } +static const match_table_t tokens = { + {1, "vfs_dcache_size=%u"}, +}; + +int vfs_parse_options(char *options, struct vfsmount *mnt) +{ + substring_t args[MAX_OPT_ARGS]; + unsigned int option; + char *p; + char *opt; + char *start = NULL; + + /* FIXME: remove options from original string */ + if (!options) + return 1; + + opt = kstrdup(options, GFP_KERNEL); + if (!opt) + return 0; + + start = opt; + + while ((p = strsep(&opt, ",")) != NULL) { + int token; + if (!*p) + continue; + + /* + * Initialize args struct so we know whether arg was + * found; some options take optional arguments. + */ + args[0].to = args[0].from = 0; + token = match_token(p, tokens, args); + switch (token) { + case 1: + if (args[0].from) { + if (match_int(&args[0], &option)) { + break; + } + else { + mnt->dcache_size = option; + } + } + else { + printk("did not give an option\n"); + break; + } + + if (!opt) /* it is the last option listed */ + *(options + (p - start)) = '\0'; + else + strcpy(options + (p - start), opt); + break; + default: + break; + } + } + kfree(start); + + return 0; +} + + + /* * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to * be given to the mount() call (ie: read-only, no-dev, no-suid etc). diff --git a/include/linux/mount.h b/include/linux/mount.h index 604f122..cf50da2 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -86,6 +86,8 @@ struct vfsmount { int mnt_expiry_mark; /* true if marked for expiry */ int mnt_pinned; int mnt_ghosts; + + unsigned int dcache_size; }; struct file; /* forward dec */ -- 1.7.5.1 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html