Add token parsing for kernel CIFS mount options

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Add token parsing for kernel CIFS mount options

Scott Lovenberg

This set of patches adds the functionality of a token parser for parsing kernel CIFS mount options.
The options are defined as constants (in an enum) and are used in a switch statement, replacing the if/else chain that was previously used for parsing options.

The first patch defines the constants and parsing function, the second patch implements them.


_______________________________________________
linux-cifs-client mailing list
[hidden email]
https://lists.samba.org/mailman/listinfo/linux-cifs-client
Reply | Threaded
Open this post in threaded view
|

[PATCH 1/2] connect.c: define mount options enum and parsing function

Scott Lovenberg
Mount options have been defined as an enum.
A token parsing function has been added to translate from text to the defined constants.

Signed-off-by: Scott Lovenberg <[hidden email]>
---
 fs/cifs/connect.c |  266 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 266 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 2208f06..83d5cd8 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -52,6 +52,94 @@
 #define CIFS_PORT 445
 #define RFC1001_PORT 139
 
+/* mounting option values */
+enum CIFS_MOUNT_TOKEN {
+ CIFS_TOKEN_ERROR    =   -1,
+ USERXATTR           =   1,
+ NO_USERXATTR        =   2,
+ USER                =   3,
+ PASS                =   4,
+ IP                  =   5,
+ ADDR                =   6,
+ SEC                 =   7,
+ UNC                 =   8,
+ TARGET              =   9,
+ PATH                =  10,
+ DOMAIN              =  11,
+ WORKGROUP           =  12,
+ PREFIXPATH          =  13,
+ IOCHARSET           =  14,
+ UID                 =  15,
+ FORCE_UID           =  16,
+ NO_FORCE_UID        =  17,
+ GID                 =  18,
+ FORCE_GID           =  19,
+ NO_FORCE_GID        =  20,
+ FILEMODE            =  21,
+ DIRMODE             =  22,
+ PORT                =  23,
+ RSIZE               =  24,
+ WSIZE               =  25,
+ SOCKOPT             =  26,
+ NETBIOSNAME         =  27,
+ SERVERNAME          =  28,
+ CREDENTIALS         =  29,
+ VERSION             =  30,
+ GUEST               =  31,
+ RW                  =  32,
+ RO                  =  33,
+ NO_BLOCKSEND        =  34,
+ NO_AUTOTUNE         =  35,
+ NO_AUTO             =  36,
+ SUID                =  37,
+ NO_SUID             =  38,
+ EXEC                =  39,
+ NO_EXEC             =  40,
+ DEV                 =  41,
+ NO_DEV              =  42,
+ HARD                =  43,
+ NO_HARD             =  44,
+ SOFT                =  45,
+ NO_SOFT             =  46,
+ PERM                =  47,
+ NO_PERM             =  48,
+ MAPCHARS            =  49,
+ NO_MAPCHARS         =  50,
+ SFU                 =  51,
+ NO_SFU              =  52,
+ NO_DFS              =  53,
+ POSIXPATHS          =  54,
+ NO_POSIXPATHS       =  55,
+ NO_UNIX             =  56,
+ NO_LINUX            =  57,
+ NO_CASE             =  58,
+ IGNORECASE          =  59,
+ BRL                 =  60,
+ NO_BRL              =  61,
+ NO_LOCK             =  62,
+ FORCE_MANDATORYLOCK =  63,
+ SETUIDS             =  64,
+ NO_SETUIDS          =  65,
+ DYNPERM             =  66,
+ NO_DYNPERM          =  67,
+ INTR                =  68,
+ NO_INTR             =  69,
+ STRICTSYNC          =  70,
+ NO_STRICTSYNC       =  71,
+ SERVERINO           =  72,
+ NO_SERVERINO        =  73,
+ ACL                 =  74,
+ NO_ACL              =  75,
+ CIFSACL             =  76,
+ NO_CIFSACL          =  77,
+ LOCALLEASE          =  78,
+ SIGN                =  79,
+ SEAL                =  80,
+ DIRECT              =  81,
+ FORCE_DIRECT        =  82,
+ NO_AC               =  83
+};
+
 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
  unsigned char *p24);
 
@@ -797,6 +885,184 @@ extract_hostname(const char *unc)
  return dst;
 }
 
