]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ubifs/xattr.c
ubifs: Massage assert in ubifs_xattr_set() wrt. init_xattrs
[karo-tx-linux.git] / fs / ubifs / xattr.c
index 3e53fdbf7997aa64ff6ac6340e28358638f2a0e9..c13eae819cbc889ffe245dc5928278b1ccc2f4c5 100644 (file)
@@ -280,7 +280,7 @@ static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum)
 }
 
 int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
-                   size_t size, int flags)
+                   size_t size, int flags, bool check_lock)
 {
        struct inode *inode;
        struct ubifs_info *c = host->i_sb->s_fs_info;
@@ -289,12 +289,7 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
        union ubifs_key key;
        int err;
 
-       /*
-        * Creating an encryption context is done unlocked since we
-        * operate on a new inode which is not visible to other users
-        * at this point.
-        */
-       if (strcmp(name, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT) != 0)
+       if (check_lock)
                ubifs_assert(inode_is_locked(host));
 
        if (size > UBIFS_MAX_INO_DATA)
@@ -513,6 +508,28 @@ out_cancel:
        return err;
 }
 
+/**
+ * ubifs_evict_xattr_inode - Evict an xattr inode.
+ * @c: UBIFS file-system description object
+ * @xattr_inum: xattr inode number
+ *
+ * When an inode that hosts xattrs is being removed we have to make sure
+ * that cached inodes of the xattrs also get removed from the inode cache
+ * otherwise we'd waste memory. This function looks up an inode from the
+ * inode cache and clears the link counter such that iput() will evict
+ * the inode.
+ */
+void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum)
+{
+       struct inode *inode;
+
+       inode = ilookup(c->vfs_sb, xattr_inum);
+       if (inode) {
+               clear_nlink(inode);
+               iput(inode);
+       }
+}
+
 static int ubifs_xattr_remove(struct inode *host, const char *name)
 {
        struct inode *inode;
@@ -559,6 +576,7 @@ out_free:
        return err;
 }
 
+#ifdef CONFIG_UBIFS_FS_SECURITY
 static int init_xattrs(struct inode *inode, const struct xattr *xattr_array,
                      void *fs_info)
 {
@@ -575,8 +593,12 @@ 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);
+               /*
+                * creating a new inode without holding the inode rwsem,
+                * no need to check whether inode is locked.
+                */
                err = ubifs_xattr_set(inode, name, xattr->value,
-                                     xattr->value_len, 0);
+                                     xattr->value_len, 0, false);
                kfree(name);
                if (err < 0)
                        break;
@@ -599,6 +621,7 @@ int ubifs_init_security(struct inode *dentry, struct inode *inode,
        }
        return err;
 }
+#endif
 
 static int xattr_get(const struct xattr_handler *handler,
                           struct dentry *dentry, struct inode *inode,
@@ -622,7 +645,7 @@ static int xattr_set(const struct xattr_handler *handler,
        name = xattr_full_name(handler, name);
 
        if (value)
-               return ubifs_xattr_set(inode, name, value, size, flags);
+               return ubifs_xattr_set(inode, name, value, size, flags, true);
        else
                return ubifs_xattr_remove(inode, name);
 }
@@ -639,15 +662,19 @@ static const struct xattr_handler ubifs_trusted_xattr_handler = {
        .set = xattr_set,
 };
 
+#ifdef CONFIG_UBIFS_FS_SECURITY
 static const struct xattr_handler ubifs_security_xattr_handler = {
        .prefix = XATTR_SECURITY_PREFIX,
        .get = xattr_get,
        .set = xattr_set,
 };
+#endif
 
 const struct xattr_handler *ubifs_xattr_handlers[] = {
        &ubifs_user_xattr_handler,
        &ubifs_trusted_xattr_handler,
+#ifdef CONFIG_UBIFS_FS_SECURITY
        &ubifs_security_xattr_handler,
+#endif
        NULL
 };