Print this page
OS-4043 tmpfs should support gigabyte sizes
OS-4044 tmpfs should support "mode" option
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
        
*** 18,28 ****
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright (c) 2011, Joyent, Inc. All rights reserved.
   */
  
  #include <sys/types.h>
  #include <sys/param.h>
  #include <sys/sysmacros.h>
--- 18,28 ----
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright 2015 Joyent, Inc.
   */
  
  #include <sys/types.h>
  #include <sys/param.h>
  #include <sys/sysmacros.h>
*** 89,99 ****
  
  static mntopt_t tmpfs_options[] = {
          /* Option name          Cancel Opt      Arg     Flags           Data */
          { MNTOPT_XATTR,         xattr_cancel,   NULL,   MO_DEFAULT,     NULL},
          { MNTOPT_NOXATTR,       noxattr_cancel, NULL,   NULL,           NULL},
!         { "size",               NULL,           "0",    MO_HASVALUE,    NULL}
  };
  
  
  static mntopts_t tmpfs_proto_opttbl = {
          sizeof (tmpfs_options) / sizeof (mntopt_t),
--- 89,100 ----
  
  static mntopt_t tmpfs_options[] = {
          /* Option name          Cancel Opt      Arg     Flags           Data */
          { MNTOPT_XATTR,         xattr_cancel,   NULL,   MO_DEFAULT,     NULL},
          { MNTOPT_NOXATTR,       noxattr_cancel, NULL,   NULL,           NULL},
!         { "size",               NULL,           "0",    MO_HASVALUE,    NULL},
!         { "mode",               NULL,           NULL,   MO_HASVALUE,    NULL}
  };
  
  
  static mntopts_t tmpfs_proto_opttbl = {
          sizeof (tmpfs_options) / sizeof (mntopt_t),
*** 225,250 ****
          mutex_init(&tmpfs_minor_lock, NULL, MUTEX_DEFAULT, NULL);
          return (0);
  }
  
  static int
! tmp_mount(
!         struct vfs *vfsp,
!         struct vnode *mvp,
!         struct mounta *uap,
!         struct cred *cr)
  {
          struct tmount *tm = NULL;
          struct tmpnode *tp;
          struct pathname dpn;
          int error;
          pgcnt_t anonmax;
          struct vattr rattr;
          int got_attrs;
  
-         char *sizestr;
- 
          if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0)
                  return (error);
  
          if (mvp->v_type != VDIR)
                  return (ENOTDIR);
--- 226,248 ----
          mutex_init(&tmpfs_minor_lock, NULL, MUTEX_DEFAULT, NULL);
          return (0);
  }
  
  static int
! tmp_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
  {
          struct tmount *tm = NULL;
          struct tmpnode *tp;
          struct pathname dpn;
          int error;
          pgcnt_t anonmax;
          struct vattr rattr;
          int got_attrs;
+         boolean_t mode_arg = B_FALSE;
+         mode_t root_mode = 0777;
+         char *argstr;
  
          if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0)
                  return (error);
  
          if (mvp->v_type != VDIR)
                  return (ENOTDIR);
*** 274,290 ****
  
          /*
           * tm_anonmax is set according to the mount arguments
           * if any.  Otherwise, it is set to a maximum value.
           */
!         if (vfs_optionisset(vfsp, "size", &sizestr)) {
!                 if ((error = tmp_convnum(sizestr, &anonmax)) != 0)
                          goto out;
          } else {
                  anonmax = ULONG_MAX;
          }
  
          if (error = pn_get(uap->dir,
              (uap->flags & MS_SYSSPACE) ? UIO_SYSSPACE : UIO_USERSPACE, &dpn))
                  goto out;
  
          if (uap->flags & MS_REMOUNT) {
--- 272,299 ----
  
          /*
           * tm_anonmax is set according to the mount arguments
           * if any.  Otherwise, it is set to a maximum value.
           */
!         if (vfs_optionisset(vfsp, "size", &argstr)) {
!                 if ((error = tmp_convnum(argstr, &anonmax)) != 0)
                          goto out;
          } else {
                  anonmax = ULONG_MAX;
          }
  
+         /*
+          * The "mode" mount argument allows the operator to override the
+          * permissions of the root of the tmpfs mount.
+          */
+         if (vfs_optionisset(vfsp, "mode", &argstr)) {
+                 if ((error = tmp_convmode(argstr, &root_mode)) != 0) {
+                         goto out;
+                 }
+                 mode_arg = B_TRUE;
+         }
+ 
          if (error = pn_get(uap->dir,
              (uap->flags & MS_SYSSPACE) ? UIO_SYSSPACE : UIO_USERSPACE, &dpn))
                  goto out;
  
          if (uap->flags & MS_REMOUNT) {
*** 339,349 ****
  
          /*
           * allocate and initialize root tmpnode structure
           */
          bzero(&rattr, sizeof (struct vattr));
!         rattr.va_mode = (mode_t)(S_IFDIR | 0777);       /* XXX modes */
          rattr.va_type = VDIR;
          rattr.va_rdev = 0;
          tp = tmp_memalloc(sizeof (struct tmpnode), TMP_MUSTHAVE);
          tmpnode_init(tm, tp, &rattr, cr);
  
--- 348,358 ----
  
          /*
           * allocate and initialize root tmpnode structure
           */
          bzero(&rattr, sizeof (struct vattr));
!         rattr.va_mode = (mode_t)(S_IFDIR | root_mode);
          rattr.va_type = VDIR;
          rattr.va_rdev = 0;
          tp = tmp_memalloc(sizeof (struct tmpnode), TMP_MUSTHAVE);
          tmpnode_init(tm, tp, &rattr, cr);
  
*** 359,369 ****
--- 368,385 ----
          /*
           * If the getattr succeeded, use its results.  Otherwise allow
           * the previously set hardwired defaults to prevail.
           */
          if (got_attrs == 0) {
+                 if (!mode_arg) {
+                         /*
+                          * Only use the underlying mount point for the
+                          * mode if the "mode" mount argument was not
+                          * provided.
+                          */
                          tp->tn_mode = rattr.va_mode;
+                 }
                  tp->tn_uid = rattr.va_uid;
                  tp->tn_gid = rattr.va_gid;
          }
  
          /*