+/* returns the CIFS_MOUNT_TOKEN value that represents 'option' */
+static int cifs_parse_mount_token(const char *option)
+{
+ if (option == NULL)
+ return CIFS_TOKEN_ERROR;
+
+ if (strnicmp(option, "user_xattr", 10) == 0)
+ return USERXATTR;
+ if (strnicmp(option, "nouser_xattr", 12) == 0)
+ return NO_USERXATTR;
+ if (strnicmp(option, "user", 4) == 0)
+ return USER;
+ if (strnicmp(option, "pass", 4) == 0)
+ return PASS;
+ if (strnicmp(option, "ip", 2) == 0)
+ return IP;
+ if (strnicmp(option, "addr", 4) == 0)
+ return ADDR;
+ if (strnicmp(option, "sec", 3) == 0)
+ return SEC;
+ if (strnicmp(option, "unc", 3) == 0)
+ return UNC;
+ if (strnicmp(option, "target", 6) == 0)
+ return TARGET;
+ if (strnicmp(option, "path", 4) == 0)
+ return PATH;
+ if (strnicmp(option, "domain", 3) == 0)
+ return DOMAIN;
+ if (strnicmp(option, "workgroup", 5) == 0)
+ return WORKGROUP;
+ if (strnicmp(option, "prefixpath", 10) == 0)
+ return PREFIXPATH;
+ if (strnicmp(option, "iocharset", 9) == 0)
+ return IOCHARSET;
+ if (strnicmp(option, "uid", 3) == 0)
+ return UID;
+ if (strnicmp(option, "forceuid", 8) == 0)
+ return FORCE_UID;
+ if (strnicmp(option, "noforceuid", 10) == 0)
+ return NO_FORCE_UID;
+ if (strnicmp(option, "gid", 3) == 0)
+ return GID;
+ if (strnicmp(option, "forcegid", 8) == 0)
+ return FORCE_GID;
+ if (strnicmp(option, "noforcegid", 10) == 0)
+ return NO_FORCE_GID;
+ if (strnicmp(option, "file_mode", 4) == 0)
+ return FILEMODE;
+ /* dir_mode || dirmode */
+ if (strnicmp(option, "dir", 3) == 0)
+ return DIRMODE;
+ if (strnicmp(option, "port", 4) == 0)
+ return PORT;
+ if (strnicmp(option, "rsize", 5) == 0)
+ return RSIZE;
+ if (strnicmp(option, "wsize", 5) == 0)
+ return WSIZE;
+ if (strnicmp(option, "sockopt", 5) == 0)
+ return SOCKOPT;
+ if (strnicmp(option, "netbiosname", 4) == 0)
+ return NETBIOSNAME;
+ if (strnicmp(option, "servername", 7) == 0)
+ return SERVERNAME;
+ if (strnicmp(option, "credentials", 4) == 0)
+ return CREDENTIALS;
+ if (strnicmp(option, "version", 3) == 0)
+ return VERSION;
+ if (strnicmp(option, "guest", 5) == 0)
+ return GUEST;
+ if (strnicmp(option, "rw", 2) == 0)
+ return RW;
+ if (strnicmp(option, "ro", 2) == 0)
+ return RO;
+ if (strnicmp(option, "noblocksend", 11) == 0)
+ return NO_BLOCKSEND;
+ if (strnicmp(option, "noautotune", 10) == 0)
+ return NO_AUTOTUNE;
+ if (strnicmp(option, "suid", 4) == 0)
+ return SUID;
+ if (strnicmp(option, "nosuid", 6) == 0)
+ return NO_SUID;
+ if (strnicmp(option, "exec", 4) == 0)
+ return EXEC;
+ if (strnicmp(option, "noexec", 6) == 0)
+ return NO_EXEC;
+ if (strnicmp(option, "dev", 3) == 0)
+ return DEV;
+ if (strnicmp(option, "nodev", 5) == 0)
+ return NO_DEV;
+ if (strnicmp(option, "noauto", 6) == 0)
+ return NO_AUTO;
+ if (strnicmp(option, "hard", 4) == 0)
+ return HARD;
+ if (strnicmp(option, "nohard", 6) == 0)
+ return NO_HARD;
+ if (strnicmp(option, "soft", 4) == 0)
+ return SOFT;
+ if (strnicmp(option, "nosoft", 6) == 0)
+ return NO_SOFT;
+ if (strnicmp(option, "perm", 4) == 0)
+ return PERM;
+ if (strnicmp(option, "noperm", 6) == 0)
+ return NO_PERM;
+ if (strnicmp(option, "mapchars", 8) == 0)
+ return MAPCHARS;
+ if (strnicmp(option, "nomapchars", 10) == 0)
+ return NO_MAPCHARS;
+ if (strnicmp(option, "sfu", 3) == 0)
+ return SFU;
+ if (strnicmp(option, "nosfu", 5) == 0)
+ return NO_SFU;
+ if (strnicmp(option, "nodfs", 5) == 0)
+ return NO_DFS;
+ if (strnicmp(option, "posixpaths", 10) == 0)
+ return POSIXPATHS;
+ if (strnicmp(option, "noposixpaths", 12) == 0)
+ return NO_POSIXPATHS;
+ if (strnicmp(option, "nounix", 6) == 0)
+ return NO_UNIX;
+ if (strnicmp(option, "nolinux", 7) == 0)
+ return NO_LINUX;
+ if (strnicmp(option, "nocase", 6) == 0)
+ return NO_CASE;
+ if (strnicmp(option, "ignorecase", 10) == 0)
+ return IGNORECASE;
+ if (strnicmp(option, "brl", 3) == 0)
+ return BRL;
+ if (strnicmp(option, "nobrl", 5) == 0)
+ return NO_BRL;
+ if (strnicmp(option, "nolock", 6) == 0)
+ return NO_LOCK;
+ if (strnicmp(option, "forcemandatorylock", 9) == 0)
+ return FORCE_MANDATORYLOCK;
+ if (strnicmp(option, "setuids", 7) == 0)
+ return SETUIDS;
+ if (strnicmp(option, "nosetuids", 9) == 0)
+ return NO_SETUIDS;
+ if (strnicmp(option, "dynperm", 7) == 0)
+ return DYNPERM;
+ if (strnicmp(option, "nodynperm", 9) == 0)
+ return NO_DYNPERM;
+ if (strnicmp(option, "intr", 4) == 0)
+ return INTR;
+ if (strnicmp(option, "nointr", 6) == 0)
+ return NO_INTR;
+ if (strnicmp(option, "strictsync", 10) == 0)
+ return STRICTSYNC;
+ if (strnicmp(option, "nostrictsync", 12) == 0)
+ return NO_STRICTSYNC;
+ if (strnicmp(option, "serverino", 7) == 0)
+ return SERVERINO;
+ if (strnicmp(option, "noserverino", 9) == 0)
+ return NO_SERVERINO;
+ if (strnicmp(option, "cifsacl", 7) == 0)
+ return CIFSACL;
+ if (strnicmp(option, "nocifsacl", 9) == 0)
+ return NO_CIFSACL;
+ if (strnicmp(option, "acl", 3) == 0)
+ return ACL;
+ if (strnicmp(option, "noacl", 5) == 0)
+ return NO_ACL;
+ if (strnicmp(option, "locallease", 6) == 0)
+ return LOCALLEASE;
+ if (strnicmp(option, "sign", 4) == 0)
+ return SIGN;
+ if (strnicmp(option, "seal", 4) == 0)
+ return SEAL;
+ if (strnicmp(option, "direct", 6) == 0)
+ return DIRECT;
+ if (strnicmp(option, "forcedirectio", 13) == 0)
+ return FORCE_DIRECT;
+ if (strnicmp(option, "noac", 4) == 0)
+ return NO_AC;
+
+ return CIFS_TOKEN_ERROR;
+}
+
+
 static int
 cifs_parse_mount_options(char *options, const char *devname,
  struct smb_vol *vol)
