Merge tag 'imx-drm-fixes-2016-05-24' of git://git.pengutronix.de/git/pza/linux into...
[deliverable/linux.git] / fs / ubifs / xattr.c
index 413d650c9476d747d1f9f52f34e93a10173e8e56..6c277eb6aef943787a1fd98e74a8ab8f57c63d4b 100644 (file)
@@ -249,42 +249,6 @@ out_free:
        return err;
 }
 
-/**
- * check_namespace - check extended attribute name-space.
- * @nm: extended attribute name
- *
- * This function makes sure the extended attribute name belongs to one of the
- * supported extended attribute name-spaces. Returns name-space index in case
- * of success and a negative error code in case of failure.
- */
-static int check_namespace(const struct qstr *nm)
-{
-       int type;
-
-       if (nm->len > UBIFS_MAX_NLEN)
-               return -ENAMETOOLONG;
-
-       if (!strncmp(nm->name, XATTR_TRUSTED_PREFIX,
-                    XATTR_TRUSTED_PREFIX_LEN)) {
-               if (nm->name[XATTR_TRUSTED_PREFIX_LEN] == '\0')
-                       return -EINVAL;
-               type = TRUSTED_XATTR;
-       } else if (!strncmp(nm->name, XATTR_USER_PREFIX,
-                                     XATTR_USER_PREFIX_LEN)) {
-               if (nm->name[XATTR_USER_PREFIX_LEN] == '\0')
-                       return -EINVAL;
-               type = USER_XATTR;
-       } else if (!strncmp(nm->name, XATTR_SECURITY_PREFIX,
-                                    XATTR_SECURITY_PREFIX_LEN)) {
-               if (nm->name[XATTR_SECURITY_PREFIX_LEN] == '\0')
-                       return -EINVAL;
-               type = SECURITY_XATTR;
-       } else
-               return -EOPNOTSUPP;
-
-       return type;
-}
-
 static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum)
 {
        struct inode *inode;
@@ -302,24 +266,23 @@ static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum)
        return ERR_PTR(-EINVAL);
 }
 
-static int setxattr(struct inode *host, const char *name, const void *value,
-                   size_t size, int flags)
+static int __ubifs_setxattr(struct inode *host, const char *name,
+                           const void *value, size_t size, int flags)
 {
        struct inode *inode;
        struct ubifs_info *c = host->i_sb->s_fs_info;
        struct qstr nm = QSTR_INIT(name, strlen(name));
        struct ubifs_dent_node *xent;
        union ubifs_key key;
-       int err, type;
+       int err;
 
        ubifs_assert(inode_is_locked(host));
 
        if (size > UBIFS_MAX_INO_DATA)
                return -ERANGE;
 
-       type = check_namespace(&nm);
-       if (type < 0)
-               return type;
+       if (nm.len > UBIFS_MAX_NLEN)
+               return -ENAMETOOLONG;
 
        xent = kmalloc(UBIFS_MAX_XENT_NODE_SZ, GFP_NOFS);
        if (!xent)
@@ -363,17 +326,8 @@ out_free:
        return err;
 }
 
