[fs/9P] Add posixacl mount option
authorVenkateswararao Jujjuri (JV) <jvrao@linux.vnet.ibm.com>
Tue, 25 Jan 2011 23:40:54 +0000 (15:40 -0800)
committerEric Van Hensbergen <ericvh@gmail.com>
Tue, 15 Mar 2011 14:57:34 +0000 (09:57 -0500)
The mount option access=client is overloaded as it assumes acl too.
Adding posixacl option to enable POSIX ACLs makes it explicit and clear.
Also it is convenient in the future to add other types of acls like richacls.

Ideally, the access mode 'client' should be just like V9FS_ACCESS_USER
except it underscores the location of access check.
Traditional 9P protocol lets the server perform access checks but with
this mode, all the access checks will be performed on the client itself.
Server just follows the client's directive.

Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
fs/9p/acl.c
fs/9p/v9fs.c
fs/9p/v9fs.h
fs/9p/vfs_super.c

index 0a2e480477a5cc78d84366869652ad385d98f289..1ee3434239c80b0be362b91a11e042e1cab970c3 100644 (file)
@@ -59,7 +59,8 @@ int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
        struct v9fs_session_info *v9ses;
 
        v9ses = v9fs_inode2v9ses(inode);
-       if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) {
+       if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) ||
+                       ((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) {
                set_cached_acl(inode, ACL_TYPE_DEFAULT, NULL);
                set_cached_acl(inode, ACL_TYPE_ACCESS, NULL);
                return 0;
@@ -104,9 +105,10 @@ int v9fs_check_acl(struct inode *inode, int mask, unsigned int flags)
                return -ECHILD;
 
        v9ses = v9fs_inode2v9ses(inode);
-       if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) {
+       if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) ||
+                       ((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) {
                /*
-                * On access = client mode get the acl
+                * On access = client  and acl = on mode get the acl
                 * values from the server
                 */
                return 0;
index d34f2937df6695ab3fd46976206ca3db239290d5..f5a3200877d69d94dd0ce1b5e60a34a415e007a1 100644 (file)
@@ -55,7 +55,7 @@ enum {
        /* Cache options */
        Opt_cache_loose, Opt_fscache,
        /* Access options */
-       Opt_access,
+       Opt_access, Opt_posixacl,
        /* Error token */
        Opt_err
 };
@@ -73,6 +73,7 @@ static const match_table_t tokens = {
        {Opt_fscache, "fscache"},
        {Opt_cachetag, "cachetag=%s"},
        {Opt_access, "access=%s"},
+       {Opt_posixacl, "posixacl"},
        {Opt_err, NULL}
 };
 
@@ -194,13 +195,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
                        else if (strcmp(s, "any") == 0)
                                v9ses->flags |= V9FS_ACCESS_ANY;
                        else if (strcmp(s, "client") == 0) {
-#ifdef CONFIG_9P_FS_POSIX_ACL
                                v9ses->flags |= V9FS_ACCESS_CLIENT;
-#else
-                               P9_DPRINTK(P9_DEBUG_ERROR,
-                                       "Not defined CONFIG_9P_FS_POSIX_ACL. "
-                                       "Ignoring access=client option\n");
-#endif
                        } else {
                                v9ses->flags |= V9FS_ACCESS_SINGLE;
                                v9ses->uid = simple_strtoul(s, &e, 10);
@@ -210,6 +205,16 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
                        kfree(s);
                        break;
 
+               case Opt_posixacl:
+#ifdef CONFIG_9P_FS_POSIX_ACL
+                       v9ses->flags |= V9FS_POSIX_ACL;
+#else
+                       P9_DPRINTK(P9_DEBUG_ERROR,
+                                       "Not defined CONFIG_9P_FS_POSIX_ACL. "
+                                       "Ignoring posixacl option\n");
+#endif
+                       break;
+
                default:
                        continue;
                }
@@ -304,6 +309,14 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
                v9ses->flags |= V9FS_ACCESS_ANY;
                v9ses->uid = ~0;
        }
+       if (!v9fs_proto_dotl(v9ses) ||
+               !((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
+               /*
+                * We support ACL checks on clinet only if the protocol is
+                * 9P2000.L and access is V9FS_ACCESS_CLIENT.
+                */
+               v9ses->flags &= ~V9FS_ACL_MASK;
+       }
 
        fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0,
                                                        v9ses->aname);
index c4b5d8864f0ddb66ee33dadec6311e42e1408663..6fa3cf5547d50db79d813d3d5c73b7baee78eddf 100644 (file)
  * @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions
  * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
  * @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
+ * @V9FS_ACCESS_CLIENT: Just like user, but access check is performed on client.
  * @V9FS_ACCESS_ANY: use a single attach for all users
  * @V9FS_ACCESS_MASK: bit mask of different ACCESS options
+ * @V9FS_POSIX_ACL: POSIX ACLs are enforced
  *
  * Session flags reflect options selected by users at mount time
  */
                         V9FS_ACCESS_USER |   \
                         V9FS_ACCESS_CLIENT)
 #define V9FS_ACCESS_MASK V9FS_ACCESS_ANY
+#define V9FS_ACL_MASK V9FS_POSIX_ACL
 
 enum p9_session_flags {
        V9FS_PROTO_2000U        = 0x01,
        V9FS_PROTO_2000L        = 0x02,
        V9FS_ACCESS_SINGLE      = 0x04,
        V9FS_ACCESS_USER        = 0x08,
-       V9FS_ACCESS_CLIENT      = 0x10
+       V9FS_ACCESS_CLIENT      = 0x10,
+       V9FS_POSIX_ACL          = 0x20
 };
 
 /* possible values of ->cache */
index dbaabe3b8131f5060d9e14ad537568f7e1ed53af..4f14be585d6cd3ecc111a3a298dfce3edc6e54e8 100644 (file)
@@ -91,7 +91,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
            MS_NOATIME;
 
 #ifdef CONFIG_9P_FS_POSIX_ACL
-       if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)
+       if ((v9ses->flags & V9FS_ACL_MASK) == V9FS_POSIX_ACL)
                sb->s_flags |= MS_POSIXACL;
 #endif