--
1.6.2.5

_______________________________________________
linux-cifs-client mailing list
[hidden email]
https://lists.samba.org/mailman/listinfo/linux-cifs-client
Reply | Threaded
Open this post in threaded view
|

[PATCH 2/2] connect.c: use defined constants for options

Scott Lovenberg
When parsing mount options, option constants are used to make code more readable.

Signed-off-by: Scott Lovenberg <[hidden email]>
---
 fs/cifs/connect.c |  290 ++++++++++++++++++++++++++++++++--------------------
 1 files changed, 178 insertions(+), 112 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 83d5cd8..a7f0b6f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1126,12 +1126,14 @@ cifs_parse_mount_options(char *options, const char *devname,
  if ((value = strchr(data, '=')) != NULL)
  *value++ = '\0';
 
- /* Have to parse this before we parse for "user" */
- if (strnicmp(data, "user_xattr", 10) == 0) {
+ switch (cifs_parse_mount_token(data)) {
+ case USERXATTR:
  vol->no_xattr = 0;
- } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
+ break;
+ case NO_USERXATTR:
  vol->no_xattr = 1;
- } else if (strnicmp(data, "user", 4) == 0) {
+ break;
+ case USER:
  if (!value) {
  printk(KERN_WARNING
        "CIFS: invalid or missing username\n");
@@ -1146,7 +1148,8 @@ cifs_parse_mount_options(char *options, const char *devname,
  printk(KERN_WARNING "CIFS: username too long\n");
  return 1;
  }
- } else if (strnicmp(data, "pass", 4) == 0) {
+ break;
+ case PASS:
  if (!value) {
  vol->password = NULL;
  continue;
@@ -1227,8 +1230,10 @@ cifs_parse_mount_options(char *options, const char *devname,
  }
  strcpy(vol->password, value);
  }
- } else if (!strnicmp(data, "ip", 2) ||
-   !strnicmp(data, "addr", 4)) {
+ break;
+ /* IP || ADDR */
+ case IP:
+ case ADDR:
  if (!value || !*value) {
  vol->UNCip = NULL;
  } else if (strnlen(value, INET6_ADDRSTRLEN) <
@@ -1239,7 +1244,8 @@ cifs_parse_mount_options(char *options, const char *devname,
     "too long\n");
  return 1;
  }
- } else if (strnicmp(data, "sec", 3) == 0) {
+ break;
+ case SEC:
  if (!value || !*value) {
  cERROR(1, "no security value specified");
  continue;
@@ -1284,9 +1290,11 @@ cifs_parse_mount_options(char *options, const char *devname,
  cERROR(1, "bad security option: %s", value);
  return 1;
  }
- } else if ((strnicmp(data, "unc", 3) == 0)
-   || (strnicmp(data, "target", 6) == 0)
-   || (strnicmp(data, "path", 4) == 0)) {
+ break;
+ /* UNC || TARGET || PATH */
+ case UNC:
+ case TARGET:
+ case PATH:
  if (!value || !*value) {
  printk(KERN_WARNING "CIFS: invalid path to "
     "network resource\n");
@@ -1310,8 +1318,11 @@ cifs_parse_mount_options(char *options, const char *devname,
  printk(KERN_WARNING "CIFS: UNC name too long\n");
  return 1;
  }
- } else if ((strnicmp(data, "domain", 3) == 0)
-   || (strnicmp(data, "workgroup", 5) == 0)) {
+ break;
+
+ /* DOMAIN || WORKGROUP */
+ case DOMAIN:
+ case WORKGROUP:
  if (!value || !*value) {
  printk(KERN_WARNING "CIFS: invalid domain name\n");
  return 1; /* needs_arg; */
@@ -1326,7 +1337,8 @@ cifs_parse_mount_options(char *options, const char *devname,
     "long\n");
  return 1;
  }
- } else if (strnicmp(data, "prefixpath", 10) == 0) {
+ break;
+ case PREFIXPATH:
  if (!value || !*value) {
  printk(KERN_WARNING
  "CIFS: invalid path prefix\n");
@@ -1348,7 +1360,8 @@ cifs_parse_mount_options(char *options, const char *devname,
  printk(KERN_WARNING "CIFS: prefix too long\n");
  return 1;
  }
- } else if (strnicmp(data, "iocharset", 9) == 0) {
+ break;
+ case IOCHARSET:
  if (!value || !*value) {
  printk(KERN_WARNING "CIFS: invalid iocharset "
     "specified\n");
@@ -1365,58 +1378,72 @@ cifs_parse_mount_options(char *options, const char *devname,
     "too long.\n");
  return 1;
  }
- } else if (!strnicmp(data, "uid", 3) && value && *value) {
- vol->linux_uid = simple_strtoul(value, &value, 0);
- uid_specified = true;
- } else if (!strnicmp(data, "forceuid", 8)) {
+ break;
+ case UID:
+ if (value && *value) {
+ vol->linux_uid =
+ simple_strtoul(value, &value, 0);
+ uid_specified = true;
+ }
+ break;
+ case FORCE_UID:
  override_uid = 1;
- } else if (!strnicmp(data, "noforceuid", 10)) {
+ break;
+ case NO_FORCE_UID:
  override_uid = 0;
- } else if (!strnicmp(data, "gid", 3) && value && *value) {
- vol->linux_gid = simple_strtoul(value, &value, 0);
- gid_specified = true;
- } else if (!strnicmp(data, "forcegid", 8)) {
- override_gid = 1;
- } else if (!strnicmp(data, "noforcegid", 10)) {
- override_gid = 0;
- } else if (strnicmp(data, "file_mode", 4) == 0) {
+ break;
+ case GID:
  if (value && *value) {
- vol->file_mode =
+ vol->linux_gid =
  simple_strtoul(value, &value, 0);
+ gid_specified = true;
  }
- } else if (strnicmp(data, "dir_mode", 4) == 0) {
+ break;
+ case FORCE_GID:
+ override_gid = 1;
+ break;
+ case NO_FORCE_GID:
+ override_gid = 0;
+ break;
+ case FILEMODE:
  if (value && *value) {
- vol->dir_mode =
+ vol->file_mode =
  simple_strtoul(value, &value, 0);
  }
- } else if (strnicmp(data, "dirmode", 4) == 0) {
+ break;
+ case DIRMODE:
  if (value && *value) {
  vol->dir_mode =
  simple_strtoul(value, &value, 0);
  }
- } else if (strnicmp(data, "port", 4) == 0) {
+ break;
+ case PORT:
  if (value && *value) {
  vol->port =
  simple_strtoul(value, &value, 0);
  }
- } else if (strnicmp(data, "rsize", 5) == 0) {
+ break;
+ case RSIZE:
  if (value && *value) {
  vol->rsize =
  simple_strtoul(value, &value, 0);
  }
- } else if (strnicmp(data, "wsize", 5) == 0) {
+ break;
+ case WSIZE:
  if (value && *value) {
  vol->wsize =
  simple_strtoul(value, &value, 0);
  }
- } else if (strnicmp(data, "sockopt", 5) == 0) {
+ break;
+ case SOCKOPT:
  if (!value || !*value) {
  cERROR(1, "no socket option specified");
  continue;
  } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
  vol->sockopt_tcp_nodelay = 1;
  }
- } else if (strnicmp(data, "netbiosname", 4) == 0) {
+ break;
+ case NETBIOSNAME:
  if (!value || !*value || (*value == ' ')) {
  cFYI(1, "invalid (empty) netbiosname");
  } else {
@@ -1439,7 +1466,8 @@ cifs_parse_mount_options(char *options, const char *devname,
  printk(KERN_WARNING "CIFS: netbiosname"
  " longer than 15 truncated.\n");
  }
- } else if (strnicmp(data, "servern", 7) == 0) {
+ break;
+ case SERVERNAME:
  /* servernetbiosname specified override *SMBSERVER */
  if (!value || !*value || (*value == ' ')) {
  cFYI(1, "empty server netbiosname specified");
@@ -1466,75 +1494,76 @@ cifs_parse_mount_options(char *options, const char *devname,
  printk(KERN_WARNING "CIFS: server net"
  "biosname longer than 15 truncated.\n");
  }
- } else if (strnicmp(data, "credentials", 4) == 0) {
- /* ignore */
- } else if (strnicmp(data, "version", 3) == 0) {
- /* ignore */
- } else if (strnicmp(data, "guest", 5) == 0) {
- /* ignore */
- } else if (strnicmp(data, "rw", 2) == 0) {
- /* ignore */
- } else if (strnicmp(data, "ro", 2) == 0) {
- /* ignore */
- } else if (strnicmp(data, "noblocksend", 11) == 0) {
+ break;
+ case NO_BLOCKSEND:
  vol->noblocksnd = 1;
- } else if (strnicmp(data, "noautotune", 10) == 0) {
+ break;
+ case NO_AUTOTUNE:
  vol->noautotune = 1;
- } else if ((strnicmp(data, "suid", 4) == 0) ||
-   (strnicmp(data, "nosuid", 6) == 0) ||
-   (strnicmp(data, "exec", 4) == 0) ||
-   (strnicmp(data, "noexec", 6) == 0) ||
-   (strnicmp(data, "nodev", 5) == 0) ||
-   (strnicmp(data, "noauto", 6) == 0) ||
-   (strnicmp(data, "dev", 3) == 0)) {
- /*  The mount tool or mount.cifs helper (if present)
-    uses these opts to set flags, and the flags are read
-    by the kernel vfs layer before we get here (ie
-    before read super) so there is no point trying to
-    parse these options again and set anything and it
-    is ok to just ignore them */
- continue;
- } else if (strnicmp(data, "hard", 4) == 0) {
+ break;
+ /* HARD || NO_SOFT */
+ case HARD:
+ case NO_SOFT:
  vol->retry = 1;
- } else if (strnicmp(data, "soft", 4) == 0) {
+ break;
+ /* SOFT || NO_HARD */
+ case SOFT:
+ case NO_HARD:
  vol->retry = 0;
- } else if (strnicmp(data, "perm", 4) == 0) {
+ break;
+ case PERM:
  vol->noperm = 0;
- } else if (strnicmp(data, "noperm", 6) == 0) {
+ break;
+ case NO_PERM:
  vol->noperm = 1;
- } else if (strnicmp(data, "mapchars", 8) == 0) {
+ break;
+ case MAPCHARS:
  vol->remap = 1;
- } else if (strnicmp(data, "nomapchars", 10) == 0) {
+ break;
+ case NO_MAPCHARS:
  vol->remap = 0;
- } else if (strnicmp(data, "sfu", 3) == 0) {
+ break;
+ case SFU:
  vol->sfu_emul = 1;
- } else if (strnicmp(data, "nosfu", 5) == 0) {
+ break;
+ case NO_SFU:
  vol->sfu_emul = 0;
- } else if (strnicmp(data, "nodfs", 5) == 0) {
+ break;
+ case NO_DFS:
  vol->nodfs = 1;
- } else if (strnicmp(data, "posixpaths", 10) == 0) {
+ break;
+ case POSIXPATHS:
  vol->posix_paths = 1;
- } else if (strnicmp(data, "noposixpaths", 12) == 0) {
+ break;
+ case NO_POSIXPATHS:
  vol->posix_paths = 0;
- } else if (strnicmp(data, "nounix", 6) == 0) {
+ break;
+ case NO_UNIX:
  vol->no_linux_ext = 1;
- } else if (strnicmp(data, "nolinux", 7) == 0) {
+ break;
+ case NO_LINUX:
  vol->no_linux_ext = 1;
- } else if ((strnicmp(data, "nocase", 6) == 0) ||
-   (strnicmp(data, "ignorecase", 10)  == 0)) {
+ break;
+ /* IGNORECASE || NO_CASE */
+ case IGNORECASE:
+ case NO_CASE:
  vol->nocase = 1;
- } else if (strnicmp(data, "brl", 3) == 0) {
+ break;
+ case BRL:
  vol->nobrl =  0;
- } else if ((strnicmp(data, "nobrl", 5) == 0) ||
-   (strnicmp(data, "nolock", 6) == 0)) {
- vol->nobrl =  1;
+ break;
+ /* NO_BRL || NO_LOCK */
+ case NO_BRL:
+ case NO_LOCK:
+ vol->nobrl = 1;
  /* turn off mandatory locking in mode
  if remote locking is turned off since the
  local vfs will do advisory */
  if (vol->file_mode ==
  (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
  vol->file_mode = S_IALLUGO;
- } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
+ break;
+ case FORCE_MANDATORYLOCK:
  /* will take the shorter form "forcemand" as well */
  /* This mount option will force use of mandatory
   (DOS/Windows style) byte range locks, instead of
@@ -1545,61 +1574,98 @@ cifs_parse_mount_options(char *options, const char *devname,
   would be used (mandatory locks is all that those
   those servers support) */
  vol->mand_lock = 1;
- } else if (strnicmp(data, "setuids", 7) == 0) {
+ break;
+ case SETUIDS:
  vol->setuids = 1;
- } else if (strnicmp(data, "nosetuids", 9) == 0) {
+ break;
+ case NO_SETUIDS:
  vol->setuids = 0;
- } else if (strnicmp(data, "dynperm", 7) == 0) {
+ break;
+ case DYNPERM:
  vol->dynperm = true;
- } else if (strnicmp(data, "nodynperm", 9) == 0) {
+ break;
+ case NO_DYNPERM:
  vol->dynperm = false;
- } else if (strnicmp(data, "nohard", 6) == 0) {
- vol->retry = 0;
- } else if (strnicmp(data, "nosoft", 6) == 0) {
- vol->retry = 1;
- } else if (strnicmp(data, "nointr", 6) == 0) {
- vol->intr = 0;
- } else if (strnicmp(data, "intr", 4) == 0) {
+ break;
+ case INTR:
  vol->intr = 1;
- } else if (strnicmp(data, "nostrictsync", 12) == 0) {
- vol->nostrictsync = 1;
- } else if (strnicmp(data, "strictsync", 10) == 0) {
+ break;
+ case NO_INTR:
+ vol->intr = 0;
+ break;
+ case STRICTSYNC:
  vol->nostrictsync = 0;
- } else if (strnicmp(data, "serverino", 7) == 0) {
+ case NO_STRICTSYNC:
+ vol->nostrictsync = 1;
+ break;
+ case SERVERINO:
  vol->server_ino = 1;
- } else if (strnicmp(data, "noserverino", 9) == 0) {
+ break;
+ case NO_SERVERINO:
  vol->server_ino = 0;
- } else if (strnicmp(data, "cifsacl", 7) == 0) {
+ break;
+ case CIFSACL:
  vol->cifs_acl = 1;
- } else if (strnicmp(data, "nocifsacl", 9) == 0) {
+ break;
+ case NO_CIFSACL:
  vol->cifs_acl = 0;
- } else if (strnicmp(data, "acl", 3) == 0) {
+ break;
+ case ACL:
  vol->no_psx_acl = 0;
- } else if (strnicmp(data, "noacl", 5) == 0) {
+ break;
+ case NO_ACL:
  vol->no_psx_acl = 1;
+ break;
 #ifdef CONFIG_CIFS_EXPERIMENTAL
- } else if (strnicmp(data, "locallease", 6) == 0) {
+ case LOCALLEASE:
  vol->local_lease = 1;
+ break;
 #endif
- } else if (strnicmp(data, "sign", 4) == 0) {
+ case SIGN:
  vol->secFlg |= CIFSSEC_MUST_SIGN;
- } else if (strnicmp(data, "seal", 4) == 0) {
+ break;
+ case SEAL:
  /* we do not do the following in secFlags because seal
    is a per tree connection (mount) not a per socket
    or per-smb connection option in the protocol */
  /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
  vol->seal = 1;
- } else if (strnicmp(data, "direct", 6) == 0) {
- vol->direct_io = 1;
- } else if (strnicmp(data, "forcedirectio", 13) == 0) {
+ break;
+ /* DIRECT || FORCE_DIRECT */
+ case DIRECT:
+ case FORCE_DIRECT:
  vol->direct_io = 1;
- } else if (strnicmp(data, "noac", 4) == 0) {
+ break;
+ case NO_AC:
  printk(KERN_WARNING "CIFS: Mount option noac not "
  "supported. Instead set "
  "/proc/fs/cifs/LookupCacheEnabled to 0\n");
- } else
+ break;
+ case CIFS_TOKEN_ERROR:
  printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
  data);
+ break;
+
+ /* ignore these */
+ case CREDENTIALS:
+ case VERSION:
+ case GUEST:
+ case RW:
+ case RO:
+ /*  The mount tool or mount.cifs helper (if present) uses these
+    opts to set flags, and the flags are read by the kernel vfs
+    layer before we get here (ie before read super) so there is
+    no point trying to parse these options again and set
+    anything and it is ok to just ignore them */
+ case SUID:
+ case NO_SUID:
+ case EXEC:
+ case NO_EXEC:
+ case DEV:
+ case NO_DEV:
+ case NO_AUTO:
+ continue;
+ }
  }
  if (vol->UNC == NULL) {
  if (devname == NULL) {
--
1.6.2.5

_______________________________________________
linux-cifs-client mailing list
[hidden email]
https://lists.samba.org/mailman/listinfo/linux-cifs-client
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 1/2] connect.c: define mount options enum and parsing function

Jeff Layton-4
In reply to this post by Scott Lovenberg
On Tue, 18 May 2010 00:53:06 -0400
Scott Lovenberg <[hidden email]> wrote:

> Mount options have been defined as an enum.
> A token parsing function has been added to translate from text to the defined constants.
>
> Signed-off-by: Scott Lovenberg <[hidden email]>
> ---
>  fs/cifs/connect.c |  266 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 266 insertions(+), 0 deletions(-)
>
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 2208f06..83d5cd8 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -52,6 +52,94 @@
>  #define CIFS_PORT 445
>  #define RFC1001_PORT 139
>  
> +/* mounting option values */
> +enum CIFS_MOUNT_TOKEN {
> + CIFS_TOKEN_ERROR    =   -1,
> + USERXATTR           =   1,
> + NO_USERXATTR        =   2,
> + USER                =   3,
> + PASS                =   4,
> + IP                  =   5,
> + ADDR                =   6,
> + SEC                 =   7,
> + UNC                 =   8,
> + TARGET              =   9,
> + PATH                =  10,
> + DOMAIN              =  11,
> + WORKGROUP           =  12,
> + PREFIXPATH          =  13,
> + IOCHARSET           =  14,
> + UID                 =  15,
> + FORCE_UID           =  16,
> + NO_FORCE_UID        =  17,
> + GID                 =  18,
> + FORCE_GID           =  19,
> + NO_FORCE_GID        =  20,
> + FILEMODE            =  21,
> + DIRMODE             =  22,
> + PORT                =  23,
> + RSIZE               =  24,
> + WSIZE               =  25,
> + SOCKOPT             =  26,
> + NETBIOSNAME         =  27,
> + SERVERNAME          =  28,
> + CREDENTIALS         =  29,
> + VERSION             =  30,
> + GUEST               =  31,
> + RW                  =  32,
> + RO                  =  33,
> + NO_BLOCKSEND        =  34,
> + NO_AUTOTUNE         =  35,
> + NO_AUTO             =  36,
> + SUID                =  37,
> + NO_SUID             =  38,
> + EXEC                =  39,
> + NO_EXEC             =  40,
> + DEV                 =  41,
> + NO_DEV              =  42,
> + HARD                =  43,
> + NO_HARD             =  44,
> + SOFT                =  45,
> + NO_SOFT             =  46,
> + PERM                =  47,
> + NO_PERM             =  48,
> + MAPCHARS            =  49,
> + NO_MAPCHARS         =  50,
> + SFU                 =  51,
> + NO_SFU              =  52,
> + NO_DFS              =  53,
> + POSIXPATHS          =  54,
> + NO_POSIXPATHS       =  55,
> + NO_UNIX             =  56,
> + NO_LINUX            =  57,
> + NO_CASE             =  58,
> + IGNORECASE          =  59,
> + BRL                 =  60,
> + NO_BRL              =  61,
> + NO_LOCK             =  62,
> + FORCE_MANDATORYLOCK =  63,
> + SETUIDS             =  64,
> + NO_SETUIDS          =  65,
> + DYNPERM             =  66,
> + NO_DYNPERM          =  67,
> + INTR                =  68,
> + NO_INTR             =  69,
> + STRICTSYNC          =  70,
> + NO_STRICTSYNC       =  71,
> + SERVERINO           =  72,
> + NO_SERVERINO        =  73,
> + ACL                 =  74,
> + NO_ACL              =  75,
> + CIFSACL             =  76,
> + NO_CIFSACL          =  77,
> + LOCALLEASE          =  78,
> + SIGN                =  79,
> + SEAL                =  80,
> + DIRECT              =  81,
> + FORCE_DIRECT        =  82,
> + NO_AC               =  83
> +};
> +

^^^^
There's really no need to assign every value on an enum. You should
also probably prefix these with the semi-standard "Opt_" so that they
aren't confused with other values. This should also be static, I think.

>  extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
>   unsigned char *p24);
>  
> @@ -797,6 +885,184 @@ extract_hostname(const char *unc)
>   return dst;
>  }
>  
> +/* returns the CIFS_MOUNT_TOKEN value that represents 'option' */
> +static int cifs_parse_mount_token(const char *option)
> +{
> + if (option == NULL)
> + return CIFS_TOKEN_ERROR;
> +
> + if (strnicmp(option, "user_xattr", 10) == 0)
> + return USERXATTR;
> + if (strnicmp(option, "nouser_xattr", 12) == 0)
> + return NO_USERXATTR;
> + if (strnicmp(option, "user", 4) == 0)
> + return USER;
> + if (strnicmp(option, "pass", 4) == 0)
> + return PASS;
> + if (strnicmp(option, "ip", 2) == 0)
> + return IP;
> + if (strnicmp(option, "addr", 4) == 0)
> + return ADDR;
> + if (strnicmp(option, "sec", 3) == 0)
> + return SEC;
> + if (strnicmp(option, "unc", 3) == 0)
> + return UNC;
> + if (strnicmp(option, "target", 6) == 0)
> + return TARGET;
> + if (strnicmp(option, "path", 4) == 0)
> + return PATH;
> + if (strnicmp(option, "domain", 3) == 0)
> + return DOMAIN;
> + if (strnicmp(option, "workgroup", 5) == 0)
> + return WORKGROUP;
> + if (strnicmp(option, "prefixpath", 10) == 0)
> + return PREFIXPATH;
> + if (strnicmp(option, "iocharset", 9) == 0)
> + return IOCHARSET;
> + if (strnicmp(option, "uid", 3) == 0)
> + return UID;
> + if (strnicmp(option, "forceuid", 8) == 0)
> + return FORCE_UID;
> + if (strnicmp(option, "noforceuid", 10) == 0)
> + return NO_FORCE_UID;
> + if (strnicmp(option, "gid", 3) == 0)
> + return GID;
> + if (strnicmp(option, "forcegid", 8) == 0)
> + return FORCE_GID;
> + if (strnicmp(option, "noforcegid", 10) == 0)
> + return NO_FORCE_GID;
> + if (strnicmp(option, "file_mode", 4) == 0)
> + return FILEMODE;
> + /* dir_mode || dirmode */
> + if (strnicmp(option, "dir", 3) == 0)
> + return DIRMODE;
> + if (strnicmp(option, "port", 4) == 0)
> + return PORT;
> + if (strnicmp(option, "rsize", 5) == 0)
> + return RSIZE;
> + if (strnicmp(option, "wsize", 5) == 0)
> + return WSIZE;
> + if (strnicmp(option, "sockopt", 5) == 0)
> + return SOCKOPT;
> + if (strnicmp(option, "netbiosname", 4) == 0)
> + return NETBIOSNAME;
> + if (strnicmp(option, "servername", 7) == 0)
> + return SERVERNAME;
> + if (strnicmp(option, "credentials", 4) == 0)
> + return CREDENTIALS;
> + if (strnicmp(option, "version", 3) == 0)
> + return VERSION;
> + if (strnicmp(option, "guest", 5) == 0)
> + return GUEST;
> + if (strnicmp(option, "rw", 2) == 0)
> + return RW;
> + if (strnicmp(option, "ro", 2) == 0)
> + return RO;
> + if (strnicmp(option, "noblocksend", 11) == 0)
> + return NO_BLOCKSEND;
> + if (strnicmp(option, "noautotune", 10) == 0)
> + return NO_AUTOTUNE;
> + if (strnicmp(option, "suid", 4) == 0)
> + return SUID;
> + if (strnicmp(option, "nosuid", 6) == 0)
> + return NO_SUID;
> + if (strnicmp(option, "exec", 4) == 0)
> + return EXEC;
> + if (strnicmp(option, "noexec", 6) == 0)
> + return NO_EXEC;
> + if (strnicmp(option, "dev", 3) == 0)
> + return DEV;
> + if (strnicmp(option, "nodev", 5) == 0)
> + return NO_DEV;
> + if (strnicmp(option, "noauto", 6) == 0)
> + return NO_AUTO;
> + if (strnicmp(option, "hard", 4) == 0)
> + return HARD;
> + if (strnicmp(option, "nohard", 6) == 0)
> + return NO_HARD;
> + if (strnicmp(option, "soft", 4) == 0)
> + return SOFT;
> + if (strnicmp(option, "nosoft", 6) == 0)
> + return NO_SOFT;
> + if (strnicmp(option, "perm", 4) == 0)
> + return PERM;
> + if (strnicmp(option, "noperm", 6) == 0)
> + return NO_PERM;
> + if (strnicmp(option, "mapchars", 8) == 0)
> + return MAPCHARS;
> + if (strnicmp(option, "nomapchars", 10) == 0)
> + return NO_MAPCHARS;
> + if (strnicmp(option, "sfu", 3) == 0)
> + return SFU;
> + if (strnicmp(option, "nosfu", 5) == 0)
> + return NO_SFU;
> + if (strnicmp(option, "nodfs", 5) == 0)
> + return NO_DFS;
> + if (strnicmp(option, "posixpaths", 10) == 0)
> + return POSIXPATHS;
> + if (strnicmp(option, "noposixpaths", 12) == 0)
> + return NO_POSIXPATHS;
> + if (strnicmp(option, "nounix", 6) == 0)
> + return NO_UNIX;
> + if (strnicmp(option, "nolinux", 7) == 0)
> + return NO_LINUX;
> + if (strnicmp(option, "nocase", 6) == 0)
> + return NO_CASE;
> + if (strnicmp(option, "ignorecase", 10) == 0)
> + return IGNORECASE;
> + if (strnicmp(option, "brl", 3) == 0)
> + return BRL;
> + if (strnicmp(option, "nobrl", 5) == 0)
> + return NO_BRL;
> + if (strnicmp(option, "nolock", 6) == 0)
> + return NO_LOCK;
> + if (strnicmp(option, "forcemandatorylock", 9) == 0)
> + return FORCE_MANDATORYLOCK;
> + if (strnicmp(option, "setuids", 7) == 0)
> + return SETUIDS;
> + if (strnicmp(option, "nosetuids", 9) == 0)
> + return NO_SETUIDS;
> + if (strnicmp(option, "dynperm", 7) == 0)
> + return DYNPERM;
> + if (strnicmp(option, "nodynperm", 9) == 0)
> + return NO_DYNPERM;
> + if (strnicmp(option, "intr", 4) == 0)
> + return INTR;
> + if (strnicmp(option, "nointr", 6) == 0)
> + return NO_INTR;
> + if (strnicmp(option, "strictsync", 10) == 0)
> + return STRICTSYNC;
> + if (strnicmp(option, "nostrictsync", 12) == 0)
> + return NO_STRICTSYNC;
> + if (strnicmp(option, "serverino", 7) == 0)
> + return SERVERINO;
> + if (strnicmp(option, "noserverino", 9) == 0)
> + return NO_SERVERINO;
> + if (strnicmp(option, "cifsacl", 7) == 0)
> + return CIFSACL;
> + if (strnicmp(option, "nocifsacl", 9) == 0)
> + return NO_CIFSACL;
> + if (strnicmp(option, "acl", 3) == 0)
> + return ACL;
> + if (strnicmp(option, "noacl", 5) == 0)
> + return NO_ACL;
> + if (strnicmp(option, "locallease", 6) == 0)
> + return LOCALLEASE;
> + if (strnicmp(option, "sign", 4) == 0)
> + return SIGN;
> + if (strnicmp(option, "seal", 4) == 0)
> + return SEAL;
> + if (strnicmp(option, "direct", 6) == 0)
> + return DIRECT;
> + if (strnicmp(option, "forcedirectio", 13) == 0)
> + return FORCE_DIRECT;
> + if (strnicmp(option, "noac", 4) == 0)
> + return NO_AC;
> +
> + return CIFS_TOKEN_ERROR;
> +}
> +
> +
>  static int
>  cifs_parse_mount_options(char *options, const char *devname,
>   struct smb_vol *vol)

This looks like a step in the right direction, but I'll note that the
kernel already has a standard mount option parser. See match_token().
For an example of how it's used, you can look at the NFS code, starting
with nfs_parse_mount_options.

It would be best to move to that code if possible, though we may need
to be cognizant of the fact that some people may be using "unapproved"
abbreviations of some mount options and match_token only matches ones
that are literally specified.


--
Jeff Layton <[hidden email]>
_______________________________________________
linux-cifs-client mailing list
[hidden email]
https://lists.samba.org/mailman/listinfo/linux-cifs-client
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 1/2] connect.c: define mount options enum and parsing function

Scott Lovenberg


On Tue, May 18, 2010 at 6:17 AM, Jeff Layton <[hidden email]> wrote:

There's really no need to assign every value on an enum. You should
also probably prefix these with the semi-standard "Opt_" so that they
aren't confused with other values. This should also be static, I think.

Agreed on Opt prefix.  I only used the enum as it was the preferred way to define related constants in the kernel coding style; TBH, I'd rather just use #define'd constants.  If it's all the same, that's what I'll do.  It means I won't have to fight with keeping the alignment in vim the same as what gets emailed (those values were all aligned in the file and the patch file). :)


This looks like a step in the right direction, but I'll note that the
kernel already has a standard mount option parser. See match_token().
For an example of how it's used, you can look at the NFS code, starting
with nfs_parse_mount_options.

Aha! 

It would be best to move to that code if possible
Agreed. 
 

--
Peace and Blessings,
-Scott.


_______________________________________________
linux-cifs-client mailing list
[hidden email]
https://lists.samba.org/mailman/listinfo/linux-cifs-client
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 1/2] connect.c: define mount options enum and parsing function