-int ubifs_setxattr(struct dentry *dentry, const char *name,
-                  const void *value, size_t size, int flags)
-{
-       dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd",
-               name, d_inode(dentry)->i_ino, dentry, size);
-
-       return setxattr(d_inode(dentry), name, value, size, flags);
-}
-
-ssize_t ubifs_getxattr(struct dentry *dentry, struct inode *host,
-                      const char *name, void *buf, size_t size)
+static ssize_t __ubifs_getxattr(struct inode *host, const char *name,
+                               void *buf, size_t size)
 {
        struct inode *inode;
        struct ubifs_info *c = host->i_sb->s_fs_info;
@@ -383,12 +337,8 @@ ssize_t ubifs_getxattr(struct dentry *dentry, struct inode *host,
        union ubifs_key key;
        int err;
 
-       dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name,
-               host->i_ino, dentry, size);
-
-       err = check_namespace(&nm);
-       if (err < 0)
-               return err;
+       if (nm.len > UBIFS_MAX_NLEN)
+               return -ENAMETOOLONG;
 
        xent = kmalloc(UBIFS_MAX_XENT_NODE_SZ, GFP_NOFS);
        if (!xent)
@@ -460,8 +410,6 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 
        lowest_xent_key(c, &key, host->i_ino);
        while (1) {
-               int type;
-
                xent = ubifs_tnc_next_ent(c, &key, &nm);
                if (IS_ERR(xent)) {
                        err = PTR_ERR(xent);
@@ -471,14 +419,10 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
                nm.name = xent->name;
                nm.len = le16_to_cpu(xent->nlen);
 
-               type = check_namespace(&nm);
-               if (unlikely(type < 0)) {
-                       err = type;
-                       break;
-               }
-
                /* Show trusted namespace only for "power" users */
-               if (type != TRUSTED_XATTR || capable(CAP_SYS_ADMIN)) {
+               if (strncmp(xent->name, XATTR_TRUSTED_PREFIX,
+                           XATTR_TRUSTED_PREFIX_LEN) ||
+                   capable(CAP_SYS_ADMIN)) {
                        memcpy(buffer + written, nm.name, nm.len + 1);
                        written += nm.len + 1;
                }
@@ -538,22 +482,19 @@ out_cancel:
        return err;
 }
 
-int ubifs_removexattr(struct dentry *dentry, const char *name)
+static int __ubifs_removexattr(struct inode *host, const char *name)
 {
-       struct inode *inode, *host = d_inode(dentry);
+       struct inode *inode;
        struct ubifs_info *c = host->i_sb->s_fs_info;
        struct qstr nm = QSTR_INIT(name, strlen(name));
        struct ubifs_dent_node *xent;
        union ubifs_key key;
        int err;
 
-       dbg_gen("xattr '%s', ino %lu ('%pd')", name,
-               host->i_ino, dentry);
        ubifs_assert(inode_is_locked(host));
 
-       err = check_namespace(&nm);
-       if (err < 0)
-               return err;
+       if (nm.len > UBIFS_MAX_NLEN)
+               return -ENAMETOOLONG;
 
        xent = kmalloc(UBIFS_MAX_XENT_NODE_SZ, GFP_NOFS);
        if (!xent)
@@ -603,7 +544,7 @@ static int init_xattrs(struct inode *inode, const struct xattr *xattr_array,
                }
                strcpy(name, XATTR_SECURITY_PREFIX);
                strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
-               err = setxattr(inode, name, xattr->value, xattr->value_len, 0);
+               err = __ubifs_setxattr(inode, name, xattr->value, xattr->value_len, 0);
                kfree(name);
                if (err < 0)
                        break;
@@ -626,3 +567,53 @@ int ubifs_init_security(struct inode *dentry, struct inode *inode,
        }
        return err;
 }
+
+static int ubifs_xattr_get(const struct xattr_handler *handler,
+                          struct dentry *dentry, struct inode *inode,
+                          const char *name, void *buffer, size_t size)
+{
+       dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name,
+               inode->i_ino, dentry, size);
+
+       return  __ubifs_getxattr(inode, name, buffer, size);
+}
+
+static int ubifs_xattr_set(const struct xattr_handler *handler,
+                          struct dentry *dentry, const char *name,
+                          const void *value, size_t size, int flags)
+{
+       struct inode *inode = d_inode(dentry);
+
+       dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd",
+               name, inode->i_ino, dentry, size);
+
+       if (value)
+               return __ubifs_setxattr(inode, name, value, size, flags);
+       else
+               return __ubifs_removexattr(inode, name);
+}
+
+const struct xattr_handler ubifs_user_xattr_handler = {
+       .prefix = XATTR_USER_PREFIX,
+       .get = ubifs_xattr_get,
+       .set = ubifs_xattr_set,
+};
+
+const struct xattr_handler ubifs_trusted_xattr_handler = {
+       .prefix = XATTR_TRUSTED_PREFIX,
+       .get = ubifs_xattr_get,
+       .set = ubifs_xattr_set,
+};
+
+const struct xattr_handler ubifs_security_xattr_handler = {
+       .prefix = XATTR_SECURITY_PREFIX,
+       .get = ubifs_xattr_get,
+       .set = ubifs_xattr_set,
+};
+
+const struct xattr_handler *ubifs_xattr_handlers[] = {
+       &ubifs_user_xattr_handler,
+       &ubifs_trusted_xattr_handler,
+       &ubifs_security_xattr_handler,
+       NULL
+};
This page took 0.029466 seconds and 5 git commands to generate.