Wrapfs: support extended attributes (xattr) operations
authorErez Zadok <ezk@cs.sunysb.edu>
Thu, 26 Jun 2014 03:22:55 +0000 (23:22 -0400)
committerErez Zadok <ezk@cs.sunysb.edu>
Tue, 27 Dec 2016 03:11:38 +0000 (22:11 -0500)
Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
Signed-off-by: Mengyang Li <li.mengyang@stonybrook.edu>
fs/wrapfs/inode.c

index a2886dc4b6c1fd769cdca246896fb97c4a73a607..dfb67fc561c7a9acf9ce1e8040266bcca144b1dc 100644 (file)
@@ -486,12 +486,104 @@ out_err:
        return err;
 }
 
+static int
+wrapfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+               size_t size, int flags)
+{
+       int err; struct dentry *lower_dentry;
+       struct path lower_path;
+
+       wrapfs_get_lower_path(dentry, &lower_path);
+       lower_dentry = lower_path.dentry;
+       if (!lower_dentry->d_inode->i_op ||
+           !lower_dentry->d_inode->i_op->setxattr) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       err = lower_dentry->d_inode->i_op->setxattr(lower_dentry,
+                                                   name, value, size, flags);
+out:
+       wrapfs_put_lower_path(dentry, &lower_path);
+       return err;
+}
+
+static ssize_t
+wrapfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
+               size_t size)
+{
+       int err;
+       struct dentry *lower_dentry;
+       struct path lower_path;
+
+       wrapfs_get_lower_path(dentry, &lower_path);
+       lower_dentry = lower_path.dentry;
+       if (!lower_dentry->d_inode->i_op ||
+           !lower_dentry->d_inode->i_op->getxattr) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       err = lower_dentry->d_inode->i_op->getxattr(lower_dentry,
+                                                   name, buffer, size);
+out:
+       wrapfs_put_lower_path(dentry, &lower_path);
+       return err;
+}
+
+static ssize_t
+wrapfs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
+{
+       int err;
+       struct dentry *lower_dentry;
+       struct path lower_path;
+
+       wrapfs_get_lower_path(dentry, &lower_path);
+       lower_dentry = lower_path.dentry;
+       if (!lower_dentry->d_inode->i_op ||
+           !lower_dentry->d_inode->i_op->listxattr) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       err = lower_dentry->d_inode->i_op->listxattr(lower_dentry,
+                                                    buffer, buffer_size);
+out:
+       wrapfs_put_lower_path(dentry, &lower_path);
+       return err;
+}
+
+static int
+wrapfs_removexattr(struct dentry *dentry, const char *name)
+{
+       int err;
+       struct dentry *lower_dentry;
+       struct path lower_path;
+
+       wrapfs_get_lower_path(dentry, &lower_path);
+       lower_dentry = lower_path.dentry;
+       if (!lower_dentry->d_inode->i_op ||
+           !lower_dentry->d_inode->i_op->removexattr) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       err = lower_dentry->d_inode->i_op->removexattr(lower_dentry,
+                                                      name);
+out:
+       wrapfs_put_lower_path(dentry, &lower_path);
+       return err;
+}
 const struct inode_operations wrapfs_symlink_iops = {
        .readlink       = wrapfs_readlink,
        .permission     = wrapfs_permission,
        .follow_link    = wrapfs_follow_link,
        .setattr        = wrapfs_setattr,
        .put_link       = wrapfs_put_link,
+       .setxattr       = wrapfs_setxattr,
+       .getxattr       = wrapfs_getxattr,
+       .listxattr      = wrapfs_listxattr,
+       .removexattr    = wrapfs_removexattr,
 };
 
 const struct inode_operations wrapfs_dir_iops = {
@@ -506,9 +598,17 @@ const struct inode_operations wrapfs_dir_iops = {
        .rename         = wrapfs_rename,
        .permission     = wrapfs_permission,
        .setattr        = wrapfs_setattr,
+       .setxattr       = wrapfs_setxattr,
+       .getxattr       = wrapfs_getxattr,
+       .listxattr      = wrapfs_listxattr,
+       .removexattr    = wrapfs_removexattr,
 };
 
 const struct inode_operations wrapfs_main_iops = {
        .permission     = wrapfs_permission,
        .setattr        = wrapfs_setattr,
+       .setxattr       = wrapfs_setxattr,
+       .getxattr       = wrapfs_getxattr,
+       .listxattr      = wrapfs_listxattr,
+       .removexattr    = wrapfs_removexattr,
 };