Scott Lovenberg

There's really no need to assign every value on an enum. You should
also probably prefix these with the semi-standard "Opt_" so that they
aren't confused with other values. This should also be static, I think.

Agreed on Opt prefix.  I only used the enum as it was the preferred way to define related constants in the kernel coding style; TBH, I'd rather just use #define'd constants.  If it's all the same, that's what I'll do.  It means I won't have to fight with keeping the alignment in vim the same as what gets emailed (those values were all aligned in the file and the patch file). :)
 
Sorry, I just realized what you were saying about assigning in the enum.  Disregard the comment above (this is why I should have a cup of coffee before replying to email, not during).  
Unfortunately GCC throws warnings if I make the enums static.
 

For an example of how it's used, you can look at the NFS code, starting
with nfs_parse_mount_options.

Aha! 

It would be best to move to that code if possible
Agreed. 
 
 
After looking at the NFS code, I scrapped what I had and rewrote to follow the style/semantics of the NFS option parsing.  I think this patch will be more in line with what you had in mind.  
I left the value parsing as it was and used the match_token to get the current token.  I'll follow up with another patch if you'd like me to implement grabbing the value with the parser lib instead of what we've got currently.

--
Peace and Blessings,
-Scott.


_______________________________________________
linux-cifs-client mailing list
[hidden email]
https://lists.samba.org/mailman/listinfo/linux-cifs-client