diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-10 17:11:50 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-10 17:11:50 -0700 |
| commit | 97d2116708ca0fd6ad8b00811ee4349b7e19e96f (patch) | |
| tree | 81f73fc1a6daee60737b591cf1be73cc4f79de37 /fs | |
| parent | 30066ce675d3af350bc5a53858991c0b518dda00 (diff) | |
| parent | fd50ecaddf8372a1d96e0daeaac0f93cf04e4d42 (diff) | |
| download | linux-97d2116708ca0fd6ad8b00811ee4349b7e19e96f.tar.gz linux-97d2116708ca0fd6ad8b00811ee4349b7e19e96f.tar.bz2 linux-97d2116708ca0fd6ad8b00811ee4349b7e19e96f.zip | |
Merge branch 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs xattr updates from Al Viro:
"xattr stuff from Andreas
This completes the switch to xattr_handler ->get()/->set() from
->getxattr/->setxattr/->removexattr"
* 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
vfs: Remove {get,set,remove}xattr inode operations
xattr: Stop calling {get,set,remove}xattr inode operations
vfs: Check for the IOP_XATTR flag in listxattr
xattr: Add __vfs_{get,set,remove}xattr helpers
libfs: Use IOP_XATTR flag for empty directory handling
vfs: Use IOP_XATTR flag for bad-inode handling
vfs: Add IOP_XATTR inode operations flag
vfs: Move xattr_resolve_name to the front of fs/xattr.c
ecryptfs: Switch to generic xattr handlers
sockfs: Get rid of getxattr iop
sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names
kernfs: Switch to generic xattr handlers
hfs: Switch to generic xattr handlers
jffs2: Remove jffs2_{get,set,remove}xattr macros
xattr: Remove unnecessary NULL attribute name check
Diffstat (limited to 'fs')
65 files changed, 338 insertions, 545 deletions
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 0e6ad3019711..afaa4b6de801 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -967,9 +967,6 @@ const struct inode_operations v9fs_dir_inode_operations_dotl = { .rename = v9fs_vfs_rename, .getattr = v9fs_vfs_getattr_dotl, .setattr = v9fs_vfs_setattr_dotl, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .removexattr = generic_removexattr, .listxattr = v9fs_listxattr, .get_acl = v9fs_iop_get_acl, }; @@ -977,9 +974,6 @@ const struct inode_operations v9fs_dir_inode_operations_dotl = { const struct inode_operations v9fs_file_inode_operations_dotl = { .getattr = v9fs_vfs_getattr_dotl, .setattr = v9fs_vfs_setattr_dotl, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .removexattr = generic_removexattr, .listxattr = v9fs_listxattr, .get_acl = v9fs_iop_get_acl, }; @@ -989,8 +983,5 @@ const struct inode_operations v9fs_symlink_inode_operations_dotl = { .get_link = v9fs_vfs_get_link_dotl, .getattr = v9fs_vfs_getattr_dotl, .setattr = v9fs_vfs_setattr_dotl, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .removexattr = generic_removexattr, .listxattr = v9fs_listxattr, }; diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 3ba385eaa26e..7bb153c33459 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c @@ -100,29 +100,12 @@ static int bad_inode_setattr(struct dentry *direntry, struct iattr *attrs) return -EIO; } -static int bad_inode_setxattr(struct dentry *dentry, struct inode *inode, - const char *name, const void *value, size_t size, int flags) -{ - return -EIO; -} - -static ssize_t bad_inode_getxattr(struct dentry *dentry, struct inode *inode, - const char *name, void *buffer, size_t size) -{ - return -EIO; -} - static ssize_t bad_inode_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) { return -EIO; } -static int bad_inode_removexattr(struct dentry *dentry, const char *name) -{ - return -EIO; -} - static const struct inode_operations bad_inode_ops = { .create = bad_inode_create, @@ -142,10 +125,7 @@ static const struct inode_operations bad_inode_ops = .permission = bad_inode_permission, .getattr = bad_inode_getattr, .setattr = bad_inode_setattr, - .setxattr = bad_inode_setxattr, - .getxattr = bad_inode_getxattr, .listxattr = bad_inode_listxattr, - .removexattr = bad_inode_removexattr, }; @@ -175,6 +155,7 @@ void make_bad_inode(struct inode *inode) inode->i_atime = inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); inode->i_op = &bad_inode_ops; + inode->i_opflags &= ~IOP_XATTR; inode->i_fop = &bad_file_ops; } EXPORT_SYMBOL(make_bad_inode); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a0d3016f6c26..994fe5af160b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10556,10 +10556,7 @@ static const struct inode_operations btrfs_dir_inode_operations = { .symlink = btrfs_symlink, .setattr = btrfs_setattr, .mknod = btrfs_mknod, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = btrfs_listxattr, - .removexattr = generic_removexattr, .permission = btrfs_permission, .get_acl = btrfs_get_acl, .set_acl = btrfs_set_acl, @@ -10633,10 +10630,7 @@ static const struct address_space_operations btrfs_symlink_aops = { static const struct inode_operations btrfs_file_inode_operations = { .getattr = btrfs_getattr, .setattr = btrfs_setattr, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = btrfs_listxattr, - .removexattr = generic_removexattr, .permission = btrfs_permission, .fiemap = btrfs_fiemap, .get_acl = btrfs_get_acl, @@ -10647,10 +10641,7 @@ static const struct inode_operations btrfs_special_inode_operations = { .getattr = btrfs_getattr, .setattr = btrfs_setattr, .permission = btrfs_permission, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = btrfs_listxattr, - .removexattr = generic_removexattr, .get_acl = btrfs_get_acl, .set_acl = btrfs_set_acl, .update_time = btrfs_update_time, @@ -10661,10 +10652,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { .getattr = btrfs_getattr, .setattr = btrfs_setattr, .permission = btrfs_permission, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = btrfs_listxattr, - .removexattr = generic_removexattr, .update_time = btrfs_update_time, }; diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index 6af790fc3df8..3ff867f87d73 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -20,6 +20,7 @@ #include <linux/mount.h> #include <linux/statfs.h> #include <linux/ctype.h> +#include <linux/xattr.h> #include "internal.h" static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches); @@ -126,8 +127,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) if (d_is_negative(root) || !d_backing_inode(root)->i_op->lookup || !d_backing_inode(root)->i_op->mkdir || - !d_backing_inode(root)->i_op->setxattr || - !d_backing_inode(root)->i_op->getxattr || + !(d_backing_inode(root)->i_opflags & IOP_XATTR) || !root->d_sb->s_op->statfs || !root->d_sb->s_op->sync_fs) goto error_unsupported; diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index c6ee4b5fb7e6..339c910da916 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -20,6 +20,7 @@ #include <linux/namei.h> #include <linux/security.h> #include <linux/slab.h> +#include <linux/xattr.h> #include "internal.h" #define CACHEFILES_KEYBUF_SIZE 512 @@ -799,8 +800,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, } ret = -EPERM; - if (!d_backing_inode(subdir)->i_op->setxattr || - !d_backing_inode(subdir)->i_op->getxattr || + if (!(d_backing_inode(subdir)->i_opflags & IOP_XATTR) || !d_backing_inode(subdir)->i_op->lookup || !d_backing_inode(subdir)->i_op->mkdir || !d_backing_inode(subdir)->i_op->create || diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index df4b3e6fa563..e33bd0933396 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1486,10 +1486,7 @@ const struct inode_operations ceph_dir_iops = { .permission = ceph_permission, .getattr = ceph_getattr, .setattr = ceph_setattr, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = ceph_listxattr, - .removexattr = generic_removexattr, .get_acl = ceph_get_acl, .set_acl = ceph_set_acl, .mknod = ceph_mknod, diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 082e82dcbaa4..da00b11d4a7a 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -94,10 +94,7 @@ const struct inode_operations ceph_file_iops = { .permission = ceph_permission, .setattr = ceph_setattr, .getattr = ceph_getattr, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = ceph_listxattr, - .removexattr = generic_removexattr, .get_acl = ceph_get_acl, .set_acl = ceph_set_acl, }; @@ -1885,10 +1882,7 @@ static const struct inode_operations ceph_symlink_iops = { .get_link = simple_get_link, .setattr = ceph_setattr, .getattr = ceph_getattr, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = ceph_listxattr, - .removexattr = generic_removexattr, }; int __ceph_setattr(struct inode *inode, struct iattr *attr) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 14ae4b8e1a3c..34aac1c73ee1 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -901,30 +901,21 @@ const struct inode_operations cifs_dir_inode_ops = { .setattr = cifs_setattr, .symlink = cifs_symlink, .mknod = cifs_mknod, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = cifs_listxattr, - .removexattr = generic_removexattr, }; const struct inode_operations cifs_file_inode_ops = { .setattr = cifs_setattr, .getattr = cifs_getattr, .permission = cifs_permission, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = cifs_listxattr, - .removexattr = generic_removexattr, }; const struct inode_operations cifs_symlink_inode_ops = { .readlink = generic_readlink, .get_link = cifs_get_link, .permission = cifs_permission, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = cifs_listxattr, - .removexattr = generic_removexattr, }; static int cifs_clone_file_range(struct file *src_file, loff_t off, diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 4ba1547bb9ad..599a29237cfe 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -715,4 +715,6 @@ int ecryptfs_set_f_namelen(long *namelen, long lower_namelen, int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, loff_t offset); +extern const struct xattr_handler *ecryptfs_xattr_handlers[]; + #endif /* #ifndef ECRYPTFS_KERNEL_H */ diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 5ffba186f352..ddccec3124d7 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -1005,15 +1005,14 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) { - int rc = 0; + int rc; struct dentry *lower_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); - if (!d_inode(lower_dentry)->i_op->setxattr) { + if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) { rc = -EOPNOTSUPP; goto out; } - rc = vfs_setxattr(lower_dentry, name, value, size, flags); if (!rc && inode) fsstack_copy_attr_all(inode, d_inode(lower_dentry)); @@ -1025,15 +1024,14 @@ ssize_t ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode, const char *name, void *value, size_t size) { - int rc = 0; + int rc; - if (!lower_inode->i_op->getxattr) { + if (!(lower_inode->i_opflags & IOP_XATTR)) { rc = -EOPNOTSUPP; goto out; } inode_lock(lower_inode); - rc = lower_inode->i_op->getxattr(lower_dentry, lower_inode, - name, value, size); + rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size); inode_unlock(lower_inode); out: return rc; @@ -1066,19 +1064,22 @@ out: return rc; } -static int ecryptfs_removexattr(struct dentry *dentry, const char *name) +static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode, + const char *name) { - int rc = 0; + int rc; struct dentry *lower_dentry; + struct inode *lower_inode; lower_dentry = ecryptfs_dentry_to_lower(dentry); - if (!d_inode(lower_dentry)->i_op->removexattr) { + lower_inode = ecryptfs_inode_to_lower(inode); + if (!(lower_inode->i_opflags & IOP_XATTR)) { rc = -EOPNOTSUPP; goto out; } - inode_lock(d_inode(lower_dentry)); - rc = d_inode(lower_dentry)->i_op->removexattr(lower_dentry, name); - inode_unlock(d_inode(lower_dentry)); + inode_lock(lower_inode); + rc = __vfs_removexattr(lower_dentry, name); + inode_unlock(lower_inode); out: return rc; } @@ -1089,10 +1090,7 @@ const struct inode_operations ecryptfs_symlink_iops = { .permission = ecryptfs_permission, .setattr = ecryptfs_setattr, .getattr = ecryptfs_getattr_link, - .setxattr = ecryptfs_setxattr, - .getxattr = ecryptfs_getxattr, .listxattr = ecryptfs_listxattr, - .removexattr = ecryptfs_removexattr }; const struct inode_operations ecryptfs_dir_iops = { @@ -1107,18 +1105,43 @@ const struct inode_operations ecryptfs_dir_iops = { .rename = ecryptfs_rename, .permission = ecryptfs_permission, .setattr = ecryptfs_setattr, - .setxattr = ecryptfs_setxattr, - .getxattr = ecryptfs_getxattr, .listxattr = ecryptfs_listxattr, - .removexattr = ecryptfs_removexattr }; const struct inode_operations ecryptfs_main_iops = { .permission = ecryptfs_permission, .setattr = ecryptfs_setattr, .getattr = ecryptfs_getattr, - .setxattr = ecryptfs_setxattr, - .getxattr = ecryptfs_getxattr, .listxattr = ecryptfs_listxattr, - .removexattr = ecryptfs_removexattr +}; + +static int ecryptfs_xattr_get(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *buffer, size_t size) +{ + return ecryptfs_getxattr(dentry, inode, name, buffer, size); +} + +static int ecryptfs_xattr_set(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, const void *value, size_t size, + int flags) +{ + if (value) + return ecryptfs_setxattr(dentry, inode, name, value, size, flags); + else { + BUG_ON(flags != XATTR_REPLACE); + return ecryptfs_removexattr(dentry, inode, name); + } +} + +const struct xattr_handler ecryptfs_xattr_handler = { + .prefix = "", /* match anything */ + .get = ecryptfs_xattr_get, + .set = ecryptfs_xattr_set, +}; + +const struct xattr_handler *ecryptfs_xattr_handlers[] = { + &ecryptfs_xattr_handler, + NULL }; diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 612004495141..151872dcc1f4 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -529,6 +529,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags /* ->kill_sb() will take care of sbi after that point */ sbi = NULL; s->s_op = &ecryptfs_sops; + s->s_xattr = ecryptfs_xattr_handlers; s->s_d_op = &ecryptfs_dops; err = "Reading sb failed"; diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 9c3437c8a5b1..1f0c471b4ba3 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -32,6 +32,7 @@ #include <linux/file.h> #include <linux/scatterlist.h> #include <linux/slab.h> +#include <linux/xattr.h> #include <asm/unaligned.h> #include "ecryptfs_kernel.h" @@ -422,7 +423,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) struct inode *lower_inode = d_inode(lower_dentry); int rc; - if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) { + if (!(lower_inode->i_opflags & IOP_XATTR)) { printk(KERN_WARNING "No support for setting xattr in lower filesystem\n"); rc = -ENOSYS; @@ -436,15 +437,13 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) goto out; } inode_lock(lower_inode); - size = lower_inode->i_op->getxattr(lower_dentry, lower_inode, - ECRYPTFS_XATTR_NAME, - xattr_virt, PAGE_SIZE); + size = __vfs_getxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, + xattr_virt, PAGE_SIZE); if (size < 0) size = 8; put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt); - rc = lower_inode->i_op->setxattr(lower_dentry, lower_inode, - ECRYPTFS_XATTR_NAME, - xattr_virt, size, 0); + rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, + xattr_virt, size, 0); inode_unlock(lower_inode); if (rc) printk(KERN_ERR "Error whilst attempting to write inode size " diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 0ca363d1341c..a0e1478dfd04 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -241,10 +241,7 @@ const struct file_operations ext2_file_operations = { const struct inode_operations ext2_file_inode_operations = { #ifdef CONFIG_EXT2_FS_XATTR - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = ext2_listxattr, - .removexattr = generic_removexattr, #endif .setattr = ext2_setattr, .get_acl = ext2_get_acl, diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index d446203127fc..ff32ea799496 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -428,10 +428,7 @@ const struct inode_operations ext2_dir_inode_operations = { .mknod = ext2_mknod, .rename = ext2_rename, #ifdef CONFIG_EXT2_FS_XATTR - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = ext2_listxattr, - .removexattr = generic_removexattr, #endif .setattr = ext2_setattr, .get_acl = ext2_get_acl, @@ -441,10 +438,7 @@ const struct inode_operations ext2_dir_inode_operations = { const struct inode_operations ext2_special_inode_operations = { #ifdef CONFIG_EXT2_FS_XATTR - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = ext2_listxattr, - .removexattr = generic_removexattr, #endif .setattr = ext2_setattr, .get_acl = ext2_get_acl, diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index 3495d8ae4b33..8437b191bf5d 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c @@ -25,10 +25,7 @@ const struct inode_operations ext2_symlink_inode_operations = { .get_link = page_get_link, .setattr = ext2_setattr, #ifdef CONFIG_EXT2_FS_XATTR - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = ext2_listxattr, - .removexattr = generic_removexattr, #endif }; @@ -37,9 +34,6 @@ const struct inode_operations ext2_fast_symlink_inode_operations = { .get_link = simple_get_link, .setattr = ext2_setattr, #ifdef CONFIG_EXT2_FS_XATTR - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, .listxattr = ext2_listxattr, - .removexattr = generic_removexattr, #endif }; diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 36d49cfbf2dc..2a822d30e73f 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -706,10 +706,7 @@ const struct file_operations ext4_file_operati |
