From 423e0ab086ad8b33626e45fa94ac7613146b7ffa Mon Sep 17 00:00:00 2001 From: Tim Chen Date: Tue, 19 Jul 2011 09:32:38 -0700 Subject: VFS : mount lock scalability for internal mounts For a number of file systems that don't have a mount point (e.g. sockfs and pipefs), they are not marked as long term. Therefore in mntput_no_expire, all locks in vfs_mount lock are taken instead of just local cpu's lock to aggregate reference counts when we release reference to file objects. In fact, only local lock need to have been taken to update ref counts as these file systems are in no danger of going away until we are ready to unregister them. The attached patch marks file systems using kern_mount without mount point as long term. The contentions of vfs_mount lock is now eliminated. Before un-registering such file system, kern_unmount should be called to remove the long term flag and make the mount point ready to be freed. Signed-off-by: Tim Chen Signed-off-by: Al Viro --- drivers/mtd/mtdchar.c | 2 +- fs/anon_inodes.c | 2 +- fs/hugetlbfs/inode.c | 1 + fs/namespace.c | 21 ++++++++++++++++++++- fs/pipe.c | 2 +- include/linux/fs.h | 1 + security/selinux/selinuxfs.c | 1 + 7 files changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 3f92731a5b9..f1af2228a1b 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -1192,7 +1192,7 @@ err_unregister_chdev: static void __exit cleanup_mtdchar(void) { unregister_mtd_user(&mtdchar_notifier); - mntput(mtd_inode_mnt); + kern_unmount(mtd_inode_mnt); unregister_filesystem(&mtd_inodefs_type); __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd"); } diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index c5567cb7843..4d433d34736 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -233,7 +233,7 @@ static int __init anon_inode_init(void) return 0; err_mntput: - mntput(anon_inode_mnt); + kern_unmount(anon_inode_mnt); err_unregister_filesystem: unregister_filesystem(&anon_inode_fs_type); err_exit: diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 7aafeb8fa30..0b686cec997 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -1030,6 +1030,7 @@ static int __init init_hugetlbfs_fs(void) static void __exit exit_hugetlbfs_fs(void) { kmem_cache_destroy(hugetlbfs_inode_cachep); + kern_unmount(hugetlbfs_vfsmount); unregister_filesystem(&hugetlbfs_fs_type); bdi_destroy(&hugetlbfs_backing_dev_info); } diff --git a/fs/namespace.c b/fs/namespace.c index cda50fe9250..22bfe8273c6 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2721,6 +2721,25 @@ EXPORT_SYMBOL(put_mnt_ns); struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) { - return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); + struct vfsmount *mnt; + mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); + if (!IS_ERR(mnt)) { + /* + * it is a longterm mount, don't release mnt until + * we unmount before file sys is unregistered + */ + mnt_make_longterm(mnt); + } + return mnt; } EXPORT_SYMBOL_GPL(kern_mount_data); + +void kern_unmount(struct vfsmount *mnt) +{ + /* release long term mount so mount point can be released */ + if (!IS_ERR_OR_NULL(mnt)) { + mnt_make_shortterm(mnt); + mntput(mnt); + } +} +EXPORT_SYMBOL(kern_unmount); diff --git a/fs/pipe.c b/fs/pipe.c index da42f7db50d..1b7f9af67cc 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1291,8 +1291,8 @@ static int __init init_pipe_fs(void) static void __exit exit_pipe_fs(void) { + kern_unmount(pipe_mnt); unregister_filesystem(&pipe_fs_type); - mntput(pipe_mnt); } fs_initcall(init_pipe_fs); diff --git a/include/linux/fs.h b/include/linux/fs.h index b224dc468a2..7a757a48a5c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1885,6 +1885,7 @@ extern int register_filesystem(struct file_system_type *); extern int unregister_filesystem(struct file_system_type *); extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data); #define kern_mount(type) kern_mount_data(type, NULL) +extern void kern_unmount(struct vfsmount *mnt); extern int may_umount_tree(struct vfsmount *); extern int may_umount(struct vfsmount *); extern long do_mount(char *, char *, char *, unsigned long, void *); diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 35459340019..de7900ef53d 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -1984,6 +1984,7 @@ __initcall(init_sel_fs); void exit_sel_fs(void) { kobject_put(selinuxfs_kobj); + kern_unmount(selinuxfs_mount); unregister_filesystem(&sel_fs_type); } #endif -- cgit v1.2.3-70-g09d2 From c0d960f038bdfe0fa73c9f698ba836ed20b672c9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jul 2011 00:22:31 -0400 Subject: ocfs2_init_acl(): fix a leak Signed-off-by: Al Viro --- fs/ocfs2/acl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index 1cee970eb55..f4cf451ce6e 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -409,6 +409,7 @@ int ocfs2_init_acl(handle_t *handle, if (ret2) { mlog_errno(ret2); ret = ret2; + posix_acl_release(clone); goto cleanup; } if (ret > 0) { -- cgit v1.2.3-70-g09d2 From 1ec95bf34d976b38897d1977b155a544d77b05e7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jul 2011 02:28:13 -0400 Subject: 9p: close ACL leaks Signed-off-by: Al Viro --- fs/9p/acl.c | 22 +++++++++++++--------- fs/9p/acl.h | 6 +++--- fs/9p/vfs_inode_dotl.c | 9 ++++++--- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/fs/9p/acl.c b/fs/9p/acl.c index e98f56d3787..7350f53f3b5 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c @@ -185,12 +185,15 @@ int v9fs_acl_chmod(struct dentry *dentry) } int v9fs_set_create_acl(struct dentry *dentry, - struct posix_acl *dpacl, struct posix_acl *pacl) + struct posix_acl **dpacl, struct posix_acl **pacl) { - v9fs_set_acl(dentry, ACL_TYPE_DEFAULT, dpacl); - v9fs_set_acl(dentry, ACL_TYPE_ACCESS, pacl); - posix_acl_release(dpacl); - posix_acl_release(pacl); + if (dentry) { + v9fs_set_acl(dentry, ACL_TYPE_DEFAULT, *dpacl); + v9fs_set_acl(dentry, ACL_TYPE_ACCESS, *pacl); + } + posix_acl_release(*dpacl); + posix_acl_release(*pacl); + *dpacl = *pacl = NULL; return 0; } @@ -212,11 +215,11 @@ int v9fs_acl_mode(struct inode *dir, mode_t *modep, struct posix_acl *clone; if (S_ISDIR(mode)) - *dpacl = acl; + *dpacl = posix_acl_dup(acl); clone = posix_acl_clone(acl, GFP_NOFS); - retval = -ENOMEM; + posix_acl_release(acl); if (!clone) - goto cleanup; + return -ENOMEM; retval = posix_acl_create_masq(clone, &mode); if (retval < 0) { @@ -225,11 +228,12 @@ int v9fs_acl_mode(struct inode *dir, mode_t *modep, } if (retval > 0) *pacl = clone; + else + posix_acl_release(clone); } *modep = mode; return 0; cleanup: - posix_acl_release(acl); return retval; } diff --git a/fs/9p/acl.h b/fs/9p/acl.h index 59e18c2e8c7..3eba10f3af1 100644 --- a/fs/9p/acl.h +++ b/fs/9p/acl.h @@ -19,7 +19,7 @@ extern int v9fs_get_acl(struct inode *, struct p9_fid *); extern int v9fs_check_acl(struct inode *inode, int mask); extern int v9fs_acl_chmod(struct dentry *); extern int v9fs_set_create_acl(struct dentry *, - struct posix_acl *, struct posix_acl *); + struct posix_acl **, struct posix_acl **); extern int v9fs_acl_mode(struct inode *dir, mode_t *modep, struct posix_acl **dpacl, struct posix_acl **pacl); #else @@ -33,8 +33,8 @@ static inline int v9fs_acl_chmod(struct dentry *dentry) return 0; } static inline int v9fs_set_create_acl(struct dentry *dentry, - struct posix_acl *dpacl, - struct posix_acl *pacl) + struct posix_acl **dpacl, + struct posix_acl **pacl) { return 0; } diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 32bbbe5aa68..803f59ff2fa 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -242,7 +242,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, goto error; /* Now set the ACL based on the default value */ - v9fs_set_create_acl(dentry, dacl, pacl); + v9fs_set_create_acl(dentry, &dacl, &pacl); v9inode = V9FS_I(inode); mutex_lock(&v9inode->v_mutex); @@ -283,6 +283,7 @@ error: err_clunk_old_fid: if (ofid) p9_client_clunk(ofid); + v9fs_set_create_acl(NULL, &dacl, &pacl); return err; } @@ -376,12 +377,13 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, d_instantiate(dentry, inode); } /* Now set the ACL based on the default value */ - v9fs_set_create_acl(dentry, dacl, pacl); + v9fs_set_create_acl(dentry, &dacl, &pacl); inc_nlink(dir); v9fs_invalidate_inode_attr(dir); error: if (fid) p9_client_clunk(fid); + v9fs_set_create_acl(NULL, &dacl, &pacl); return err; } @@ -781,10 +783,11 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode, d_instantiate(dentry, inode); } /* Now set the ACL based on the default value */ - v9fs_set_create_acl(dentry, dacl, pacl); + v9fs_set_create_acl(dentry, &dacl, &pacl); error: if (fid) p9_client_clunk(fid); + v9fs_set_create_acl(NULL, &dacl, &pacl); return err; } -- cgit v1.2.3-70-g09d2 From 963945bf93e46b9bf71a07bf9c78183e0f57733a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jul 2011 18:18:58 -0400 Subject: fix jffs2 ACLs on big-endian with 16bit mode_t casting int * to mode_t * is not a good thing - on a *lot* of big-endian architectures mode_t happens to be smaller than int and there it breaks quite spectaculary... Fucked-up-by: commit cfc8dc6f6f69ede939e09c2af06a01adee577285 Signed-off-by: Al Viro --- fs/jffs2/acl.c | 4 ++-- fs/jffs2/acl.h | 2 +- fs/jffs2/fs.c | 2 +- fs/jffs2/os-linux.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 3675b3cdee8..f9c302430aa 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -278,7 +278,7 @@ int jffs2_check_acl(struct inode *inode, int mask) return -EAGAIN; } -int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) +int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, mode_t *i_mode) { struct posix_acl *acl, *clone; int rc; @@ -301,7 +301,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) clone = posix_acl_clone(acl, GFP_KERNEL); if (!clone) return -ENOMEM; - rc = posix_acl_create_masq(clone, (mode_t *)i_mode); + rc = posix_acl_create_masq(clone, i_mode); if (rc < 0) { posix_acl_release(clone); return rc; diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h index 5e42de8d954..9973073b9c4 100644 --- a/fs/jffs2/acl.h +++ b/fs/jffs2/acl.h @@ -28,7 +28,7 @@ struct jffs2_acl_header { extern int jffs2_check_acl(struct inode *, int); extern int jffs2_acl_chmod(struct inode *); -extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); +extern int jffs2_init_acl_pre(struct inode *, struct inode *, mode_t *); extern int jffs2_init_acl_post(struct inode *); extern const struct xattr_handler jffs2_acl_access_xattr_handler; diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 46ad619b612..eeead33d8ef 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -406,7 +406,7 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data) /* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, fill in the raw_inode while you're at it. */ -struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri) +struct inode *jffs2_new_inode (struct inode *dir_i, mode_t mode, struct jffs2_raw_inode *ri) { struct inode *inode; struct super_block *sb = dir_i->i_sb; diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 9c252835e8e..526979c607b 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h @@ -173,7 +173,7 @@ int jffs2_do_setattr (struct inode *, struct iattr *); struct inode *jffs2_iget(struct super_block *, unsigned long); void jffs2_evict_inode (struct inode *); void jffs2_dirty_inode(struct inode *inode, int flags); -struct inode *jffs2_new_inode (struct inode *dir_i, int mode, +struct inode *jffs2_new_inode (struct inode *dir_i, mode_t mode, struct jffs2_raw_inode *ri); int jffs2_statfs (struct dentry *, struct kstatfs *); int jffs2_remount_fs (struct super_block *, int *, char *); -- cgit v1.2.3-70-g09d2 From e772aed369779c98f44e83ccd7fb1b713953cd09 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jul 2011 20:59:40 -0400 Subject: asus-wmi: ->is_visible() can't return negative It's mode_t; return 0 (no access) on error. Signed-off-by: Al Viro --- drivers/platform/x86/asus-wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 3c7857c71a2..65b66aa44c7 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -857,7 +857,7 @@ static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, int err = asus_wmi_get_devstate(asus, dev_id, &value); if (err < 0) - return err; + return 0; /* can't return negative here */ } if (dev_id == ASUS_WMI_DEVID_FAN_CTRL) { -- cgit v1.2.3-70-g09d2 From e55d92b92d240189241c22bfdfc885d4225a4d61 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 24 Jul 2011 02:07:46 -0400 Subject: get rid of create_proc_entry() abuses - proc_mkdir() is there for purpose Signed-off-by: Al Viro --- arch/arm/mach-bcmring/dma.c | 2 +- drivers/staging/rtl8187se/r8180_core.c | 2 +- drivers/staging/rtl8192e/ieee80211/ieee80211_module.c | 2 +- drivers/staging/rtl8192e/r8192E_core.c | 6 ++---- drivers/staging/rtl8192u/ieee80211/ieee80211_module.c | 2 +- drivers/staging/rtl8192u/r8192U_core.c | 6 ++---- sound/core/info.c | 2 +- 7 files changed, 9 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c index d87ad30dda3..9f2a948e0e7 100644 --- a/arch/arm/mach-bcmring/dma.c +++ b/arch/arm/mach-bcmring/dma.c @@ -835,7 +835,7 @@ int dma_init(void) /* Create /proc/dma/channels and /proc/dma/devices */ - gDmaDir = create_proc_entry("dma", S_IFDIR | S_IRUGO | S_IXUGO, NULL); + gDmaDir = proc_mkdir("dma", NULL); if (gDmaDir == NULL) { printk(KERN_ERR "Unable to create /proc/dma\n"); diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index bae7d85fe83..4c6651aac30 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -307,7 +307,7 @@ static int proc_get_stats_tx(char *page, char **start, void rtl8180_proc_module_init(void) { DMESG("Initializing proc filesystem"); - rtl8180_proc = create_proc_entry(RTL8180_MODULE_NAME, S_IFDIR, init_net.proc_net); + rtl8180_proc = proc_mkdir(RTL8180_MODULE_NAME, init_net.proc_net); } void rtl8180_proc_module_remove(void) diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c index 663b0b8e109..c2901b50dbf 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c @@ -311,7 +311,7 @@ int __init ieee80211_rtl_init(void) } ieee80211_debug_level = debug; - ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net); + ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net); if (ieee80211_proc == NULL) { IEEE80211_ERROR("Unable to create " DRV_NAME " proc directory\n"); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 19a9a07224a..8550794c6b9 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -508,7 +508,7 @@ static int proc_get_stats_rx(char *page, char **start, static void rtl8192_proc_module_init(void) { RT_TRACE(COMP_INIT, "Initializing proc filesystem\n"); - rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net); + rtl8192_proc = proc_mkdir(RTL819xE_MODULE_NAME, init_net.proc_net); } @@ -540,9 +540,7 @@ static void rtl8192_proc_init_one(struct r8192_priv *priv) struct net_device *dev = priv->ieee80211->dev; struct proc_dir_entry *e; - priv->dir_dev = create_proc_entry(dev->name, - S_IFDIR | S_IRUGO | S_IXUGO, - rtl8192_proc); + priv->dir_dev = proc_mkdir(dev->name, rtl8192_proc); if (!priv->dir_dev) { RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n", dev->name); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index fe978f359f9..d315b256b7a 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -283,7 +283,7 @@ int __init ieee80211_debug_init(void) ieee80211_debug_level = debug; - ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net); + ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net); if (ieee80211_proc == NULL) { IEEE80211_ERROR("Unable to create " DRV_NAME " proc directory\n"); diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index e81b8ab6aa9..6a1b5c17902 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -671,7 +671,7 @@ static int proc_get_stats_rx(char *page, char **start, void rtl8192_proc_module_init(void) { RT_TRACE(COMP_INIT, "Initializing proc filesystem"); - rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net); + rtl8192_proc = proc_mkdir(RTL819xU_MODULE_NAME, init_net.proc_net); } @@ -706,9 +706,7 @@ void rtl8192_proc_init_one(struct net_device *dev) { struct proc_dir_entry *e; struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - priv->dir_dev = create_proc_entry(dev->name, - S_IFDIR | S_IRUGO | S_IXUGO, - rtl8192_proc); + priv->dir_dev = proc_mkdir(dev->name, rtl8192_proc); if (!priv->dir_dev) { RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n", dev->name); diff --git a/sound/core/info.c b/sound/core/info.c index 7077f601da5..601f0ebb677 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -531,7 +531,7 @@ int __init snd_info_init(void) { struct proc_dir_entry *p; - p = create_proc_entry("asound", S_IFDIR | S_IRUGO | S_IXUGO, NULL); + p = proc_mkdir("asound", NULL); if (p == NULL) return -ENOMEM; snd_proc_root = p; -- cgit v1.2.3-70-g09d2 From eda65cc6ce2a45dc01c233e301e59cd7a0f763ad Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 24 Jul 2011 04:32:53 -0400 Subject: caam: don't pass bogus S_IFCHR to debugfs_create_...() it will be replaced with S_IFREG anyway Signed-off-by: Al Viro --- drivers/crypto/caam/ctrl.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 9009713a3c2..5433c304ac5 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -164,52 +164,52 @@ static int caam_probe(struct platform_device *pdev) /* Controller-level - performance monitor counters */ ctrlpriv->ctl_rq_dequeued = debugfs_create_u64("rq_dequeued", - S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &perfmon->req_dequeued); ctrlpriv->ctl_ob_enc_req = debugfs_create_u64("ob_rq_encrypted", - S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &perfmon->ob_enc_req); ctrlpriv->ctl_ib_dec_req = debugfs_create_u64("ib_rq_decrypted", - S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &perfmon->ib_dec_req); ctrlpriv->ctl_ob_enc_bytes = debugfs_create_u64("ob_bytes_encrypted", - S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &perfmon->ob_enc_bytes); ctrlpriv->ctl_ob_prot_bytes = debugfs_create_u64("ob_bytes_protected", - S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &perfmon->ob_prot_bytes); ctrlpriv->ctl_ib_dec_bytes = debugfs_create_u64("ib_bytes_decrypted", - S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &perfmon->ib_dec_bytes); ctrlpriv->ctl_ib_valid_bytes = debugfs_create_u64("ib_bytes_validated", - S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &perfmon->ib_valid_bytes); /* Controller level - global status values */ ctrlpriv->ctl_faultaddr = debugfs_create_u64("fault_addr", - S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &perfmon->faultaddr); ctrlpriv->ctl_faultdetail = debugfs_create_u32("fault_detail", - S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &perfmon->faultdetail); ctrlpriv->ctl_faultstatus = debugfs_create_u32("fault_status", - S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &perfmon->status); /* Internal covering keys (useful in non-secure mode only) */ ctrlpriv->ctl_kek_wrap.data = &ctrlpriv->ctrl->kek[0]; ctrlpriv->ctl_kek_wrap.size = KEK_KEY_SIZE * sizeof(u32); ctrlpriv->ctl_kek = debugfs_create_blob("kek", - S_IFCHR | S_IRUSR | + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &ctrlpriv->ctl_kek_wrap); @@ -217,7 +217,7 @@ static int caam_probe(struct platform_device *pdev) ctrlpriv->ctl_tkek_wrap.data = &ctrlpriv->ctrl->tkek[0]; ctrlpriv->ctl_tkek_wrap.size = KEK_KEY_SIZE * sizeof(u32); ctrlpriv->ctl_tkek = debugfs_create_blob("tkek", - S_IFCHR | S_IRUSR | + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &ctrlpriv->ctl_tkek_wrap); @@ -225,7 +225,7 @@ static int caam_probe(struct platform_device *pdev) ctrlpriv->ctl_tdsk_wrap.data = &ctrlpriv->ctrl->tdsk[0]; ctrlpriv->ctl_tdsk_wrap.size = KEK_KEY_SIZE * sizeof(u32); ctrlpriv->ctl_tdsk = debugfs_create_blob("tdsk", - S_IFCHR | S_IRUSR | + S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, &ctrlpriv->ctl_tdsk_wrap); -- cgit v1.2.3-70-g09d2 From e13889bab3c6b5c839075086d28fe05f71984dda Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 25 Jul 2011 14:15:50 -0400 Subject: fix devtmpfs race After we's done complete(&req->done), there's nothing to prevent the scope containing *req from being gone and *req overwritten by any kind of junk. So we must read req->next before that... Signed-off-by: Al Viro --- drivers/base/devtmpfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 6d678c99512..b89fffc1d77 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -406,9 +406,10 @@ static int devtmpfsd(void *p) requests = NULL; spin_unlock(&req_lock); while (req) { + struct req *next = req->next; req->err = handle(req->name, req->mode, req->dev); complete(&req->done); - req = req->next; + req = next; } spin_lock(&req_lock); } -- cgit v1.2.3-70-g09d2 From 340a0a01b9675a16201cc4fc4a210eb5b3bc11ce Mon Sep 17 00:00:00 2001 From: Markus Trippelsdorf Date: Sun, 24 Jul 2011 14:03:30 +0200 Subject: xfs: Fix wrong return value of xfs_file_aio_write The fsync prototype change commit 02c24a82187d accidentally overwrote the ssize_t return value of xfs_file_aio_write with 0 for SYNC type writes. Fix this by checking if an error occured when calling xfs_file_fsync and only change the return value in this case. In addition xfs_file_fsync actually returns a normal negative error, so fix this, too. Signed-off-by: Markus Trippelsdorf Reviewed-by: Christoph Hellwig Tested-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/xfs/linux-2.6/xfs_file.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index cca00f49e09..825390e1c13 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -881,11 +881,14 @@ xfs_file_aio_write( /* Handle various SYNC-type writes */ if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { loff_t end = pos + ret - 1; + int error; xfs_rw_iunlock(ip, iolock); - ret = -xfs_file_fsync(file, pos, end, + error = xfs_file_fsync(file, pos, end, (file->f_flags & __O_SYNC) ? 0 : 1); xfs_rw_ilock(ip, iolock); + if (error) + ret = error; } out_unlock: -- cgit v1.2.3-70-g09d2 From 3ca30d40a91fb9b9871e61d5dea2c1a895906a15 Mon Sep 17 00:00:00 2001 From: Pavel Shilovsky Date: Mon, 25 Jul 2011 17:59:10 +0400 Subject: CIFS: Fix oops while mounting with prefixpath commit fec11dd9a0109fe52fd631e5c510778d6cbff6cc caused a regression when we have already mounted //server/share/a and want to mount //server/share/a/b. The problem is that lookup_one_len calls __lookup_hash with nd pointer as NULL. Then __lookup_hash calls do_revalidate in the case when dentry exists and we end up with NULL pointer deference in cifs_d_revalidate: if (nd->flags & LOOKUP_RCU) return -ECHILD; Fix this by checking nd for NULL. Signed-off-by: Pavel Shilovsky Signed-off-by: Al Viro --- fs/cifs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 14d602f178c..499f27fc857 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -641,7 +641,7 @@ lookup_out: static int cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) { - if (nd->flags & LOOKUP_RCU) + if (nd && (nd->flags & LOOKUP_RCU)) return -ECHILD; if (direntry->d_inode) { -- cgit v1.2.3-70-g09d2 From e77819e57f0817c6dc7cadd061acd70c604cbce2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 22 Jul 2011 19:30:19 -0700 Subject: vfs: move ACL cache lookup into generic code This moves logic for checking the cached ACL values from low-level filesystems into generic code. The end result is a streamlined ACL check that doesn't need to load the inode->i_op->check_acl pointer at all for the common cached case. The filesystems also don't need to check for a non-blocking RCU walk case in their acl_check() functions, because that is all handled at a VFS layer. Signed-off-by: Linus Torvalds Signed-off-by: Al Viro --- fs/9p/acl.c | 3 --- fs/btrfs/acl.c | 19 +++++++---------- fs/ext2/acl.c | 6 ------ fs/ext3/acl.c | 6 ------ fs/ext4/acl.c | 6 ------ fs/generic_acl.c | 19 +++++++---------- fs/gfs2/acl.c | 6 ------ fs/jffs2/acl.c | 3 --- fs/jfs/acl.c | 3 --- fs/namei.c | 52 +++++++++++++++++++++++++++++++++++++++++++--- fs/ocfs2/acl.c | 3 --- fs/xfs/linux-2.6/xfs_acl.c | 8 ++----- 12 files changed, 65 insertions(+), 69 deletions(-) diff --git a/fs/9p/acl.c b/fs/9p/acl.c index 7350f53f3b5..8be87857605 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c @@ -101,9 +101,6 @@ int v9fs_check_acl(struct inode *inode, int mask) struct posix_acl *acl; struct v9fs_session_info *v9ses; - if (mask & MAY_NOT_BLOCK) - return -ECHILD; - v9ses = v9fs_inode2v9ses(inode); if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) || ((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) { diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 9f62ab2a728..c13ea9fbf36 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -198,19 +198,14 @@ out: int btrfs_check_acl(struct inode *inode, int mask) { int error = -EAGAIN; + struct posix_acl *acl; - if (mask & MAY_NOT_BLOCK) { - if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) - error = -ECHILD; - } else { - struct posix_acl *acl; - acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - } + acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl) { + error = posix_acl_permission(inode, acl, mask); + posix_acl_release(acl); } return error; diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index bfe651f9ae1..ced1c478ebd 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -236,12 +236,6 @@ ext2_check_acl(struct inode *inode, int mask) { struct posix_acl *acl; - if (mask & MAY_NOT_BLOCK) { - if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) - return -ECHILD; - return -EAGAIN; - } - acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index edfeb293d4c..5326038e853 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -244,12 +244,6 @@ ext3_check_acl(struct inode *inode, int mask) { struct posix_acl *acl; - if (mask & MAY_NOT_BLOCK) { - if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) - return -ECHILD; - return -EAGAIN; - } - acl = ext3_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 60d900fcc3d..4cd9e2e4085 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -242,12 +242,6 @@ ext4_check_acl(struct inode *inode, int mask) { struct posix_acl *acl; - if (mask & MAY_NOT_BLOCK) { - if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) - return -ECHILD; - return -EAGAIN; - } - acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); diff --git a/fs/generic_acl.c b/fs/generic_acl.c index 70e90b4974c..4949473d354 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c @@ -192,18 +192,13 @@ generic_acl_chmod(struct inode *inode) int generic_check_acl(struct inode *inode, int mask) { - if (mask & MAY_NOT_BLOCK) { - if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) - return -ECHILD; - } else { - struct posix_acl *acl; - - acl = get_cached_acl(inode, ACL_TYPE_ACCESS); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } + struct posix_acl *acl; + + acl = get_cached_acl(inode, ACL_TYPE_ACCESS); + if (acl) { + int error = posix_acl_permission(inode, acl, mask); + posix_acl_release(acl); + return error; } return -EAGAIN; } diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 8ef1079f166..48171f4c943 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c @@ -80,12 +80,6 @@ int gfs2_check_acl(struct inode *inode, int mask) struct posix_acl *acl; int error; - if (mask & MAY_NOT_BLOCK) { - if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) - return -ECHILD; - return -EAGAIN; - } - acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index f9c302430aa..4933a8f8ecc 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -264,9 +264,6 @@ int jffs2_check_acl(struct inode *inode, int mask) struct posix_acl *acl; int rc; - if (mask & MAY_NOT_BLOCK) - return -ECHILD; - acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 8a0a0666d5a..ead200eef5e 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -118,9 +118,6 @@ int jfs_check_acl(struct inode *inode, int mask) { struct posix_acl *acl; - if (mask & MAY_NOT_BLOCK) - return -ECHILD; - acl = jfs_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); diff --git a/fs/namei.c b/fs/namei.c index b7fad009bbf..120efc76d3d 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "internal.h" @@ -173,12 +174,58 @@ void putname(const char *name) EXPORT_SYMBOL(putname); #endif +static int check_acl(struct inode *inode, int mask) +{ + struct posix_acl *acl; + + /* + * Under RCU walk, we cannot even do a "get_cached_acl()", + * because that involves locking and getting a refcount on + * a cached ACL. + * + * So the only case we handle during RCU walking is the + * case of a cached "no ACL at all", which needs no locks + * or refcounts. + */ + if (mask & MAY_NOT_BLOCK) { + if (negative_cached_acl(inode, ACL_TYPE_ACCESS)) + return -EAGAIN; + return -ECHILD; + } + + acl = get_cached_acl(inode, ACL_TYPE_ACCESS); + + /* + * A filesystem can force a ACL callback by just never + * filling the ACL cache. But normally you'd fill the + * cache either at inode instantiation time, or on the + * first ->check_acl call. + * + * If the filesystem doesn't have a check_acl() function + * at all, we'll just create the negative cache entry. + */ + if (acl == ACL_NOT_CACHED) { + if (inode->i_op->check_acl) + return inode->i_op->check_acl(inode, mask); + + set_cached_acl(inode, ACL_TYPE_ACCESS, NULL); + return -EAGAIN; + } + + if (acl) { + int error = posix_acl_permission(inode, acl, mask); + posix_acl_release(acl); + return error; + } + + return -EAGAIN; +} + /* * This does basic POSIX ACL permission checking */ static int acl_permission_check(struct inode *inode, int mask) { - int (*check_acl)(struct inode *inode, int mask); unsigned int mode = inode->i_mode; mask &= MAY_READ | MAY_WRITE | MAY_EXEC | MAY_NOT_BLOCK; @@ -189,8 +236,7 @@ static int acl_permission_check(struct inode *inode, int mask) if (current_fsuid() == inode->i_uid) mode >>= 6; else { - check_acl = inode->i_op->check_acl; - if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) { + if (IS_POSIXACL(inode) && (mode & S_IRWXG)) { int error = check_acl(inode, mask); if (error != -EAGAIN) return error; diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index f4cf451ce6e..aff23e59b58 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -297,9 +297,6 @@ int ocfs2_check_acl(struct inode *inode, int mask) struct posix_acl *acl; int ret = -EAGAIN; - if (mask & MAY_NOT_BLOCK) - return -ECHILD; - osb = OCFS2_SB(inode->i_sb); if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) return ret; diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index cac48fe22ad..f6d065ac56b 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c @@ -231,16 +231,12 @@ xfs_check_acl(struct inode *inode, int mask) /* * If there is no attribute fork no ACL exists on this inode and * we can skip the whole exercise. + * + * FIXME! Fill the cache! Locking? */ if (!XFS_IFORK_Q(ip)) return -EAGAIN; - if (mask & MAY_NOT_BLOCK) { - if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) - return -ECHILD; - return -EAGAIN; - } - acl = xfs_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); -- cgit v1.2.3-70-g09d2 From ebbb0ef2871bf3f529987313a9146cc42419a8a8 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 23 Jul 2011 17:36:38 +0200 Subject: 9p: do no return 0 from ->check_acl without actually checking If we do not want to use ACLs we at least need to perform normal Unix permission checks. From the comment I'm not quite sure that's what is intended, but if 0p wants to do permission checks entirely on the server it needs to do so in ->permission, not in ->check_acl. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/9p/acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/9p/acl.c b/fs/9p/acl.c index 8be87857605..df4d7a171d7 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c @@ -108,7 +108,7 @@ int v9fs_check_acl(struct inode *inode, int mask) * On access = client and acl = on mode get the acl * values from the server */ - return 0; + return -EAGAIN; } acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); -- cgit v1.2.3-70-g09d2 From 6311b10800a4bdc3f2c85d01fb113cf49bb83770 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 23 Jul 2011 17:36:50 +0200 Subject: xfs: cache negative ACLs if there is no attribute fork Always set up a negative ACL cache entry if the inode doesn't have an attribute fork. That behaves much better than doing this check inside ->check_acl. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/xfs/linux-2.6/xfs_acl.c | 13 +------------ fs/xfs/linux-2.6/xfs_iops.c | 4 ++++ 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index f6d065ac56b..13c4e4fd5c6 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c @@ -221,21 +221,10 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) int xfs_check_acl(struct inode *inode, int mask) { - struct xfs_inode *ip; struct posix_acl *acl; int error = -EAGAIN; - ip = XFS_I(inode); - trace_xfs_check_acl(ip); - - /* - * If there is no attribute fork no ACL exists on this inode and - * we can skip the whole exercise. - * - * FIXME! Fill the cache! Locking? - */ - if (!XFS_IFORK_Q(ip)) - return -EAGAIN; + trace_xfs_check_acl(XFS_I(inode)); acl = xfs_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 501e4f63054..de666917db0 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -1194,6 +1194,10 @@ xfs_setup_inode( break; } + /* if there is no attribute fork no ACL can exist on this inode */ + if (!XFS_IFORK_Q(ip)) + cache_no_acl(inode); + xfs_iflags_clear(ip, XFS_INEW); barrier(); -- cgit v1.2.3-70-g09d2 From 4482a087d4c5a6ffbc385c56b4a4e2f694d9fd5d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 23 Jul 2011 17:37:03 +0200 Subject: reiserfs: cache negative ACLs for v1 stat format Always set up a negative ACL cache entry if the inode can't have ACLs. That behaves much better than doing this check inside ->check_acl. Also remove the left over MAY_NOT_BLOCK check. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/reiserfs/inode.c | 5 +++++ fs/reiserfs/xattr.c | 9 --------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 2922b90ceac..9b0d4b78b4f 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1475,6 +1475,11 @@ void reiserfs_read_locked_inode(struct inode *inode, reiserfs_check_path(&path_to_sd); /* init inode should be relsing */ + /* + * Stat data v1 doesn't support ACLs. + */ + if (get_inode_sd_version(inode) == STAT_DATA_V1) + cache_no_acl(inode); } /** diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 6938d8c68d6..7ba083eb62b 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -872,15 +872,6 @@ int reiserfs_check_acl(struct inode *inode, int mask) struct posix_acl *acl; int error = -EAGAIN; /* do regular unix permission checks by default */ - /* - * Stat data v1 doesn't support ACLs. - */ - if (get_inode_sd_version(inode) == STAT_DATA_V1) - return -EAGAIN; - - if (mask & MAY_NOT_BLOCK) - return -ECHILD; - acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); if (acl) { -- cgit v1.2.3-70-g09d2 From bc26ab5f65ae41b71df86ea46df3c3833d1d8d83 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jul 2011 00:18:02 -0400 Subject: kill boilerplate around posix_acl_chmod_masq() new helper: posix_acl_chmod(&acl, gfp, mode). Replaces acl with modified clone or with NULL if that has failed; returns 0 or -ve on error. All callers of posix_acl_chmod_masq() switched to that - they'd been doing exactly the same thing. Signed-off-by: Al Viro --- fs/9p/acl.c | 13 +++++-------- fs/btrfs/acl.c | 16 +++++----------- fs/ext2/acl.c | 13 +++++-------- fs/ext3/acl.c | 43 +++++++++++++++++++------------------------ fs/ext4/acl.c | 44 ++++++++++++++++++++------------------------ fs/generic_acl.c | 13 +++++-------- fs/gfs2/acl.c | 30 ++++++++++++------------------ fs/jffs2/acl.c | 13 +++++-------- fs/jfs/acl.c | 31 ++++++++++++++----------------- fs/ocfs2/acl.c | 15 ++++++--------- fs/posix_acl.c | 18 ++++++++++++++++++ fs/reiserfs/xattr_acl.c | 41 ++++++++++++++++++----------------------- fs/xfs/linux-2.6/xfs_acl.c | 16 ++++++---------- include/linux/posix_acl.h | 1 + 14 files changed, 139 insertions(+), 168 deletions(-) diff --git a/fs/9p/acl.c b/fs/9p/acl.c index df4d7a171d7..d7211e28c0d 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c @@ -162,21 +162,18 @@ err_free_out: int v9fs_acl_chmod(struct dentry *dentry) { int retval = 0; - struct posix_acl *acl, *clone; + struct posix_acl *acl; struct inode *inode = dentry->d_inode; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); if (acl) { - clone = posix_acl_clone(acl, GFP_KERNEL); + retval = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (retval) + return retval; + retval = v9fs_set_acl(dentry, ACL_TYPE_ACCESS, acl); posix_acl_release(acl); - if (!clone) - return -ENOMEM; - retval = posix_acl_chmod_masq(clone, inode->i_mode); - if (!retval) - retval = v9fs_set_acl(dentry, ACL_TYPE_ACCESS, clone); - posix_acl_release(clone); } return retval; } diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index c13ea9fbf36..88bca53b302 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -272,7 +272,7 @@ failed: int btrfs_acl_chmod(struct inode *inode) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; int ret = 0; if (S_ISLNK(inode->i_mode)) @@ -285,17 +285,11 @@ int btrfs_acl_chmod(struct inode *inode) if (IS_ERR_OR_NULL(acl)) return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_KERNEL); + ret = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (ret) + return ret; + ret = btrfs_set_acl(NULL, inode, acl, ACL_TYPE_ACCESS); posix_acl_release(acl); - if (!clone) - return -ENOMEM; - - ret = posix_acl_chmod_masq(clone, inode->i_mode); - if (!ret) - ret = btrfs_set_acl(NULL, inode, clone, ACL_TYPE_ACCESS); - - posix_acl_release(clone); - return ret; } diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index ced1c478ebd..1226dbcc66f 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -316,7 +316,7 @@ cleanup: int ext2_acl_chmod(struct inode *inode) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; int error; if (!test_opt(inode->i_sb, POSIX_ACL)) @@ -326,14 +326,11 @@ ext2_acl_chmod(struct inode *inode) acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl) || !acl) return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_KERNEL); + error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (error) + return error; + error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl); posix_acl_release(acl); - if (!clone) - return -ENOMEM; - error = posix_acl_chmod_masq(clone, inode->i_mode); - if (!error) - error = ext2_set_acl(inode, ACL_TYPE_ACCESS, clone); - posix_acl_release(clone); return error; } diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index 5326038e853..7ea638acaec 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -326,7 +326,9 @@ cleanup: int ext3_acl_chmod(struct inode *inode) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; + handle_t *handle; + int retries = 0; int error; if (S_ISLNK(inode->i_mode)) @@ -336,31 +338,24 @@ ext3_acl_chmod(struct inode *inode) acl = ext3_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl) || !acl) return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_KERNEL); - posix_acl_release(acl); - if (!clone) - return -ENOMEM; - error = posix_acl_chmod_masq(clone, inode->i_mode); - if (!error) { - handle_t *handle; - int retries = 0; - - retry: - handle = ext3_journal_start(inode, - EXT3_DATA_TRANS_BLOCKS(inode->i_sb)); - if (IS_ERR(handle)) { - error = PTR_ERR(handle); - ext3_std_error(inode->i_sb, error); - goto out; - } - error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, clone); - ext3_journal_stop(handle); - if (error == -ENOSPC && - ext3_should_retry_alloc(inode->i_sb, &retries)) - goto retry; + error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (error) + return error; +retry: + handle = ext3_journal_start(inode, + EXT3_DATA_TRANS_BLOCKS(inode->i_sb)); + if (IS_ERR(handle)) { + error = PTR_ERR(handle); + ext3_std_error(inode->i_sb, error); + goto out; } + error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); + ext3_journal_stop(handle); + if (error == -ENOSPC && + ext3_should_retry_alloc(inode->i_sb, &retries)) + goto retry; out: - posix_acl_release(clone); + posix_acl_release(acl); return error; } diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 4cd9e2e4085..e38a2047d24 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -324,9 +324,12 @@ cleanup: int ext4_acl_chmod(struct inode *inode) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; + handle_t *handle; + int retries = 0; int error; + if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (!test_opt(inode->i_sb, POSIX_ACL)) @@ -334,31 +337,24 @@ ext4_acl_chmod(struct inode *inode) acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl) || !acl) return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_KERNEL); - posix_acl_release(acl); - if (!clone) - return -ENOMEM; - error = posix_acl_chmod_masq(clone, inode->i_mode); - if (!error) { - handle_t *handle; - int retries = 0; - - retry: - handle = ext4_journal_start(inode, - EXT4_DATA_TRANS_BLOCKS(inode->i_sb)); - if (IS_ERR(handle)) { - error = PTR_ERR(handle); - ext4_std_error(inode->i_sb, error); - goto out; - } - error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, clone); - ext4_journal_stop(handle); - if (error == -ENOSPC && - ext4_should_retry_alloc(inode->i_sb, &retries)) - goto retry; + error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (error) + return error; +retry: + handle = ext4_journal_start(inode, + EXT4_DATA_TRANS_BLOCKS(inode->i_sb)); + if (IS_ERR(handle)) { + error = PTR_ERR(handle); + ext4_std_error(inode->i_sb, error); + goto out; } + error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); + ext4_journal_stop(handle); + if (error == -ENOSPC && + ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; out: - posix_acl_release(clone); + posix_acl_release(acl); return error; } diff --git a/fs/generic_acl.c b/fs/generic_acl.c index 4949473d354..3a60d9d1653 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c @@ -170,21 +170,18 @@ cleanup: int generic_acl_chmod(struct inode *inode) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; int error = 0; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; acl = get_cached_acl(inode, ACL_TYPE_ACCESS); if (acl) { - clone = posix_acl_clone(acl, GFP_KERNEL); + error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (error) + return error; + set_cached_acl(inode, ACL_TYPE_ACCESS, acl); posix_acl_release(acl); - if (!clone) - return -ENOMEM; - error = posix_acl_chmod_masq(clone, inode->i_mode); - if (!error) - set_cached_acl(inode, ACL_TYPE_ACCESS, clone); - posix_acl_release(clone); } return error; } diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 48171f4c943..160d4e1575c 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c @@ -187,7 +187,7 @@ out: int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; char *data; unsigned int len; int error; @@ -198,25 +198,19 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) if (!acl) return gfs2_setattr_simple(ip, attr); - clone = posix_acl_clone(acl, GFP_NOFS); + error = posix_acl_chmod(&acl, GFP_NOFS, attr->ia_mode); + if (error) + return error; + + len = posix_acl_to_xattr(acl, NULL, 0); + data = kmalloc(len, GFP_NOFS); error = -ENOMEM; - if (!clone) + if (data == NULL) goto out; - posix_acl_release(acl); - acl = clone; - - error = posix_acl_chmod_masq(acl, attr->ia_mode); - if (!error) { - len = posix_acl_to_xattr(acl, NULL, 0); - data = kmalloc(len, GFP_NOFS); - error = -ENOMEM; - if (data == NULL) - goto out; - posix_acl_to_xattr(acl, data, len); - error = gfs2_xattr_acl_chmod(ip, attr, data); - kfree(data); - set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl); - } + posix_acl_to_xattr(acl, data, len); + error = gfs2_xattr_acl_chmod(ip, attr, data); + kfree(data); + set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl); out: posix_acl_release(acl); diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 4933a8f8ecc..71d022d3850 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -332,7 +332,7 @@ int jffs2_init_acl_post(struct inode *inode) int jffs2_acl_chmod(struct inode *inode) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; int rc; if (S_ISLNK(inode->i_mode)) @@ -340,14 +340,11 @@ int jffs2_acl_chmod(struct inode *inode) acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl) || !acl) return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_KERNEL); + rc = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (rc) + return rc; + rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, acl); posix_acl_release(acl); - if (!clone) - return -ENOMEM; - rc = posix_acl_chmod_masq(clone, inode->i_mode); - if (!rc) - rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone); - posix_acl_release(clone); return rc; } diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index ead200eef5e..89ced71e225 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -177,8 +177,9 @@ cleanup: int jfs_acl_chmod(struct inode *inode) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; int rc; + tid_t tid; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; @@ -187,22 +188,18 @@ int jfs_acl_chmod(struct inode *inode) if (IS_ERR(acl) || !acl) return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_KERNEL); - posix_acl_release(acl); - if (!clone) - return -ENOMEM; - - rc = posix_acl_chmod_masq(clone, inode->i_mode); - if (!rc) { - tid_t tid = txBegin(inode->i_sb, 0); - mutex_lock(&JFS_IP(inode)->commit_mutex); - rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone); - if (!rc) - rc = txCommit(tid, 1, &inode, 0); - txEnd(tid); - mutex_unlock(&JFS_IP(inode)->commit_mutex); - } + rc = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (rc) + return rc; - posix_acl_release(clone); + tid = txBegin(inode->i_sb, 0); + mutex_lock(&JFS_IP(inode)->commit_mutex); + rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl); + if (!rc) + rc = txCommit(tid, 1, &inode, 0); + txEnd(tid); + mutex_unlock(&JFS_IP(inode)->commit_mutex); + + posix_acl_release(acl); return rc; } diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index aff23e59b58..dd0296ade18 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -327,7 +327,7 @@ int ocfs2_check_acl(struct inode *inode, int mask) int ocfs2_acl_chmod(struct inode *inode) { struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); - struct posix_acl *acl, *clone; + struct posix_acl *acl; int ret; if (S_ISLNK(inode->i_mode)) @@ -339,15 +339,12 @@ int ocfs2_acl_chmod(struct inode *inode) acl = ocfs2_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl) || !acl) return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_KERNEL); + ret = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (ret) + return ret; + ret = ocfs2_set_acl(NULL, inode, NULL, ACL_TYPE_ACCESS, + acl, NULL, NULL); posix_acl_release(acl); - if (!clone) - return -ENOMEM; - ret = posix_acl_chmod_masq(clone, inode->i_mode); - if (!ret) - ret = ocfs2_set_acl(NULL, inode, NULL, ACL_TYPE_ACCESS, - clone, NULL, NULL); - posix_acl_release(clone); return ret; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index b1cf6bf4b41..0aa9f167672 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -386,3 +386,21 @@ posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode) return 0; } + +int +posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, mode_t mode) +{ + struct posix_acl *clone = posix_acl_clone(*acl, gfp); + int err = -ENOMEM; + if (clone) { + err = posix_acl_chmod_masq(clone, mode); + if (err) { + posix_acl_release(clone); + clone = NULL; + } + } + posix_acl_release(*acl); + *acl = clone; + return err; +} +EXPORT_SYMBOL(posix_acl_chmod); diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 3dc38f1206f..26b08acf913 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -445,7 +445,10 @@ int reiserfs_cache_default_acl(struct inode *inode) int reiserfs_acl_chmod(struct inode *inode) { - struct posix_acl *acl, *clone; + struct reiserfs_transaction_handle th; + struct posix_acl *acl; + size_t size; + int depth; int error; if (S_ISLNK(inode->i_mode)) @@ -463,30 +466,22 @@ int reiserfs_acl_chmod(struct inode *inode) return 0; if (IS_ERR(acl)) return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_NOFS); - posix_acl_release(acl); - if (!clone) - return -ENOMEM; - error = posix_acl_chmod_masq(clone, inode->i_mode); + error = posix_acl_chmod(&acl, GFP_NOFS, inode->i_mode); + if (error) + return error; + + size = reiserfs_xattr_nblocks(inode, reiserfs_acl_size(acl->a_count)); + depth = reiserfs_write_lock_once(inode->i_sb); + error = journal_begin(&th, inode->i_sb, size * 2); if (!error) { - struct reiserfs_transaction_handle th; - size_t size = reiserfs_xattr_nblocks(inode, - reiserfs_acl_size(clone->a_count)); - int depth; - - depth = reiserfs_write_lock_once(inode->i_sb); - error = journal_begin(&th, inode->i_sb, size * 2); - if (!error) { - int error2; - error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS, - clone); - error2 = journal_end(&th, inode->i_sb, size * 2); - if (error2) - error = error2; - } - reiserfs_write_unlock_once(inode->i_sb, depth); + int error2; + error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS, acl); + error2 = journal_end(&th, inode->i_sb, size * 2); + if (error2) + error = error2; } - posix_acl_release(clone); + reiserfs_write_unlock_once(inode->i_sb, depth); + posix_acl_release(acl); return error; } diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index 13c4e4fd5c6..4c554122db0 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c @@ -326,7 +326,7 @@ xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl) int xfs_acl_chmod(struct inode *inode) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; int error; if (S_ISLNK(inode->i_mode)) @@ -336,16 +336,12 @@ xfs_acl_chmod(struct inode *inode) if (IS_ERR(acl) || !acl) return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_KERNEL); - posix_acl_release(acl); - if (!clone) - return -ENOMEM; - - error = posix_acl_chmod_masq(clone, inode->i_mode); - if (!error) - error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone); + error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (error) + return error; - posix_acl_release(clone); + error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl); + posix_acl_release(acl); return error; } diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 54211c1cd92..7a74d37482e 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -80,6 +80,7 @@ extern struct posix_acl *posix_acl_from_mode(mode_t, gfp_t); extern int posix_acl_equiv_mode(const struct posix_acl *, mode_t *); extern int posix_acl_create_masq(struct posix_acl *, mode_t *); extern int posix_acl_chmod_masq(struct posix_acl *, mode_t); +extern int posix_acl_chmod(struct posix_acl **, gfp_t, mode_t); extern struct posix_acl *get_posix_acl(struct inode *, int); extern int set_posix_acl(struct inode *, int, struct posix_acl *); -- cgit v1.2.3-70-g09d2 From 95203befa8887997f14077d8557e67d78457ee02 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jul 2011 02:41:54 -0400 Subject: generic_acl: no need to clone acl just to push it to set_cached_acl() In-core acls are copy-on-write, so the reference taken by set_cached_acl() will do just fine. Signed-off-by: Al Viro --- fs/generic_acl.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/fs/generic_acl.c b/fs/generic_acl.c index 3a60d9d1653..134782116a6 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c @@ -134,14 +134,8 @@ generic_acl_init(struct inode *inode, struct inode *dir) if (acl) { struct posix_acl *clone; - if (S_ISDIR(inode->i_mode)) { - clone = posix_acl_clone(acl, GFP_KERNEL); - error = -ENOMEM; - if (!clone) - goto cleanup; - set_cached_acl(inode, ACL_TYPE_DEFAULT, clone); - posix_acl_release(clone); - } + if (S_ISDIR(inode->i_mode)) + set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); clone = posix_acl_clone(acl, GFP_KERNEL); error = -ENOMEM; if (!clone) -- cgit v1.2.3-70-g09d2 From 826cae2f2b4d726b925f43bc208a571639da4761 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jul 2011 03:10:32 -0400 Subject: kill boilerplates around posix_acl_create_masq() new helper: posix_acl_create(&acl, gfp, mode_p). Replaces acl with modified clone, on failure releases acl and replaces with NULL. Returns 0 or -ve on error. All callers of posix_acl_create_masq() switched. Signed-off-by: Al Viro --- fs/9p/acl.c | 22 +++++----------------- fs/btrfs/acl.c | 24 ++++++++---------------- fs/ext2/acl.c | 25 ++++++++----------------- fs/ext3/acl.c | 26 +++++++++----------------- fs/ext4/acl.c | 26 +++++++++----------------- fs/generic_acl.c | 20 ++++++-------------- fs/gfs2/acl.c | 14 ++++---------- fs/jffs2/acl.c | 15 +++++---------- fs/jfs/acl.c | 23 +++++++---------------- fs/nfs/nfs3acl.c | 10 +++------- fs/ocfs2/acl.c | 36 ++++++++++++++---------------------- fs/posix_acl.c | 18 ++++++++++++++++++ fs/reiserfs/xattr_acl.c | 30 +++++++----------------------- fs/xfs/linux-2.6/xfs_acl.c | 28 +++++++++++----------------- fs/xfs/linux-2.6/xfs_iops.c | 2 +- include/linux/posix_acl.h | 1 + 16 files changed, 116 insertions(+), 204 deletions(-) diff --git a/fs/9p/acl.c b/fs/9p/acl.c index d7211e28c0d..075bc909da1 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c @@ -206,30 +206,18 @@ int v9fs_acl_mode(struct inode *dir, mode_t *modep, mode &= ~current_umask(); } if (acl) { - struct posix_acl *clone; - if (S_ISDIR(mode)) *dpacl = posix_acl_dup(acl); - clone = posix_acl_clone(acl, GFP_NOFS); - posix_acl_release(acl); - if (!clone) - return -ENOMEM; - - retval = posix_acl_create_masq(clone, &mode); - if (retval < 0) { - posix_acl_release(clone); - goto cleanup; - } + retval = posix_acl_create(&acl, GFP_NOFS, &mode); + if (retval < 0) + return retval; if (retval > 0) - *pacl = clone; + *pacl = acl; else - posix_acl_release(clone); + posix_acl_release(acl); } *modep = mode; return 0; -cleanup: - return retval; - } static int v9fs_remote_get_acl(struct dentry *dentry, const char *name, diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 88bca53b302..9508ad14c92 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -238,8 +238,7 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans, } if (IS_POSIXACL(dir) && acl) { - struct posix_acl *clone; - mode_t mode; + mode_t mode = inode->i_mode; if (S_ISDIR(inode->i_mode)) { ret = btrfs_set_acl(trans, inode, acl, @@ -247,22 +246,15 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans, if (ret) goto failed; } - clone = posix_acl_clone(acl, GFP_NOFS); - ret = -ENOMEM; - if (!clone) - goto failed; + ret = posix_acl_create(&acl, GFP_NOFS, &mode); + if (ret < 0) + return ret; - mode = inode->i_mode; - ret = posix_acl_create_masq(clone, &mode); - if (ret >= 0) { - inode->i_mode = mode; - if (ret > 0) { - /* we need an acl */ - ret = btrfs_set_acl(trans, inode, clone, - ACL_TYPE_ACCESS); - } + inode->i_mode = mode; + if (ret > 0) { + /* we need an acl */ + ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS); } - posix_acl_release(clone); } failed: posix_acl_release(acl); diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 1226dbcc66f..ba99fa4b2f3 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -270,29 +270,20 @@ ext2_init_acl(struct inode *inode, struct inode *dir) inode->i_mode &= ~current_umask(); } if (test_opt(inode->i_sb, POSIX_ACL) && acl) { - struct posix_acl *clone; - mode_t mode; - + mode_t mode = inode->i_mode; if (S_ISDIR(inode->i_mode)) { error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl); if (error) goto cleanup; } - clone = posix_acl_clone(acl, GFP_KERNEL); - error = -ENOMEM; - if (!clone) - goto cleanup; - mode = inode->i_mode; - error = posix_acl_create_masq(clone, &mode); - if (error >= 0) { - inode->i_mode = mode; - if (error > 0) { - /* This is an extended ACL */ - error = ext2_set_acl(inode, - ACL_TYPE_ACCESS, clone); - } + error = posix_acl_create(&acl, GFP_KERNEL, &mode); + if (error < 0) + return error; + inode->i_mode = mode; + if (error > 0) { + /* This is an extended ACL */ + error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl); } - posix_acl_release(clone); } cleanup: posix_acl_release(acl); diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index 7ea638acaec..a9fdd77d4b5 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -278,8 +278,7 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) inode->i_mode &= ~current_umask(); } if (test_opt(inode->i_sb, POSIX_ACL) && acl) { - struct posix_acl *clone; - mode_t mode; + mode_t mode = inode->i_mode; if (S_ISDIR(inode->i_mode)) { error = ext3_set_acl(handle, inode, @@ -287,22 +286,15 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) if (error) goto cleanup; } - clone = posix_acl_clone(acl, GFP_NOFS); - error = -ENOMEM; - if (!clone) - goto cleanup; - - mode = inode->i_mode; - error = posix_acl_create_masq(clone, &mode); - if (error >= 0) { - inode->i_mode = mode; - if (error > 0) { - /* This is an extended ACL */ - error = ext3_set_acl(handle, inode, - ACL_TYPE_ACCESS, clone); - } + error = posix_acl_create(&acl, GFP_NOFS, &mode); + if (error < 0) + return error; + + inode->i_mode = mode; + if (error > 0) { + /* This is an extended ACL */ + error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); } - posix_acl_release(clone); } cleanup: posix_acl_release(acl); diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index e38a2047d24..7b094d1a8d3 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -276,8 +276,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) inode->i_mode &= ~current_umask(); } if (test_opt(inode->i_sb, POSIX_ACL) && acl) { - struct posix_acl *clone; - mode_t mode; + mode_t mode = inode->i_mode; if (S_ISDIR(inode->i_mode)) { error = ext4_set_acl(handle, inode, @@ -285,22 +284,15 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) if (error) goto cleanup; } - clone = posix_acl_clone(acl, GFP_NOFS); - error = -ENOMEM; - if (!clone) - goto cleanup; - - mode = inode->i_mode; - error = posix_acl_create_masq(clone, &mode); - if (error >= 0) { - inode->i_mode = mode; - if (error > 0) { - /* This is an extended ACL */ - error = ext4_set_acl(handle, inode, - ACL_TYPE_ACCESS, clone); - } + error = posix_acl_create(&acl, GFP_NOFS, &mode); + if (error < 0) + return error; + + inode->i_mode = mode; + if (error > 0) { + /* This is an extended ACL */ + error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); } - posix_acl_release(clone); } cleanup: posix_acl_release(acl); diff --git a/fs/generic_acl.c b/fs/generic_acl.c index 134782116a6..ea19ca47d45 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c @@ -132,25 +132,17 @@ generic_acl_init(struct inode *inode, struct inode *dir) if (!S_ISLNK(inode->i_mode)) acl = get_cached_acl(dir, ACL_TYPE_DEFAULT); if (acl) { - struct posix_acl *clone; - if (S_ISDIR(inode->i_mode)) set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); - clone = posix_acl_clone(acl, GFP_KERNEL); - error = -ENOMEM; - if (!clone) - goto cleanup; - error = posix_acl_create_masq(clone, &mode); - if (error >= 0) { - inode->i_mode = mode; - if (error > 0) - set_cached_acl(inode, ACL_TYPE_ACCESS, clone); - } - posix_acl_release(clone); + error = posix_acl_create(&acl, GFP_KERNEL, &mode); + if (error < 0) + return error; + inode->i_mode = mode; + if (error > 0) + set_cached_acl(inode, ACL_TYPE_ACCESS, acl); } error = 0; -cleanup: posix_acl_release(acl); return error; } diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 160d4e1575c..a2dd63c0c11 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c @@ -137,7 +137,7 @@ out: int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) { struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); - struct posix_acl *acl, *clone; + struct posix_acl *acl; mode_t mode = inode->i_mode; int error = 0; @@ -162,16 +162,10 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) goto out; } - clone = posix_acl_clone(acl, GFP_NOFS); - error = -ENOMEM; - if (!clone) - goto out; - posix_acl_release(acl); - acl = clone; - - error = posix_acl_create_masq(acl, &mode); + error = posix_acl_create(&acl, GFP_NOFS, &mode); if (error < 0) - goto out; + return error; + if (error == 0) goto munge; diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 71d022d3850..5783ed81171 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -277,7 +277,7 @@ int jffs2_check_acl(struct inode *inode, int mask) int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, mode_t *i_mode) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; int rc; cache_no_acl(inode); @@ -295,18 +295,13 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, mode_t *i_mode) if (S_ISDIR(*i_mode)) set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); - clone = posix_acl_clone(acl, GFP_KERNEL); - if (!clone) - return -ENOMEM; - rc = posix_acl_create_masq(clone, i_mode); - if (rc < 0) { - posix_acl_release(clone); + rc = posix_acl_create(&acl, GFP_KERNEL, i_mode); + if (rc < 0) return rc; - } if (rc > 0) - set_cached_acl(inode, ACL_TYPE_ACCESS, clone); + set_cached_acl(inode, ACL_TYPE_ACCESS, acl); - posix_acl_release(clone); + posix_acl_release(acl); } return 0; } diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 89ced71e225..687a1ae42e3 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -133,8 +133,6 @@ int jfs_check_acl(struct inode *inode, int mask) int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) { struct posix_acl *acl = NULL; - struct posix_acl *clone; - mode_t mode; int rc = 0; if (S_ISLNK(inode->i_mode)) @@ -145,25 +143,18 @@ int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) return PTR_ERR(acl); if (acl) { + mode_t mode = inode->i_mode; if (S_ISDIR(inode->i_mode)) { rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl); if (rc) goto cleanup; } - clone = posix_acl_clone(acl, GFP_KERNEL); - if (!clone) { - rc = -ENOMEM; - goto cleanup; - } - mode = inode->i_mode; - rc = posix_acl_create_masq(clone, &mode); - if (rc >= 0) { - inode->i_mode = mode; - if (rc > 0) - rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, - clone); - } - posix_acl_release(clone); + rc = posix_acl_create(&acl, GFP_KERNEL, &mode); + if (rc < 0) + goto cleanup; /* posix_acl_release(NULL) is no-op */ + inode->i_mode = mode; + if (rc > 0) + rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl); cleanup: posix_acl_release(acl); } else diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index 27434277165..e49e73107e6 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c @@ -427,16 +427,12 @@ int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode, } if (!dfacl) return 0; - acl = posix_acl_clone(dfacl, GFP_KERNEL); - error = -ENOMEM; - if (!acl) - goto out_release_dfacl; - error = posix_acl_create_masq(acl, &mode); + acl = posix_acl_dup(dfacl); + error = posix_acl_create(&acl, GFP_KERNEL, &mode); if (error < 0) - goto out_release_acl; + goto out_release_dfacl; error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ? dfacl : NULL); -out_release_acl: posix_acl_release(acl); out_release_dfacl: posix_acl_release(dfacl); diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index dd0296ade18..480200e94e8 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -382,8 +382,6 @@ int ocfs2_init_acl(handle_t *handle, } } if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) { - struct posix_acl *clone; - if (S_ISDIR(inode->i_mode)) { ret = ocfs2_set_acl(handle, inode, di_bh, ACL_TYPE_DEFAULT, acl, @@ -391,28 +389,22 @@ int ocfs2_init_acl(handle_t *handle, if (ret) goto cleanup; } - clone = posix_acl_clone(acl, GFP_NOFS); - ret = -ENOMEM; - if (!clone) - goto cleanup; - mode = inode->i_mode; - ret = posix_acl_create_masq(clone, &mode); - if (ret >= 0) { - ret2 = ocfs2_acl_set_mode(inode, di_bh, handle, mode); - if (ret2) { - mlog_errno(ret2); - ret = ret2; - posix_acl_release(clone); - goto cleanup; - } - if (ret > 0) { - ret = ocfs2_set_acl(handle, inode, - di_bh, ACL_TYPE_ACCESS, - clone, meta_ac, data_ac); - } + ret = posix_acl_create(&acl, GFP_NOFS, &mode); + if (ret < 0) + return ret; + + ret2 = ocfs2_acl_set_mode(inode, di_bh, handle, mode); + if (ret2) { + mlog_errno(ret2); + ret = ret2; + goto cleanup; + } + if (ret > 0) { + ret = ocfs2_set_acl(handle, inode, + di_bh, ACL_TYPE_ACCESS, + acl, meta_ac, data_ac); } - posix_acl_release(clone); } cleanup: posix_acl_release(acl); diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 0aa9f167672..365a0712da6 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -387,6 +387,24 @@ posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode) return 0; } +int +posix_acl_create(struct posix_acl **acl, gfp_t gfp, mode_t *mode_p) +{ + struct posix_acl *clone = posix_acl_clone(*acl, gfp); + int err = -ENOMEM; + if (clone) { + err = posix_acl_create_masq(clone, mode_p); + if (err < 0) { + posix_acl_release(clone); + clone = NULL; + } + } + posix_acl_release(*acl); + *acl = clone; + return err; +} +EXPORT_SYMBOL(posix_acl_create); + int posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, mode_t mode) { diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 26b08acf913..7362cf4c946 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -354,9 +354,7 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, return PTR_ERR(acl); if (acl) { - struct posix_acl *acl_copy; mode_t mode = inode->i_mode; - int need_acl; /* Copy the default ACL to the default ACL of a new directory */ if (S_ISDIR(inode->i_mode)) { @@ -368,29 +366,15 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, /* Now we reconcile the new ACL and the mode, potentially modifying both */ - acl_copy = posix_acl_clone(acl, GFP_NOFS); - if (!acl_copy) { - err = -ENOMEM; - goto cleanup; - } + err = posix_acl_create(&acl, GFP_NOFS, &mode); + if (err < 0) + return err; - need_acl = posix_acl_create_masq(acl_copy, &mode); - if (need_acl >= 0) { - if (mode != inode->i_mode) { - inode->i_mode = mode; - } + inode->i_mode = mode; - /* If we need an ACL.. */ - if (need_acl > 0) { - err = reiserfs_set_acl(th, inode, - ACL_TYPE_ACCESS, - acl_copy); - if (err) - goto cleanup_copy; - } - } - cleanup_copy: - posix_acl_release(acl_copy); + /* If we need an ACL.. */ + if (err > 0) + err = reiserfs_set_acl(th, inode, ACL_TYPE_ACCESS, acl); cleanup: posix_acl_release(acl); } else { diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index 4c554122db0..2827bbd8366 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c @@ -282,29 +282,23 @@ posix_acl_default_exists(struct inode *inode) * No need for i_mutex because the inode is not yet exposed to the VFS. */ int -xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl) +xfs_inherit_acl(struct inode *inode, struct posix_acl *acl) { - struct posix_acl *clone; - mode_t mode; + mode_t mode = inode->i_mode; int error = 0, inherit = 0; if (S_ISDIR(inode->i_mode)) { - error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl); + error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, acl); if (error) - return error; + goto out; } - clone = posix_acl_clone(default_acl, GFP_KERNEL); - if (!clone) - return -ENOMEM; - - mode = inode->i_mode; - error = posix_acl_create_masq(clone, &mode); + error = posix_acl_create(&acl, GFP_KERNEL, &mode); if (error < 0) - goto out_release_clone; + return error; /* - * If posix_acl_create_masq returns a positive value we need to + * If posix_acl_create returns a positive value we need to * inherit a permission that can't be represented using the Unix * mode bits and we actually need to set an ACL. */ @@ -313,13 +307,13 @@ xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl) error = xfs_set_mode(inode, mode); if (error) - goto out_release_clone; + goto out; if (inherit) - error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone); + error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl); - out_release_clone: - posix_acl_release(clone); +out: + posix_acl_release(acl); return error; } diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index de666917db0..77463dd5519 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -202,9 +202,9 @@ xfs_vn_mknod( if (default_acl) { error = -xfs_inherit_acl(inode, default_acl); + default_acl = NULL; if (unlikely(error)) goto out_cleanup_inode; - posix_acl_release(default_acl); } diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 7a74d37482e..0ae0e4a3e20 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -80,6 +80,7 @@ extern struct posix_acl *posix_acl_from_mode(mode_t, gfp_t); extern int posix_acl_equiv_mode(const struct posix_acl *, mode_t *); extern int posix_acl_create_masq(struct posix_acl *, mode_t *); extern int posix_acl_chmod_masq(struct posix_acl *, mode_t); +extern int posix_acl_create(struct posix_acl **, gfp_t, mode_t *); extern int posix_acl_chmod(struct posix_acl **, gfp_t, mode_t); extern struct posix_acl *get_posix_acl(struct inode *, int); -- cgit v1.2.3-70-g09d2 From edde854e8bb34a7f32fa993d721f1da0faf64165 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jul 2011 03:27:37 -0400 Subject: bury posix_acl_..._masq() variants made static; no callers left outside of posix_acl.c. posix_acl_clone() also has lost all external callers and became static... Signed-off-by: Al Viro --- fs/posix_acl.c | 11 +++-------- include/linux/posix_acl.h | 3 --- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 365a0712da6..0dd0266f979 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -24,12 +24,9 @@ EXPORT_SYMBOL(posix_acl_init); EXPORT_SYMBOL(posix_acl_alloc); -EXPORT_SYMBOL(posix_acl_clone); EXPORT_SYMBOL(posix_acl_valid); EXPORT_SYMBOL(posix_acl_equiv_mode); EXPORT_SYMBOL(posix_acl_from_mode); -EXPORT_SYMBOL(posix_acl_create_masq); -EXPORT_SYMBOL(posix_acl_chmod_masq); EXPORT_SYMBOL(posix_acl_permission); /* @@ -59,7 +56,7 @@ posix_acl_alloc(int count, gfp_t flags) /* * Clone an ACL. */ -struct posix_acl * +static struct posix_acl * posix_acl_clone(const struct posix_acl *acl, gfp_t flags) { struct posix_acl *clone = NULL; @@ -283,8 +280,7 @@ check_perm: * system calls. All permissions that are not granted by the acl are removed. * The permissions in the acl are changed to reflect the mode_p parameter. */ -int -posix_acl_create_masq(struct posix_acl *acl, mode_t *mode_p) +static int posix_acl_create_masq(struct posix_acl *acl, mode_t *mode_p) { struct posix_acl_entry *pa, *pe; struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; @@ -341,8 +337,7 @@ posix_acl_create_masq(struct posix_acl *acl, mode_t *mode_p) /* * Modify the ACL for the chmod syscall. */ -int -posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode) +static int posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode) { struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; struct posix_acl_entry *pa, *pe; diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 0ae0e4a3e20..9a53b99818e 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -73,13 +73,10 @@ posix_acl_release(struct posix_acl *acl) extern void posix_acl_init(struct posix_acl *, int); extern struct posix_acl *posix_acl_alloc(int, gfp_t); -extern struct posix_acl *posix_acl_clone(const struct posix_acl *, gfp_t); extern int posix_acl_valid(const struct posix_acl *); extern int posix_acl_permission(struct inode *, const struct posix_acl *, int); extern struct posix_acl *posix_acl_from_mode(mode_t, gfp_t); extern int posix_acl_equiv_mode(const struct posix_acl *, mode_t *); -extern int posix_acl_create_masq(struct posix_acl *, mode_t *); -extern int posix_acl_chmod_masq(struct posix_acl *, mode_t); extern int posix_acl_create(struct posix_acl **, gfp_t, mode_t *); extern int posix_acl_chmod(struct posix_acl **, gfp_t, mode_t); -- cgit v1.2.3-70-g09d2 From 4e34e719e457f2e031297175410fc0bd4016a085 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 23 Jul 2011 17:37:31 +0200 Subject: fs: take the ACL checks to common code Replace the ->check_acl method with a ->get_acl method that simply reads an ACL from disk after having a cache miss. This means we can replace the ACL checking boilerplate code with a single implementation in namei.c. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- Documentation/filesystems/Locking | 4 ++-- Documentation/filesystems/porting | 7 ++++--- Documentation/filesystems/vfs.txt | 2 +- fs/9p/acl.c | 14 +++----------- fs/9p/acl.h | 4 ++-- fs/9p/vfs_inode_dotl.c | 4 ++-- fs/btrfs/acl.c | 18 +----------------- fs/btrfs/ctree.h | 4 ++-- fs/btrfs/inode.c | 10 +++++----- fs/ext2/acl.c | 19 +------------------ fs/ext2/acl.h | 4 ++-- fs/ext2/file.c | 2 +- fs/ext2/namei.c | 4 ++-- fs/ext3/acl.c | 19 +------------------ fs/ext3/acl.h | 4 ++-- fs/ext3/file.c | 2 +- fs/ext3/namei.c | 4 ++-- fs/ext4/acl.c | 19 +------------------ fs/ext4/acl.h | 4 ++-- fs/ext4/file.c | 2 +- fs/ext4/namei.c | 4 ++-- fs/generic_acl.c | 14 -------------- fs/gfs2/acl.c | 25 ++----------------------- fs/gfs2/acl.h | 2 +- fs/gfs2/inode.c | 6 +++--- fs/jffs2/acl.c | 18 +----------------- fs/jffs2/acl.h | 4 ++-- fs/jffs2/dir.c | 2 +- fs/jffs2/file.c | 2 +- fs/jffs2/symlink.c | 2 +- fs/jfs/acl.c | 18 +----------------- fs/jfs/file.c | 2 +- fs/jfs/jfs_acl.h | 2 +- fs/jfs/namei.c | 2 +- fs/namei.c | 24 +++++++++++++----------- fs/ocfs2/acl.c | 24 ++++++------------------ fs/ocfs2/acl.h | 2 +- fs/ocfs2/file.c | 4 ++-- fs/ocfs2/namei.c | 2 +- fs/posix_acl.c | 1 - fs/reiserfs/file.c | 2 +- fs/reiserfs/namei.c | 6 +++--- fs/reiserfs/xattr.c | 18 ------------------ fs/xfs/linux-2.6/xfs_acl.c | 21 ++------------------- fs/xfs/linux-2.6/xfs_iops.c | 8 ++++---- fs/xfs/linux-2.6/xfs_trace.h | 2 +- fs/xfs/xfs_acl.h | 2 -- include/linux/fs.h | 2 +- include/linux/generic_acl.h | 1 - include/linux/reiserfs_acl.h | 6 +----- include/linux/reiserfs_xattr.h | 2 -- mm/shmem.c | 6 ------ 52 files changed, 92 insertions(+), 294 deletions(-) diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index ca7e2529254..7e4699146fe 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -52,7 +52,7 @@ ata *); void (*put_link) (struct dentry *, struct nameidata *, void *); void (*truncate) (struct inode *); int (*permission) (struct inode *, int, unsigned int); - int (*check_acl)(struct inode *, int); + int (*get_acl)(struct inode *, int); int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *); int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); @@ -80,7 +80,7 @@ put_link: no truncate: yes (see below) setattr: yes permission: no (may not block if called in rcu-walk mode) -check_acl: no +get_acl: no getattr: no setxattr: yes getxattr: no diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 7f8861d341e..b4a3d765ff9 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -407,10 +407,11 @@ to some pointer to returning that pointer. On errors return ERR_PTR(...). -- [mandatory] - ->permission(), generic_permission() and ->check_acl() have lost flags + ->permission() and generic_permission()have lost flags argument; instead of passing IPERM_FLAG_RCU we add MAY_NOT_BLOCK into mask. - generic_permission() has also lost the check_acl argument; if you want -non-NULL to be used for that inode, put it into ->i_op->check_acl. + generic_permission() has also lost the check_acl argument; ACL checking +has been taken to VFS and filesystems need to provide a non-NULL ->i_op->get_acl +to read an ACL from disk. -- [mandatory] diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index eff6617c9a0..52d8fb81cff 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -356,7 +356,7 @@ struct inode_operations { void (*put_link) (struct dentry *, struct nameidata *, void *); void (*truncate) (struct inode *); int (*permission) (struct inode *, int); - int (*check_acl)(struct inode *, int); + int (*get_acl)(struct inode *, int); int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); diff --git a/fs/9p/acl.c b/fs/9p/acl.c index 075bc909da1..814be079c18 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c @@ -96,7 +96,7 @@ static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type) return acl; } -int v9fs_check_acl(struct inode *inode, int mask) +struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type) { struct posix_acl *acl; struct v9fs_session_info *v9ses; @@ -108,18 +108,10 @@ int v9fs_check_acl(struct inode *inode, int mask) * On access = client and acl = on mode get the acl * values from the server */ - return -EAGAIN; + return NULL; } - acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); + return v9fs_get_cached_acl(inode, type); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } - return -EAGAIN; } static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl) diff --git a/fs/9p/acl.h b/fs/9p/acl.h index 3eba10f3af1..ddb7ae19d97 100644 --- a/fs/9p/acl.h +++ b/fs/9p/acl.h @@ -16,14 +16,14 @@ #ifdef CONFIG_9P_FS_POSIX_ACL extern int v9fs_get_acl(struct inode *, struct p9_fid *); -extern int v9fs_check_acl(struct inode *inode, int mask); +extern struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type); extern int v9fs_acl_chmod(struct dentry *); extern int v9fs_set_create_acl(struct dentry *, struct posix_acl **, struct posix_acl **); extern int v9fs_acl_mode(struct inode *dir, mode_t *modep, struct posix_acl **dpacl, struct posix_acl **pacl); #else -#define v9fs_check_acl NULL +#define v9fs_iop_get_acl NULL static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid) { return 0; diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 803f59ff2fa..9d808d0e0cd 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -872,7 +872,7 @@ const struct inode_operations v9fs_dir_inode_operations_dotl = { .getxattr = generic_getxattr, .removexattr = generic_removexattr, .listxattr = v9fs_listxattr, - .check_acl = v9fs_check_acl, + .get_acl = v9fs_iop_get_acl, }; const struct inode_operations v9fs_file_inode_operations_dotl = { @@ -882,7 +882,7 @@ const struct inode_operations v9fs_file_inode_operations_dotl = { .getxattr = generic_getxattr, .removexattr = generic_removexattr, .listxattr = v9fs_listxattr, - .check_acl = v9fs_check_acl, + .get_acl = v9fs_iop_get_acl, }; const struct inode_operations v9fs_symlink_inode_operations_dotl = { diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 9508ad14c92..65a735d8f6e 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -30,7 +30,7 @@ #ifdef CONFIG_BTRFS_FS_POSIX_ACL -static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) +struct posix_acl *btrfs_get_acl(struct inode *inode, int type) { int size; const char *name; @@ -195,22 +195,6 @@ out: return ret; } -int btrfs_check_acl(struct inode *inode, int mask) -{ - int error = -EAGAIN; - struct posix_acl *acl; - - acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - } - - return error; -} - /* * btrfs_init_acl is already generally called under fs_mutex, so the locking * stuff has been fixed to work with that. If the locking stuff changes, we diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 82be74efbb2..fe9287b0649 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2645,9 +2645,9 @@ do { \ /* acl.c */ #ifdef CONFIG_BTRFS_FS_POSIX_ACL -int btrfs_check_acl(struct inode *inode, int mask); +struct posix_acl *btrfs_get_acl(struct inode *inode, int type); #else -#define btrfs_check_acl NULL +#define btrfs_get_acl NULL #endif int btrfs_init_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2548a04a023..e91b097e725 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7351,12 +7351,12 @@ static const struct inode_operations btrfs_dir_inode_operations = { .listxattr = btrfs_listxattr, .removexattr = btrfs_removexattr, .permission = btrfs_permission, - .check_acl = btrfs_check_acl, + .get_acl = btrfs_get_acl, }; static const struct inode_operations btrfs_dir_ro_inode_operations = { .lookup = btrfs_lookup, .permission = btrfs_permission, - .check_acl = btrfs_check_acl, + .get_acl = btrfs_get_acl, }; static const struct file_operations btrfs_dir_file_operations = { @@ -7425,7 +7425,7 @@ static const struct inode_operations btrfs_file_inode_operations = { .removexattr = btrfs_removexattr, .permission = btrfs_permission, .fiemap = btrfs_fiemap, - .check_acl = btrfs_check_acl, + .get_acl = btrfs_get_acl, }; static const struct inode_operations btrfs_special_inode_operations = { .getattr = btrfs_getattr, @@ -7435,7 +7435,7 @@ static const struct inode_operations btrfs_special_inode_operations = { .getxattr = btrfs_getxattr, .listxattr = btrfs_listxattr, .removexattr = btrfs_removexattr, - .check_acl = btrfs_check_acl, + .get_acl = btrfs_get_acl, }; static const struct inode_operations btrfs_symlink_inode_operations = { .readlink = generic_readlink, @@ -7447,7 +7447,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { .getxattr = btrfs_getxattr, .listxattr = btrfs_listxattr, .removexattr = btrfs_removexattr, - .check_acl = btrfs_check_acl, + .get_acl = btrfs_get_acl, }; const struct dentry_operations btrfs_dentry_operations = { diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index ba99fa4b2f3..52c05376394 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -128,7 +128,7 @@ fail: /* * inode->i_mutex: don't care */ -static struct posix_acl * +struct posix_acl * ext2_get_acl(struct inode *inode, int type) { int name_index; @@ -231,23 +231,6 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) return error; } -int -ext2_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl; - - acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } - - return -EAGAIN; -} - /* * Initialize the ACLs of a new inode. Called from ext2_new_inode. * diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h index 3ff6cbb9ac4..5c0a6a4fb05 100644 --- a/fs/ext2/acl.h +++ b/fs/ext2/acl.h @@ -54,13 +54,13 @@ static inline int ext2_acl_count(size_t size) #ifdef CONFIG_EXT2_FS_POSIX_ACL /* acl.c */ -extern int ext2_check_acl (struct inode *, int); +extern struct posix_acl *ext2_get_acl(struct inode *inode, int type); extern int ext2_acl_chmod (struct inode *); extern int ext2_init_acl (struct inode *, struct inode *); #else #include -#define ext2_check_acl NULL +#define ext2_get_acl NULL #define ext2_get_acl NULL #define ext2_set_acl NULL diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 82e06321de3..a5b3a5db312 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -102,6 +102,6 @@ const struct inode_operations ext2_file_inode_operations = { .removexattr = generic_removexattr, #endif .setattr = ext2_setattr, - .check_acl = ext2_check_acl, + .get_acl = ext2_get_acl, .fiemap = ext2_fiemap, }; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index d60b7099e2d..761fde807fc 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -408,7 +408,7 @@ const struct inode_operations ext2_dir_inode_operations = { .removexattr = generic_removexattr, #endif .setattr = ext2_setattr, - .check_acl = ext2_check_acl, + .get_acl = ext2_get_acl, }; const struct inode_operations ext2_special_inode_operations = { @@ -419,5 +419,5 @@ const struct inode_operations ext2_special_inode_operations = { .removexattr = generic_removexattr, #endif .setattr = ext2_setattr, - .check_acl = ext2_check_acl, + .get_acl = ext2_get_acl, }; diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index a9fdd77d4b5..6c29bf0df04 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -131,7 +131,7 @@ fail: * * inode->i_mutex: don't care */ -static struct posix_acl * +struct posix_acl * ext3_get_acl(struct inode *inode, int type) { int name_index; @@ -239,23 +239,6 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type, return error; } -int -ext3_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl; - - acl = ext3_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } - - return -EAGAIN; -} - /* * Initialize the ACLs of a new inode. Called from ext3_new_inode. * diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h index 597334626de..dbc921e458c 100644 --- a/fs/ext3/acl.h +++ b/fs/ext3/acl.h @@ -54,13 +54,13 @@ static inline int ext3_acl_count(size_t size) #ifdef CONFIG_EXT3_FS_POSIX_ACL /* acl.c */ -extern int ext3_check_acl (struct inode *, int); +extern struct posix_acl *ext3_get_acl(struct inode *inode, int type); extern int ext3_acl_chmod (struct inode *); extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); #else /* CONFIG_EXT3_FS_POSIX_ACL */ #include -#define ext3_check_acl NULL +#define ext3_get_acl NULL static inline int ext3_acl_chmod(struct inode *inode) diff --git a/fs/ext3/file.c b/fs/ext3/file.c index f55df0e61cb..2be5b99097f 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c @@ -79,7 +79,7 @@ const struct inode_operations ext3_file_inode_operations = { .listxattr = ext3_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext3_check_acl, + .get_acl = ext3_get_acl, .fiemap = ext3_fiemap, }; diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index c095cf5640c..3b57230a17b 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -2529,7 +2529,7 @@ const struct inode_operations ext3_dir_inode_operations = { .listxattr = ext3_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext3_check_acl, + .get_acl = ext3_get_acl, }; const struct inode_operations ext3_special_inode_operations = { @@ -2540,5 +2540,5 @@ const struct inode_operations ext3_special_inode_operations = { .listxattr = ext3_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext3_check_acl, + .get_acl = ext3_get_acl, }; diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 7b094d1a8d3..dca2d1ded93 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -131,7 +131,7 @@ fail: * * inode->i_mutex: don't care */ -static struct posix_acl * +struct posix_acl * ext4_get_acl(struct inode *inode, int type) { int name_index; @@ -237,23 +237,6 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type, return error; } -int -ext4_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl; - - acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } - - return -EAGAIN; -} - /* * Initialize the ACLs of a new inode. Called from ext4_new_inode. * diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h index 9d843d5deac..18cb39ed7c7 100644 --- a/fs/ext4/acl.h +++ b/fs/ext4/acl.h @@ -54,13 +54,13 @@ static inline int ext4_acl_count(size_t size) #ifdef CONFIG_EXT4_FS_POSIX_ACL /* acl.c */ -extern int ext4_check_acl(struct inode *, int); +struct posix_acl *ext4_get_acl(struct inode *inode, int type); extern int ext4_acl_chmod(struct inode *); extern int ext4_init_acl(handle_t *, struct inode *, struct inode *); #else /* CONFIG_EXT4_FS_POSIX_ACL */ #include -#define ext4_check_acl NULL +#define ext4_get_acl NULL static inline int ext4_acl_chmod(struct inode *inode) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index ce766f974b1..e4095e988eb 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -301,7 +301,7 @@ const struct inode_operations ext4_file_inode_operations = { .listxattr = ext4_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext4_check_acl, + .get_acl = ext4_get_acl, .fiemap = ext4_fiemap, }; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 707d605bf76..8c9babac43d 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2590,7 +2590,7 @@ const struct inode_operations ext4_dir_inode_operations = { .listxattr = ext4_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext4_check_acl, + .get_acl = ext4_get_acl, .fiemap = ext4_fiemap, }; @@ -2602,5 +2602,5 @@ const struct inode_operations ext4_special_inode_operations = { .listxattr = ext4_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext4_check_acl, + .get_acl = ext4_get_acl, }; diff --git a/fs/generic_acl.c b/fs/generic_acl.c index ea19ca47d45..d5e33a077a6 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c @@ -172,20 +172,6 @@ generic_acl_chmod(struct inode *inode) return error; } -int -generic_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl; - - acl = get_cached_acl(inode, ACL_TYPE_ACCESS); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } - return -EAGAIN; -} - const struct xattr_handler generic_acl_access_handler = { .prefix = POSIX_ACL_XATTR_ACCESS, .flags = ACL_TYPE_ACCESS, diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index a2dd63c0c11..884c9af0542 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c @@ -67,30 +67,9 @@ static struct posix_acl *gfs2_acl_get(struct gfs2_inode *ip, int type) return acl; } -/** - * gfs2_check_acl - Check an ACL to see if we're allowed to do something - * @inode: the file we want to do something to - * @mask: what we want to do - * - * Returns: errno - */ - -int gfs2_check_acl(struct inode *inode, int mask) +struct posix_acl *gfs2_get_acl(struct inode *inode, int type) { - struct posix_acl *acl; - int error; - - acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - - if (acl) { - error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } - - return -EAGAIN; + return gfs2_acl_get(GFS2_I(inode), type); } static int gfs2_set_mode(struct inode *inode, mode_t mode) diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h index b522b0cb39e..0da38dc7efe 100644 --- a/fs/gfs2/acl.h +++ b/fs/gfs2/acl.h @@ -16,7 +16,7 @@ #define GFS2_POSIX_ACL_DEFAULT "posix_acl_default" #define GFS2_ACL_MAX_ENTRIES 25 -extern int gfs2_check_acl(struct inode *inode, int mask); +extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type); extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode); extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); extern const struct xattr_handler gfs2_xattr_system_handler; diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 0fb51a96eff..900cf986aad 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1846,7 +1846,7 @@ const struct inode_operations gfs2_file_iops = { .listxattr = gfs2_listxattr, .removexattr = gfs2_removexattr, .fiemap = gfs2_fiemap, - .check_acl = gfs2_check_acl, + .get_acl = gfs2_get_acl, }; const struct inode_operations gfs2_dir_iops = { @@ -1867,7 +1867,7 @@ const struct inode_operations gfs2_dir_iops = { .listxattr = gfs2_listxattr, .removexattr = gfs2_removexattr, .fiemap = gfs2_fiemap, - .check_acl = gfs2_check_acl, + .get_acl = gfs2_get_acl, }; const struct inode_operations gfs2_symlink_iops = { @@ -1882,6 +1882,6 @@ const struct inode_operations gfs2_symlink_iops = { .listxattr = gfs2_listxattr, .removexattr = gfs2_removexattr, .fiemap = gfs2_fiemap, - .check_acl = gfs2_check_acl, + .get_acl = gfs2_get_acl, }; diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 5783ed81171..27c511a1cf0 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -156,7 +156,7 @@ static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size) return ERR_PTR(-EINVAL); } -static struct posix_acl *jffs2_get_acl(struct inode *inode, int type) +struct posix_acl *jffs2_get_acl(struct inode *inode, int type) { struct posix_acl *acl; char *value = NULL; @@ -259,22 +259,6 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) return rc; } -int jffs2_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl; - int rc; - - acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - rc = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return rc; - } - return -EAGAIN; -} - int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, mode_t *i_mode) { struct posix_acl *acl; diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h index 9973073b9c4..b3421c78d9f 100644 --- a/fs/jffs2/acl.h +++ b/fs/jffs2/acl.h @@ -26,7 +26,7 @@ struct jffs2_acl_header { #ifdef CONFIG_JFFS2_FS_POSIX_ACL -extern int jffs2_check_acl(struct inode *, int); +struct posix_acl *jffs2_get_acl(struct inode *inode, int type); extern int jffs2_acl_chmod(struct inode *); extern int jffs2_init_acl_pre(struct inode *, struct inode *, mode_t *); extern int jffs2_init_acl_post(struct inode *); @@ -36,7 +36,7 @@ extern const struct xattr_handler jffs2_acl_default_xattr_handler; #else -#define jffs2_check_acl (NULL) +#define jffs2_get_acl (NULL) #define jffs2_acl_chmod(inode) (0) #define jffs2_init_acl_pre(dir_i,inode,mode) (0) #define jffs2_init_acl_post(inode) (0) diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 5f243cd63af..9659b7c0046 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -56,7 +56,7 @@ const struct inode_operations jffs2_dir_inode_operations = .rmdir = jffs2_rmdir, .mknod = jffs2_mknod, .rename = jffs2_rename, - .check_acl = jffs2_check_acl, + .get_acl = jffs2_get_acl, .setattr = jffs2_setattr, .setxattr = jffs2_setxattr, .getxattr = jffs2_getxattr, diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 3989f7e09f7..61e6723535b 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -63,7 +63,7 @@ const struct file_operations jffs2_file_operations = const struct inode_operations jffs2_file_inode_operations = { - .check_acl = jffs2_check_acl, + .get_acl = jffs2_get_acl, .setattr = jffs2_setattr, .setxattr = jffs2_setxattr, .getxattr = jffs2_getxattr, diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c index b955626071c..e3035afb181 100644 --- a/fs/jffs2/symlink.c +++ b/fs/jffs2/symlink.c @@ -20,7 +20,7 @@ const struct inode_operations jffs2_symlink_inode_operations = { .readlink = generic_readlink, .follow_link = jffs2_follow_link, - .check_acl = jffs2_check_acl, + .get_acl = jffs2_get_acl, .setattr = jffs2_setattr, .setxattr = jffs2_setxattr, .getxattr = jffs2_getxattr, diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 687a1ae42e3..b3a32caf2b4 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -27,7 +27,7 @@ #include "jfs_xattr.h" #include "jfs_acl.h" -static struct posix_acl *jfs_get_acl(struct inode *inode, int type) +struct posix_acl *jfs_get_acl(struct inode *inode, int type) { struct posix_acl *acl; char *ea_name; @@ -114,22 +114,6 @@ out: return rc; } -int jfs_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl; - - acl = jfs_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } - - return -EAGAIN; -} - int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) { struct posix_acl *acl = NULL; diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 7527855b5cc..844f9460cb1 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -140,7 +140,7 @@ const struct inode_operations jfs_file_inode_operations = { .removexattr = jfs_removexattr, .setattr = jfs_setattr, #ifdef CONFIG_JFS_POSIX_ACL - .check_acl = jfs_check_acl, + .get_acl = jfs_get_acl, #endif }; diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h index 54e07559878..ad84fe50ca9 100644 --- a/fs/jfs/jfs_acl.h +++ b/fs/jfs/jfs_acl.h @@ -20,7 +20,7 @@ #ifdef CONFIG_JFS_POSIX_ACL -int jfs_check_acl(struct inode *, int); +struct posix_acl *jfs_get_acl(struct inode *inode, int type); int jfs_init_acl(tid_t, struct inode *, struct inode *); int jfs_acl_chmod(struct inode *inode); diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 03787ef6a11..29b1f1a2114 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -1537,7 +1537,7 @@ const struct inode_operations jfs_dir_inode_operations = { .removexattr = jfs_removexattr, .setattr = jfs_setattr, #ifdef CONFIG_JFS_POSIX_ACL - .check_acl = jfs_check_acl, + .get_acl = jfs_get_acl, #endif }; diff --git a/fs/namei.c b/fs/namei.c index 120efc76d3d..ec2e5656b44 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -196,20 +196,22 @@ static int check_acl(struct inode *inode, int mask) acl = get_cached_acl(inode, ACL_TYPE_ACCESS); /* - * A filesystem can force a ACL callback by just never - * filling the ACL cache. But normally you'd fill the - * cache either at inode instantiation time, or on the - * first ->check_acl call. + * A filesystem can force a ACL callback by just never filling the + * ACL cache. But normally you'd fill the cache either at inode + * instantiation time, or on the first ->get_acl call. * - * If the filesystem doesn't have a check_acl() function - * at all, we'll just create the negative cache entry. + * If the filesystem doesn't have a get_acl() function at all, we'll + * just create the negative cache entry. */ if (acl == ACL_NOT_CACHED) { - if (inode->i_op->check_acl) - return inode->i_op->check_acl(inode, mask); - - set_cached_acl(inode, ACL_TYPE_ACCESS, NULL); - return -EAGAIN; + if (inode->i_op->get_acl) { + acl = inode->i_op->get_acl(inode, ACL_TYPE_ACCESS); + if (IS_ERR(acl)) + return PTR_ERR(acl); + } else { + set_cached_acl(inode, ACL_TYPE_ACCESS, NULL); + return -EAGAIN; + } } if (acl) { diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index 480200e94e8..783c58d9daf 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -290,7 +290,7 @@ static int ocfs2_set_acl(handle_t *handle, return ret; } -int ocfs2_check_acl(struct inode *inode, int mask) +struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type) { struct ocfs2_super *osb; struct buffer_head *di_bh = NULL; @@ -299,29 +299,17 @@ int ocfs2_check_acl(struct inode *inode, int mask) osb = OCFS2_SB(inode->i_sb); if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) - return ret; + return NULL; ret = ocfs2_read_inode_block(inode, &di_bh); - if (ret < 0) { - mlog_errno(ret); - return ret; - } + if (ret < 0) + return ERR_PTR(ret); - acl = ocfs2_get_acl_nolock(inode, ACL_TYPE_ACCESS, di_bh); + acl = ocfs2_get_acl_nolock(inode, type, di_bh); brelse(di_bh); - if (IS_ERR(acl)) { - mlog_errno(PTR_ERR(acl)); - return PTR_ERR(acl); - } - if (acl) { - ret = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return ret; - } - - return -EAGAIN; + return acl; } int ocfs2_acl_chmod(struct inode *inode) diff --git a/fs/ocfs2/acl.h b/fs/ocfs2/acl.h index 5c5d31f0585..071fbd380f2 100644 --- a/fs/ocfs2/acl.h +++ b/fs/ocfs2/acl.h @@ -26,7 +26,7 @@ struct ocfs2_acl_entry { __le32 e_id; }; -extern int ocfs2_check_acl(struct inode *, int); +struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type); extern int ocfs2_acl_chmod(struct inode *); extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, struct buffer_head *, struct buffer_head *, diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 0fc2bd34039..de4ea1af041 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2600,14 +2600,14 @@ const struct inode_operations ocfs2_file_iops = { .listxattr = ocfs2_listxattr, .removexattr = generic_removexattr, .fiemap = ocfs2_fiemap, - .check_acl = ocfs2_check_acl, + .get_acl = ocfs2_iop_get_acl, }; const struct inode_operations ocfs2_special_file_iops = { .setattr = ocfs2_setattr, .getattr = ocfs2_getattr, .permission = ocfs2_permission, - .check_acl = ocfs2_check_acl, + .get_acl = ocfs2_iop_get_acl, }; /* diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 33889dc52dd..53aa41ed7bf 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -2498,5 +2498,5 @@ const struct inode_operations ocfs2_dir_iops = { .listxattr = ocfs2_listxattr, .removexattr = generic_removexattr, .fiemap = ocfs2_fiemap, - .check_acl = ocfs2_check_acl, + .get_acl = ocfs2_iop_get_acl, }; diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 0dd0266f979..a6227d219e9 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -27,7 +27,6 @@ EXPORT_SYMBOL(posix_acl_alloc); EXPORT_SYMBOL(posix_acl_valid); EXPORT_SYMBOL(posix_acl_equiv_mode); EXPORT_SYMBOL(posix_acl_from_mode); -EXPORT_SYMBOL(posix_acl_permission); /* * Init a fresh posix_acl diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index c7156dc39ce..ace635053a3 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -319,5 +319,5 @@ const struct inode_operations reiserfs_file_inode_operations = { .listxattr = reiserfs_listxattr, .removexattr = reiserfs_removexattr, .permission = reiserfs_permission, - .check_acl = reiserfs_check_acl, + .get_acl = reiserfs_get_acl, }; diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 551f1b79dbc..ef392324bbf 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -1529,7 +1529,7 @@ const struct inode_operations reiserfs_dir_inode_operations = { .listxattr = reiserfs_listxattr, .removexattr = reiserfs_removexattr, .permission = reiserfs_permission, - .check_acl = reiserfs_check_acl, + .get_acl = reiserfs_get_acl, }; /* @@ -1546,7 +1546,7 @@ const struct inode_operations reiserfs_symlink_inode_operations = { .listxattr = reiserfs_listxattr, .removexattr = reiserfs_removexattr, .permission = reiserfs_permission, - .check_acl = reiserfs_check_acl, + .get_acl = reiserfs_get_acl, }; @@ -1560,5 +1560,5 @@ const struct inode_operations reiserfs_special_inode_operations = { .listxattr = reiserfs_listxattr, .removexattr = reiserfs_removexattr, .permission = reiserfs_permission, - .check_acl = reiserfs_check_acl, + .get_acl = reiserfs_get_acl, }; diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 7ba083eb62b..6bc346c160e 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -867,24 +867,6 @@ out: return err; } -int reiserfs_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl; - int error = -EAGAIN; /* do regular unix permission checks by default */ - - acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); - - if (acl) { - if (!IS_ERR(acl)) { - error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - } else if (PTR_ERR(acl) != -ENODATA) - error = PTR_ERR(acl); - } - - return error; -} - static int create_privroot(struct dentry *dentry) { int err; diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index 2827bbd8366..44ce5165680 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c @@ -114,6 +114,8 @@ xfs_get_acl(struct inode *inode, int type) if (acl != ACL_NOT_CACHED) return acl; + trace_xfs_get_acl(ip); + switch (type) { case ACL_TYPE_ACCESS: ea_name = SGI_ACL_FILE; @@ -218,25 +220,6 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) return error; } -int -xfs_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl; - int error = -EAGAIN; - - trace_xfs_check_acl(XFS_I(inode)); - - acl = xfs_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - } - - return error; -} - static int xfs_set_mode(struct inode *inode, mode_t mode) { diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 77463dd5519..6544c3236bc 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -1022,7 +1022,7 @@ xfs_vn_fiemap( } static const struct inode_operations xfs_inode_operations = { - .check_acl = xfs_check_acl, + .get_acl = xfs_get_acl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1048,7 +1048,7 @@ static const struct inode_operations xfs_dir_inode_operations = { .rmdir = xfs_vn_unlink, .mknod = xfs_vn_mknod, .rename = xfs_vn_rename, - .check_acl = xfs_check_acl, + .get_acl = xfs_get_acl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1073,7 +1073,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { .rmdir = xfs_vn_unlink, .mknod = xfs_vn_mknod, .rename = xfs_vn_rename, - .check_acl = xfs_check_acl, + .get_acl = xfs_get_acl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1086,7 +1086,7 @@ static const struct inode_operations xfs_symlink_inode_operations = { .readlink = generic_readlink, .follow_link = xfs_vn_follow_link, .put_link = xfs_vn_put_link, - .check_acl = xfs_check_acl, + .get_acl = xfs_get_acl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index fda0708ef2e..690fc7a7bd7 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -571,7 +571,7 @@ DEFINE_INODE_EVENT(xfs_alloc_file_space); DEFINE_INODE_EVENT(xfs_free_file_space); DEFINE_INODE_EVENT(xfs_readdir); #ifdef CONFIG_XFS_POSIX_ACL -DEFINE_INODE_EVENT(xfs_check_acl); +DEFINE_INODE_EVENT(xfs_get_acl); #endif DEFINE_INODE_EVENT(xfs_vm_bmap); DEFINE_INODE_EVENT(xfs_file_ioctl); diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 0135e2a669d..2c656ef4947 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -42,7 +42,6 @@ struct xfs_acl { #define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1) #ifdef CONFIG_XFS_POSIX_ACL -extern int xfs_check_acl(struct inode *inode, int mask); extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); extern int xfs_acl_chmod(struct inode *inode); @@ -52,7 +51,6 @@ extern int posix_acl_default_exists(struct inode *inode); extern const struct xattr_handler xfs_xattr_acl_access_handler; extern const struct xattr_handler xfs_xattr_acl_default_handler; #else -# define xfs_check_acl NULL # define xfs_get_acl(inode, type) NULL # define xfs_inherit_acl(inode, default_acl) 0 # define xfs_acl_chmod(inode) 0 diff --git a/include/linux/fs.h b/include/linux/fs.h index 7a757a48a5c..12f84b30c3c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1586,7 +1586,7 @@ struct inode_operations { struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); void * (*follow_link) (struct dentry *, struct nameidata *); int (*permission) (struct inode *, int); - int (*check_acl)(struct inode *, int); + struct posix_acl * (*get_acl)(struct inode *, int); int (*readlink) (struct dentry *, char __user *,int); void (*put_link) (struct dentry *, struct nameidata *, void *); diff --git a/include/linux/generic_acl.h b/include/linux/generic_acl.h index 574bea4013b..b6d657544ef 100644 --- a/include/linux/generic_acl.h +++ b/include/linux/generic_acl.h @@ -10,6 +10,5 @@ extern const struct xattr_handler generic_acl_default_handler; int generic_acl_init(struct inode *, struct inode *); int generic_acl_chmod(struct inode *); -int generic_check_acl(struct inode *inode, int mask); #endif /* LINUX_GENERIC_ACL_H */ diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h index 3fd8c4506bb..f096b80e73d 100644 --- a/include/linux/reiserfs_acl.h +++ b/include/linux/reiserfs_acl.h @@ -59,11 +59,7 @@ extern const struct xattr_handler reiserfs_posix_acl_access_handler; #else #define reiserfs_cache_default_acl(inode) 0 - -static inline struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) -{ - return NULL; -} +#define reiserfs_get_acl NULL static inline int reiserfs_acl_chmod(struct inode *inode) { diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index 57958c0e1d3..c2b71473266 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h @@ -45,7 +45,6 @@ int reiserfs_permission(struct inode *inode, int mask); #ifdef CONFIG_REISERFS_FS_XATTR #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir) -int reiserfs_check_acl(struct inode *inode, int mask); ssize_t reiserfs_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); int reiserfs_setxattr(struct dentry *dentry, const char *name, @@ -123,7 +122,6 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode) #define reiserfs_setxattr NULL #define reiserfs_listxattr NULL #define reiserfs_removexattr NULL -#define reiserfs_check_acl NULL static inline void reiserfs_init_xattr_rwsem(struct inode *inode) { diff --git a/mm/shmem.c b/mm/shmem.c index fcedf5464eb..3e519798b52 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2715,10 +2715,6 @@ static const struct inode_operations shmem_inode_operations = { .listxattr = shmem_listxattr, .removexattr = shmem_removexattr, #endif -#ifdef CONFIG_TMPFS_POSIX_ACL - .check_acl = generic_check_acl, -#endif - }; static const struct inode_operations shmem_dir_inode_operations = { @@ -2741,7 +2737,6 @@ static const struct inode_operations shmem_dir_inode_operations = { #endif #ifdef CONFIG_TMPFS_POSIX_ACL .setattr = shmem_setattr, - .check_acl = generic_check_acl, #endif }; @@ -2754,7 +2749,6 @@ static const struct inode_operations shmem_special_inode_operations = { #endif #ifdef CONFIG_TMPFS_POSIX_ACL .setattr = shmem_setattr, - .check_acl = generic_check_acl, #endif }; -- cgit v1.2.3-70-g09d2