From b5450d9c84bdd38b261922057cd167da51dfae93 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 19 Jun 2009 10:30:07 +0200 Subject: reiserfs: remove stray unlock_super in reiserfs_resize Reiserfs doesn't use lock_super anywhere internally, and ->remount_fs which calls reiserfs_resize does have it currently but also expects it to be held on return, so there's no business for the unlock_super here. Signed-off-by: Christoph Hellwig Acked by Edward Shishkin Signed-off-by: Al Viro --- fs/reiserfs/resize.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 238e9d9b31e0..18b315d3d104 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c @@ -82,7 +82,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) if (reiserfs_allocate_list_bitmaps(s, jbitmap, bmap_nr_new) < 0) { printk ("reiserfs_resize: unable to allocate memory for journal bitmaps\n"); - unlock_super(s); return -ENOMEM; } /* the new journal bitmaps are zero filled, now we copy in the bitmap -- cgit v1.2.3 From 654f562c526cf9dfb8d453f687341fe0777ee454 Mon Sep 17 00:00:00 2001 From: "J. R. Okajima" Date: Thu, 18 Jun 2009 23:30:15 +0900 Subject: vfs: fix nd->root leak in do_filp_open() commit 2a737871108de9ba8930f7650d549f1383767f8b "Cache root in nameidata" introduced a new member nd->root, but forgot to put it in do_filp_open(). Signed-off-by: J. R. Okajima Signed-off-by: Al Viro --- fs/namei.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index 527119afb6a5..5b961eb71cbf 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1698,8 +1698,11 @@ struct file *do_filp_open(int dfd, const char *pathname, if (error) return ERR_PTR(error); error = path_walk(pathname, &nd); - if (error) + if (error) { + if (nd.root.mnt) + path_put(&nd.root); return ERR_PTR(error); + } if (unlikely(!audit_dummy_context())) audit_inode(pathname, nd.path.dentry); @@ -1759,6 +1762,8 @@ do_last: } filp = nameidata_to_filp(&nd, open_flag); mnt_drop_write(nd.path.mnt); + if (nd.root.mnt) + path_put(&nd.root); return filp; } @@ -1819,6 +1824,8 @@ ok: */ if (will_write) mnt_drop_write(nd.path.mnt); + if (nd.root.mnt) + path_put(&nd.root); return filp; exit_mutex_unlock: @@ -1859,6 +1866,8 @@ do_link: * with "intent.open". */ release_open_intent(&nd); + if (nd.root.mnt) + path_put(&nd.root); return ERR_PTR(error); } nd.flags &= ~LOOKUP_PARENT; -- cgit v1.2.3 From 3b22edc5730b87d360ee7dd7143397ba09b73a47 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 23 Jun 2009 17:29:49 -0400 Subject: VFS: Switch init_mount_tree() to use the new create_mnt_ns() helper Eliminates some duplicated code... Signed-off-by: Trond Myklebust Signed-off-by: Al Viro --- fs/namespace.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index a7bea8c8bd46..4a86b8595164 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2222,16 +2222,9 @@ static void __init init_mount_tree(void) mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); if (IS_ERR(mnt)) panic("Can't create rootfs"); - ns = kmalloc(sizeof(*ns), GFP_KERNEL); - if (!ns) + ns = create_mnt_ns(mnt); + if (IS_ERR(ns)) panic("Can't allocate initial namespace"); - atomic_set(&ns->count, 1); - INIT_LIST_HEAD(&ns->list); - init_waitqueue_head(&ns->poll); - ns->event = 0; - list_add(&mnt->mnt_list, &ns->list); - ns->root = mnt; - mnt->mnt_ns = ns; init_task.nsproxy->mnt_ns = ns; get_mnt_ns(ns); -- cgit v1.2.3 From f6cc746bbb3b8a8ceb8514a7906ba582607a8cf7 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 16 Jun 2009 21:15:04 -0700 Subject: devpts: remove module-related code These days, the devpts filesystem is closely integrated with the pty memory management, and cannot be built as a module, even less removed from the kernel. Accordingly, remove all module-related stuff from this filesystem. [ v2: only remove code that's actually dead ] Signed-off-by: H. Peter Anvin Signed-off-by: Al Viro --- fs/devpts/inode.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 9b1d285f9fe6..75efb028974b 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -423,7 +423,6 @@ static void devpts_kill_sb(struct super_block *sb) } static struct file_system_type devpts_fs_type = { - .owner = THIS_MODULE, .name = "devpts", .get_sb = devpts_get_sb, .kill_sb = devpts_kill_sb, @@ -564,13 +563,4 @@ static int __init init_devpts_fs(void) } return err; } - -static void __exit exit_devpts_fs(void) -{ - unregister_filesystem(&devpts_fs_type); - mntput(devpts_mnt); -} - module_init(init_devpts_fs) -module_exit(exit_devpts_fs) -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 7e325d3a6b117c7288bfc0755410e9d9d2b71326 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 19 Jun 2009 20:22:37 +0200 Subject: update Documentation/filesystems/Locking The rules for locking in many superblock operations has changed significantly, so update the documentation for it. Also correct some older updates and ommissions. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- Documentation/filesystems/Locking | 43 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 229d7b7c50a3..18b9d0ca0630 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -109,27 +109,28 @@ prototypes: locking rules: All may block. - BKL s_lock s_umount -alloc_inode: no no no -destroy_inode: no -dirty_inode: no (must not sleep) -write_inode: no -drop_inode: no !!!inode_lock!!! -delete_inode: no -put_super: yes yes no -write_super: no yes read -sync_fs: no no read -freeze_fs: ? -unfreeze_fs: ? -statfs: no no no -remount_fs: yes yes maybe (see below) -clear_inode: no -umount_begin: yes no no -show_options: no (vfsmount->sem) -quota_read: no no no (see below) -quota_write: no no no (see below) - -->remount_fs() will have the s_umount lock if it's already mounted. + None have BKL + s_umount +alloc_inode: +destroy_inode: +dirty_inode: (must not sleep) +write_inode: +drop_inode: !!!inode_lock!!! +delete_inode: +put_super: write +write_super: read +sync_fs: read +freeze_fs: read +unfreeze_fs: read +statfs: no +remount_fs: maybe (see below) +clear_inode: +umount_begin: no +show_options: no (namespace_sem) +quota_read: no (see below) +quota_write: no (see below) + +->remount_fs() will have the s_umount exclusive lock if it's already mounted. When called from get_sb_single, it does NOT have the s_umount lock. ->quota_read() and ->quota_write() functions are both guaranteed to be the only ones operating on the quota file by the quota code (via -- cgit v1.2.3 From c63e09ecccb50f930e899d7005edc5411ee86d4f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 24 Jun 2009 02:05:18 -0400 Subject: Make allocation of anon devices cheaper Standard trick - add a new variable (start) such that for each n < start n is known to be busy. Allocation can skip checking everything in [0..start) and if it returns n, we can set start to n + 1. Freeing below start sets start to what we'd just freed. Of course, it still sucks if we do something like free 0 allocate allocate in a loop - still O(n^2) time. However, on saner loads it improves the things a lot and the entire thing is not worth the trouble of switching to something with better worst-case behaviour. Signed-off-by: Al Viro --- fs/super.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/super.c b/fs/super.c index d40d53a22fb5..808ffd59e01b 100644 --- a/fs/super.c +++ b/fs/super.c @@ -608,6 +608,7 @@ void emergency_remount(void) static DEFINE_IDA(unnamed_dev_ida); static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */ +static int unnamed_dev_start = 0; /* don't bother trying below it */ int set_anon_super(struct super_block *s, void *data) { @@ -618,7 +619,8 @@ int set_anon_super(struct super_block *s, void *data) if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0) return -ENOMEM; spin_lock(&unnamed_dev_lock); - error = ida_get_new(&unnamed_dev_ida, &dev); + error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev); + unnamed_dev_start = dev + 1; spin_unlock(&unnamed_dev_lock); if (error == -EAGAIN) /* We raced and lost with another CPU. */ @@ -629,6 +631,7 @@ int set_anon_super(struct super_block *s, void *data) if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) { spin_lock(&unnamed_dev_lock); ida_remove(&unnamed_dev_ida, dev); + unnamed_dev_start = dev; spin_unlock(&unnamed_dev_lock); return -EMFILE; } @@ -645,6 +648,8 @@ void kill_anon_super(struct super_block *sb) generic_shutdown_super(sb); spin_lock(&unnamed_dev_lock); ida_remove(&unnamed_dev_ida, slot); + if (slot < unnamed_dev_start) + unnamed_dev_start = slot; spin_unlock(&unnamed_dev_lock); } -- cgit v1.2.3 From f21f62208a6f60e2e05440b2e438d9541822dc4d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 24 Jun 2009 03:12:00 -0400 Subject: ... and the same for vfsmount id/mount group id Signed-off-by: Al Viro --- fs/namespace.c | 26 ++++++++++++++++++++++---- fs/super.c | 6 ++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 4a86b8595164..3dc283fd4716 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -42,6 +42,8 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); static int event; static DEFINE_IDA(mnt_id_ida); static DEFINE_IDA(mnt_group_ida); +static int mnt_id_start = 0; +static int mnt_group_start = 1; static struct list_head *mount_hashtable __read_mostly; static struct kmem_cache *mnt_cache __read_mostly; @@ -69,7 +71,9 @@ static int mnt_alloc_id(struct vfsmount *mnt) retry: ida_pre_get(&mnt_id_ida, GFP_KERNEL); spin_lock(&vfsmount_lock); - res = ida_get_new(&mnt_id_ida, &mnt->mnt_id); + res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id); + if (!res) + mnt_id_start = mnt->mnt_id + 1; spin_unlock(&vfsmount_lock); if (res == -EAGAIN) goto retry; @@ -79,8 +83,11 @@ retry: static void mnt_free_id(struct vfsmount *mnt) { + int id = mnt->mnt_id; spin_lock(&vfsmount_lock); - ida_remove(&mnt_id_ida, mnt->mnt_id); + ida_remove(&mnt_id_ida, id); + if (mnt_id_start > id) + mnt_id_start = id; spin_unlock(&vfsmount_lock); } @@ -91,10 +98,18 @@ static void mnt_free_id(struct vfsmount *mnt) */ static int mnt_alloc_group_id(struct vfsmount *mnt) { + int res; + if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL)) return -ENOMEM; - return ida_get_new_above(&mnt_group_ida, 1, &mnt->mnt_group_id); + res = ida_get_new_above(&mnt_group_ida, + mnt_group_start, + &mnt->mnt_group_id); + if (!res) + mnt_group_start = mnt->mnt_group_id + 1; + + return res; } /* @@ -102,7 +117,10 @@ static int mnt_alloc_group_id(struct vfsmount *mnt) */ void mnt_release_group_id(struct vfsmount *mnt) { - ida_remove(&mnt_group_ida, mnt->mnt_group_id); + int id = mnt->mnt_group_id; + ida_remove(&mnt_group_ida, id); + if (mnt_group_start > id) + mnt_group_start = id; mnt->mnt_group_id = 0; } diff --git a/fs/super.c b/fs/super.c index 808ffd59e01b..2761d3e22ed9 100644 --- a/fs/super.c +++ b/fs/super.c @@ -620,7 +620,8 @@ int set_anon_super(struct super_block *s, void *data) return -ENOMEM; spin_lock(&unnamed_dev_lock); error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev); - unnamed_dev_start = dev + 1; + if (!error) + unnamed_dev_start = dev + 1; spin_unlock(&unnamed_dev_lock); if (error == -EAGAIN) /* We raced and lost with another CPU. */ @@ -631,7 +632,8 @@ int set_anon_super(struct super_block *s, void *data) if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) { spin_lock(&unnamed_dev_lock); ida_remove(&unnamed_dev_ida, dev); - unnamed_dev_start = dev; + if (unnamed_dev_start > dev) + unnamed_dev_start = dev; spin_unlock(&unnamed_dev_lock); return -EMFILE; } -- cgit v1.2.3 From 01c031945f2755c7afaaf456088543312f2b72ea Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 8 Jun 2009 13:35:40 +0200 Subject: cleanup __writeback_single_inode There is no reason to for the split between __writeback_single_inode and __sync_single_inode, the former just does a couple of checks before tail-calling the latter. So merge the two, and while we're at it split out the I_SYNC waiting case for data integrity writers, as it's logically separate function. Finally rename __writeback_single_inode to writeback_single_inode. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/fs-writeback.c | 100 +++++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index caf049146ca2..c54226be5294 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -278,7 +278,26 @@ int sb_has_dirty_inodes(struct super_block *sb) EXPORT_SYMBOL(sb_has_dirty_inodes); /* - * Write a single inode's dirty pages and inode data out to disk. + * Wait for writeback on an inode to complete. + */ +static void inode_wait_for_writeback(struct inode *inode) +{ + DEFINE_WAIT_BIT(wq, &inode->i_state, __I_SYNC); + wait_queue_head_t *wqh; + + wqh = bit_waitqueue(&inode->i_state, __I_SYNC); + do { + spin_unlock(&inode_lock); + __wait_on_bit(wqh, &wq, inode_wait, TASK_UNINTERRUPTIBLE); + spin_lock(&inode_lock); + } while (inode->i_state & I_SYNC); +} + +/* + * Write out an inode's dirty pages. Called under inode_lock. Either the + * caller has ref on the inode (either via __iget or via syscall against an fd) + * or the inode has I_WILL_FREE set (via generic_forget_inode) + * * If `wait' is set, wait on the writeout. * * The whole writeout design is quite complex and fragile. We want to avoid @@ -288,13 +307,38 @@ EXPORT_SYMBOL(sb_has_dirty_inodes); * Called under inode_lock. */ static int -__sync_single_inode(struct inode *inode, struct writeback_control *wbc) +writeback_single_inode(struct inode *inode, struct writeback_control *wbc) { - unsigned dirty; struct address_space *mapping = inode->i_mapping; int wait = wbc->sync_mode == WB_SYNC_ALL; + unsigned dirty; int ret; + if (!atomic_read(&inode->i_count)) + WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING))); + else + WARN_ON(inode->i_state & I_WILL_FREE); + + if (inode->i_state & I_SYNC) { + /* + * If this inode is locked for writeback and we are not doing + * writeback-for-data-integrity, move it to s_more_io so that + * writeback can proceed with the other inodes on s_io. + * + * We'll have another go at writing back this inode when we + * completed a full scan of s_io. + */ + if (!wait) { + requeue_io(inode); + return 0; + } + + /* + * It's a data-integrity sync. We must wait. + */ + inode_wait_for_writeback(inode); + } + BUG_ON(inode->i_state & I_SYNC); /* Set I_SYNC, reset I_DIRTY */ @@ -389,50 +433,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc) return ret; } -/* - * Write out an inode's dirty pages. Called under inode_lock. Either the - * caller has ref on the inode (either via __iget or via syscall against an fd) - * or the inode has I_WILL_FREE set (via generic_forget_inode) - */ -static int -__writeback_single_inode(struct inode *inode, struct writeback_control *wbc) -{ - wait_queue_head_t *wqh; - - if (!atomic_read(&inode->i_count)) - WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING))); - else - WARN_ON(inode->i_state & I_WILL_FREE); - - if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_SYNC)) { - /* - * We're skipping this inode because it's locked, and we're not - * doing writeback-for-data-integrity. Move it to s_more_io so - * that writeback can proceed with the other inodes on s_io. - * We'll have another go at writing back this inode when we - * completed a full scan of s_io. - */ - requeue_io(inode); - return 0; - } - - /* - * It's a data-integrity sync. We must wait. - */ - if (inode->i_state & I_SYNC) { - DEFINE_WAIT_BIT(wq, &inode->i_state, __I_SYNC); - - wqh = bit_waitqueue(&inode->i_state, __I_SYNC); - do { - spin_unlock(&inode_lock); - __wait_on_bit(wqh, &wq, inode_wait, - TASK_UNINTERRUPTIBLE); - spin_lock(&inode_lock); - } while (inode->i_state & I_SYNC); - } - return __sync_single_inode(inode, wbc); -} - /* * Write out a superblock's list of dirty inodes. A wait will be performed * upon no inodes, all inodes or the final one, depending upon sync_mode. @@ -526,7 +526,7 @@ void generic_sync_sb_inodes(struct super_block *sb, BUG_ON(inode->i_state & (I_FREEING | I_CLEAR)); __iget(inode); pages_skipped = wbc->pages_skipped; - __writeback_single_inode(inode, wbc); + writeback_single_inode(inode, wbc); if (current_is_pdflush()) writeback_release(bdi); if (wbc->pages_skipped != pages_skipped) { @@ -708,7 +708,7 @@ int write_inode_now(struct inode *inode, int sync) might_sleep(); spin_lock(&inode_lock); - ret = __writeback_single_inode(inode, &wbc); + ret = writeback_single_inode(inode, &wbc); spin_unlock(&inode_lock); if (sync) inode_sync_wait(inode); @@ -732,7 +732,7 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc) int ret; spin_lock(&inode_lock); - ret = __writeback_single_inode(inode, wbc); + ret = writeback_single_inode(inode, wbc); spin_unlock(&inode_lock); return ret; } -- cgit v1.2.3 From 3e63cbb1efca7dd3137de1bb475e2e068e38ef23 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Fri, 19 Jun 2009 14:28:07 -0400 Subject: fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls This patch adds ioctls to vfs for compatibility with legacy XFS pre-allocation ioctls (XFS_IOC_*RESVP*). The implementation effectively invokes sys_fallocate for the new ioctls. Also handles the compat_ioctl case. Note: These legacy ioctls are also implemented by OCFS2. [AV: folded fixes from hch] Signed-off-by: Ankit Jain Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/compat_ioctl.c | 48 +++++++++++++++++++++++++++++++++++++++++ fs/ioctl.c | 35 ++++++++++++++++++++++++++++++ fs/open.c | 58 +++++++++++++++++++++++++------------------------- include/linux/falloc.h | 21 ++++++++++++++++++ include/linux/fs.h | 6 ++++++ 5 files changed, 139 insertions(+), 29 deletions(-) diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index c135202c38b3..626c7483b4de 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1779,6 +1780,41 @@ lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) return sys_ioctl(fd, cmd, (unsigned long)tn); } +/* on ia32 l_start is on a 32-bit boundary */ +#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) +struct space_resv_32 { + __s16 l_type; + __s16 l_whence; + __s64 l_start __attribute__((packed)); + /* len == 0 means until end of file */ + __s64 l_len __attribute__((packed)); + __s32 l_sysid; + __u32 l_pid; + __s32 l_pad[4]; /* reserve area */ +}; + +#define FS_IOC_RESVSP_32 _IOW ('X', 40, struct space_resv_32) +#define FS_IOC_RESVSP64_32 _IOW ('X', 42, struct space_resv_32) + +/* just account for different alignment */ +static int compat_ioctl_preallocate(struct file *file, unsigned long arg) +{ + struct space_resv_32 __user *p32 = (void __user *)arg; + struct space_resv __user *p = compat_alloc_user_space(sizeof(*p)); + + if (copy_in_user(&p->l_type, &p32->l_type, sizeof(s16)) || + copy_in_user(&p->l_whence, &p32->l_whence, sizeof(s16)) || + copy_in_user(&p->l_start, &p32->l_start, sizeof(s64)) || + copy_in_user(&p->l_len, &p32->l_len, sizeof(s64)) || + copy_in_user(&p->l_sysid, &p32->l_sysid, sizeof(s32)) || + copy_in_user(&p->l_pid, &p32->l_pid, sizeof(u32)) || + copy_in_user(&p->l_pad, &p32->l_pad, 4*sizeof(u32))) + return -EFAULT; + + return ioctl_preallocate(file, p); +} +#endif + typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int, unsigned long, struct file *); @@ -2756,6 +2792,18 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, case FIOQSIZE: break; +#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) + case FS_IOC_RESVSP_32: + case FS_IOC_RESVSP64_32: + error = compat_ioctl_preallocate(filp, arg); + goto out_fput; +#else + case FS_IOC_RESVSP: + case FS_IOC_RESVSP64: + error = ioctl_preallocate(filp, (void __user *)arg); + goto out_fput; +#endif + case FIBMAP: case FIGETBSZ: case FIONREAD: diff --git a/fs/ioctl.c b/fs/ioctl.c index 001f8d3118f2..5612880fcbe7 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -403,6 +404,37 @@ EXPORT_SYMBOL(generic_block_fiemap); #endif /* CONFIG_BLOCK */ +/* + * This provides compatibility with legacy XFS pre-allocation ioctls + * which predate the fallocate syscall. + * + * Only the l_start, l_len and l_whence fields of the 'struct space_resv' + * are used here, rest are ignored. + */ +int ioctl_preallocate(struct file *filp, void __user *argp) +{ + struct inode *inode = filp->f_path.dentry->d_inode; + struct space_resv sr; + + if (copy_from_user(&sr, argp, sizeof(sr))) + return -EFAULT; + + switch (sr.l_whence) { + case SEEK_SET: + break; + case SEEK_CUR: + sr.l_start += filp->f_pos; + break; + case SEEK_END: + sr.l_start += i_size_read(inode); + break; + default: + return -EINVAL; + } + + return do_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len); +} + static int file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -414,6 +446,9 @@ static int file_ioctl(struct file *filp, unsigned int cmd, return ioctl_fibmap(filp, p); case FIONREAD: return put_user(i_size_read(inode) - filp->f_pos, p); + case FS_IOC_RESVSP: + case FS_IOC_RESVSP64: + return ioctl_preallocate(filp, p); } return vfs_ioctl(filp, cmd, arg); diff --git a/fs/open.c b/fs/open.c index 7200e23d9258..dd98e8076024 100644 --- a/fs/open.c +++ b/fs/open.c @@ -378,63 +378,63 @@ SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64); #endif #endif /* BITS_PER_LONG == 32 */ -SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) + +int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) { - struct file *file; - struct inode *inode; - long ret = -EINVAL; + struct inode *inode = file->f_path.dentry->d_inode; + long ret; if (offset < 0 || len <= 0) - goto out; + return -EINVAL; /* Return error if mode is not supported */ - ret = -EOPNOTSUPP; if (mode && !(mode & FALLOC_FL_KEEP_SIZE)) - goto out; + return -EOPNOTSUPP; - ret = -EBADF; - file = fget(fd); - if (!file) - goto out; if (!(file->f_mode & FMODE_WRITE)) - goto out_fput; + return -EBADF; /* * Revalidate the write permissions, in case security policy has * changed since the files were opened. */ ret = security_file_permission(file, MAY_WRITE); if (ret) - goto out_fput; + return ret; - inode = file->f_path.dentry->d_inode; - - ret = -ESPIPE; if (S_ISFIFO(inode->i_mode)) - goto out_fput; + return -ESPIPE; - ret = -ENODEV; /* * Let individual file system decide if it supports preallocation * for directories or not. */ if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) - goto out_fput; + return -ENODEV; - ret = -EFBIG; /* Check for wrap through zero too */ if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) - goto out_fput; + return -EFBIG; - if (inode->i_op->fallocate) - ret = inode->i_op->fallocate(inode, mode, offset, len); - else - ret = -EOPNOTSUPP; + if (!inode->i_op->fallocate) + return -EOPNOTSUPP; -out_fput: - fput(file); -out: - return ret; + return inode->i_op->fallocate(inode, mode, offset, len); } + +SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) +{ + struct file *file; + int error = -EBADF; + + file = fget(fd); + if (file) { + error = do_fallocate(file, mode, offset, len); + fput(file); + } + + return error; +} + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len) { diff --git a/include/linux/falloc.h b/include/linux/falloc.h index 8e912ab6a072..3c155107d61f 100644 --- a/include/linux/falloc.h +++ b/include/linux/falloc.h @@ -3,4 +3,25 @@ #define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */ +#ifdef __KERNEL__ + +/* + * Space reservation ioctls and argument structure + * are designed to be compatible with the legacy XFS ioctls. + */ +struct space_resv { + __s16 l_type; + __s16 l_whence; + __s64 l_start; + __s64 l_len; /* len == 0 means until end of file */ + __s32 l_sysid; + __u32 l_pid; + __s32 l_pad[4]; /* reserved area */ +}; + +#define FS_IOC_RESVSP _IOW('X', 40, struct space_resv) +#define FS_IOC_RESVSP64 _IOW('X', 42, struct space_resv) + +#endif /* __KERNEL__ */ + #endif /* _FALLOC_H_ */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 1ff5e4e01952..79e302ddde0f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1906,6 +1906,8 @@ static inline int break_lease(struct inode *inode, unsigned int mode) extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, struct file *filp); +extern int do_fallocate(struct file *file, int mode, loff_t offset, + loff_t len); extern long do_sys_open(int dfd, const char __user *filename, int flags, int mode); extern struct file *filp_open(const char *, int, int); @@ -1914,6 +1916,10 @@ extern struct file * dentry_open(struct dentry *, struct vfsmount *, int, extern int filp_close(struct file *, fl_owner_t id); extern char * getname(const char __user *); +/* fs/ioctl.c */ + +extern int ioctl_preallocate(struct file *filp, void __user *argp); + /* fs/dcache.c */ extern void __init vfs_caches_init_early(void); extern void __init vfs_caches_init(unsigned long); -- cgit v1.2.3 From f19d4a8fa6f9b6ccf54df0971c97ffcaa390b7b0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 19:50:45 -0400 Subject: add caching of ACLs in struct inode No helpers, no conversions yet. Signed-off-by: Al Viro --- fs/inode.c | 10 ++++++++++ include/linux/fs.h | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/fs/inode.c b/fs/inode.c index f643be565df8..e193cd592fa8 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -25,6 +25,7 @@ #include #include #include +#include /* * This is needed for the following functions: @@ -189,6 +190,9 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode) } inode->i_private = NULL; inode->i_mapping = mapping; +#ifdef CONFIG_FS_POSIX_ACL + inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; +#endif #ifdef CONFIG_FSNOTIFY inode->i_fsnotify_mask = 0; @@ -227,6 +231,12 @@ void destroy_inode(struct inode *inode) ima_inode_free(inode); security_inode_free(inode); fsnotify_inode_delete(inode); +#ifdef CONFIG_FS_POSIX_ACL + if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) + posix_acl_release(inode->i_acl); + if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) + posix_acl_release(inode->i_default_acl); +#endif if (inode->i_sb->s_op->destroy_inode) inode->i_sb->s_op->destroy_inode(inode); else diff --git a/include/linux/fs.h b/include/linux/fs.h index 79e302ddde0f..0872372184fe 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -710,6 +710,9 @@ static inline int mapping_writably_mapped(struct address_space *mapping) #define i_size_ordered_init(inode) do { } while (0) #endif +struct posix_acl; +#define ACL_NOT_CACHED ((void *)(-1)) + struct inode { struct hlist_node i_hash; struct list_head i_list; @@ -772,6 +775,10 @@ struct inode { atomic_t i_writecount; #ifdef CONFIG_SECURITY void *i_security; +#endif +#ifdef CONFIG_FS_POSIX_ACL + struct posix_acl *i_acl; + struct posix_acl *i_default_acl; #endif void *i_private; /* fs or device private pointer */ }; -- cgit v1.2.3 From 5e78b435683daaaacadad1b2aeefb8904cf6acfb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 19:52:55 -0400 Subject: switch ext2 to inode->i_acl Signed-off-by: Al Viro --- fs/ext2/acl.c | 24 +++++++++++------------- fs/ext2/acl.h | 4 ---- fs/ext2/ext2.h | 4 ---- fs/ext2/inode.c | 4 ---- fs/ext2/super.c | 16 ---------------- 5 files changed, 11 insertions(+), 41 deletions(-) diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index d46e38cb85c5..d2ffddc12117 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -128,10 +128,10 @@ fail: static inline struct posix_acl * ext2_iget_acl(struct inode *inode, struct posix_acl **i_acl) { - struct posix_acl *acl = EXT2_ACL_NOT_CACHED; + struct posix_acl *acl = ACL_NOT_CACHED; spin_lock(&inode->i_lock); - if (*i_acl != EXT2_ACL_NOT_CACHED) + if (*i_acl != ACL_NOT_CACHED) acl = posix_acl_dup(*i_acl); spin_unlock(&inode->i_lock); @@ -143,7 +143,7 @@ ext2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct posix_acl *acl) { spin_lock(&inode->i_lock); - if (*i_acl != EXT2_ACL_NOT_CACHED) + if (*i_acl != ACL_NOT_CACHED) posix_acl_release(*i_acl); *i_acl = posix_acl_dup(acl); spin_unlock(&inode->i_lock); @@ -155,7 +155,6 @@ ext2_iset_acl(struct inode *inode, struct posix_acl **i_acl, static struct posix_acl * ext2_get_acl(struct inode *inode, int type) { - struct ext2_inode_info *ei = EXT2_I(inode); int name_index; char *value = NULL; struct posix_acl *acl; @@ -166,15 +165,15 @@ ext2_get_acl(struct inode *inode, int type) switch(type) { case ACL_TYPE_ACCESS: - acl = ext2_iget_acl(inode, &ei->i_acl); - if (acl != EXT2_ACL_NOT_CACHED) + acl = ext2_iget_acl(inode, &inode->i_acl); + if (acl != ACL_NOT_CACHED) return acl; name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: - acl = ext2_iget_acl(inode, &ei->i_default_acl); - if (acl != EXT2_ACL_NOT_CACHED) + acl = ext2_iget_acl(inode, &inode->i_default_acl); + if (acl != ACL_NOT_CACHED) return acl; name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT; break; @@ -200,11 +199,11 @@ ext2_get_acl(struct inode *inode, int type) if (!IS_ERR(acl)) { switch(type) { case ACL_TYPE_ACCESS: - ext2_iset_acl(inode, &ei->i_acl, acl); + ext2_iset_acl(inode, &inode->i_acl, acl); break; case ACL_TYPE_DEFAULT: - ext2_iset_acl(inode, &ei->i_default_acl, acl); + ext2_iset_acl(inode, &inode->i_default_acl, acl); break; } } @@ -217,7 +216,6 @@ ext2_get_acl(struct inode *inode, int type) static int ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) { - struct ext2_inode_info *ei = EXT2_I(inode); int name_index; void *value = NULL; size_t size = 0; @@ -266,11 +264,11 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) if (!error) { switch(type) { case ACL_TYPE_ACCESS: - ext2_iset_acl(inode, &ei->i_acl, acl); + ext2_iset_acl(inode, &inode->i_acl, acl); break; case ACL_TYPE_DEFAULT: - ext2_iset_acl(inode, &ei->i_default_acl, acl); + ext2_iset_acl(inode, &inode->i_default_acl, acl); break; } } diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h index b42cf578554b..ecefe478898f 100644 --- a/fs/ext2/acl.h +++ b/fs/ext2/acl.h @@ -53,10 +53,6 @@ static inline int ext2_acl_count(size_t size) #ifdef CONFIG_EXT2_FS_POSIX_ACL -/* Value for inode->u.ext2_i.i_acl and inode->u.ext2_i.i_default_acl - if the ACL has not been cached */ -#define EXT2_ACL_NOT_CACHED ((void *)-1) - /* acl.c */ extern int ext2_permission (struct inode *, int); extern int ext2_acl_chmod (struct inode *); diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index d988a718aedb..9a8a8e27a063 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -46,10 +46,6 @@ struct ext2_inode_info { * EAs. */ struct rw_semaphore xattr_sem; -#endif -#ifdef CONFIG_EXT2_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; #endif rwlock_t i_meta_lock; diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 29ed682061f6..e27130341d4f 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -1224,10 +1224,6 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino) return inode; ei = EXT2_I(inode); -#ifdef CONFIG_EXT2_FS_POSIX_ACL - ei->i_acl = EXT2_ACL_NOT_CACHED; - ei->i_default_acl = EXT2_ACL_NOT_CACHED; -#endif ei->i_block_alloc_info = NULL; raw_inode = ext2_get_inode(inode->i_sb, ino, &bh); diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 458999638c3d..1a9ffee47d56 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -152,10 +152,6 @@ static struct inode *ext2_alloc_inode(struct super_block *sb) ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, GFP_KERNEL); if (!ei) return NULL; -#ifdef CONFIG_EXT2_FS_POSIX_ACL - ei->i_acl = EXT2_ACL_NOT_CACHED; - ei->i_default_acl = EXT2_ACL_NOT_CACHED; -#endif ei->i_block_alloc_info = NULL; ei->vfs_inode.i_version = 1; return &ei->vfs_inode; @@ -198,18 +194,6 @@ static void destroy_inodecache(void) static void ext2_clear_inode(struct inode *inode) { struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info; -#ifdef CONFIG_EXT2_FS_POSIX_ACL - struct ext2_inode_info *ei = EXT2_I(inode); - - if (ei->i_acl && ei->i_acl != EXT2_ACL_NOT_CACHED) { - posix_acl_release(ei->i_acl); - ei->i_acl = EXT2_ACL_NOT_CACHED; - } - if (ei->i_default_acl && ei->i_default_acl != EXT2_ACL_NOT_CACHED) { - posix_acl_release(ei->i_default_acl); - ei->i_default_acl = EXT2_ACL_NOT_CACHED; - } -#endif ext2_discard_reservation(inode); EXT2_I(inode)->i_block_alloc_info = NULL; if (unlikely(rsv)) -- cgit v1.2.3 From 6582a0e6f6bc7bf64817b9e1a424782855292ab0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 19:53:58 -0400 Subject: switch ext3 to inode->i_acl Signed-off-by: Al Viro --- fs/ext3/acl.c | 22 ++++++++++------------ fs/ext3/acl.h | 4 ---- fs/ext3/inode.c | 4 ---- fs/ext3/super.c | 16 ---------------- include/linux/ext3_fs_i.h | 4 ---- 5 files changed, 10 insertions(+), 40 deletions(-) diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index e0c745451715..a9707689d9e1 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -134,7 +134,7 @@ ext3_iget_acl(struct inode *inode, struct posix_acl **i_acl) if (acl) { spin_lock(&inode->i_lock); acl = *i_acl; - if (acl != EXT3_ACL_NOT_CACHED) + if (acl != ACL_NOT_CACHED) acl = posix_acl_dup(acl); spin_unlock(&inode->i_lock); } @@ -147,7 +147,7 @@ ext3_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct posix_acl *acl) { spin_lock(&inode->i_lock); - if (*i_acl != EXT3_ACL_NOT_CACHED) + if (*i_acl != ACL_NOT_CACHED) posix_acl_release(*i_acl); *i_acl = posix_acl_dup(acl); spin_unlock(&inode->i_lock); @@ -161,7 +161,6 @@ ext3_iset_acl(struct inode *inode, struct posix_acl **i_acl, static struct posix_acl * ext3_get_acl(struct inode *inode, int type) { - struct ext3_inode_info *ei = EXT3_I(inode); int name_index; char *value = NULL; struct posix_acl *acl; @@ -172,15 +171,15 @@ ext3_get_acl(struct inode *inode, int type) switch(type) { case ACL_TYPE_ACCESS: - acl = ext3_iget_acl(inode, &ei->i_acl); - if (acl != EXT3_ACL_NOT_CACHED) + acl = ext3_iget_acl(inode, &inode->i_acl); + if (acl != ACL_NOT_CACHED) return acl; name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: - acl = ext3_iget_acl(inode, &ei->i_default_acl); - if (acl != EXT3_ACL_NOT_CACHED) + acl = ext3_iget_acl(inode, &inode->i_default_acl); + if (acl != ACL_NOT_CACHED) return acl; name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT; break; @@ -206,11 +205,11 @@ ext3_get_acl(struct inode *inode, int type) if (!IS_ERR(acl)) { switch(type) { case ACL_TYPE_ACCESS: - ext3_iset_acl(inode, &ei->i_acl, acl); + ext3_iset_acl(inode, &inode->i_acl, acl); break; case ACL_TYPE_DEFAULT: - ext3_iset_acl(inode, &ei->i_default_acl, acl); + ext3_iset_acl(inode, &inode->i_default_acl, acl); break; } } @@ -226,7 +225,6 @@ static int ext3_set_acl(handle_t *handle, struct inode *inode, int type, struct posix_acl *acl) { - struct ext3_inode_info *ei = EXT3_I(inode); int name_index; void *value = NULL; size_t size = 0; @@ -274,11 +272,11 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type, if (!error) { switch(type) { case ACL_TYPE_ACCESS: - ext3_iset_acl(inode, &ei->i_acl, acl); + ext3_iset_acl(inode, &inode->i_acl, acl); break; case ACL_TYPE_DEFAULT: - ext3_iset_acl(inode, &ei->i_default_acl, acl); + ext3_iset_acl(inode, &inode->i_default_acl, acl); break; } } diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h index 42da16b8cac0..07d15a3a5969 100644 --- a/fs/ext3/acl.h +++ b/fs/ext3/acl.h @@ -53,10 +53,6 @@ static inline int ext3_acl_count(size_t size) #ifdef CONFIG_EXT3_FS_POSIX_ACL -/* Value for inode->u.ext3_i.i_acl and inode->u.ext3_i.i_default_acl - if the ACL has not been cached */ -#define EXT3_ACL_NOT_CACHED ((void *)-1) - /* acl.c */ extern int ext3_permission (struct inode *, int); extern int ext3_acl_chmod (struct inode *); diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 05dea8132fc0..5f51fed5c750 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -2752,10 +2752,6 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino) return inode; ei = EXT3_I(inode); -#ifdef CONFIG_EXT3_FS_POSIX_ACL - ei->i_acl = EXT3_ACL_NOT_CACHED; - ei->i_default_acl = EXT3_ACL_NOT_CACHED; -#endif ei->i_block_alloc_info = NULL; ret = __ext3_get_inode_loc(inode, &iloc, 0); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 601e881e6105..524b349c6299 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -464,10 +464,6 @@ static struct inode *ext3_alloc_inode(struct super_block *sb) ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS); if (!ei) return NULL; -#ifdef CONFIG_EXT3_FS_POSIX_ACL - ei->i_acl = EXT3_ACL_NOT_CACHED; - ei->i_default_acl = EXT3_ACL_NOT_CACHED; -#endif ei->i_block_alloc_info = NULL; ei->vfs_inode.i_version = 1; return &ei->vfs_inode; @@ -518,18 +514,6 @@ static void destroy_inodecache(void) static void ext3_clear_inode(struct inode *inode) { struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info; -#ifdef CONFIG_EXT3_FS_POSIX_ACL - if (EXT3_I(inode)->i_acl && - EXT3_I(inode)->i_acl != EXT3_ACL_NOT_CACHED) { - posix_acl_release(EXT3_I(inode)->i_acl); - EXT3_I(inode)->i_acl = EXT3_ACL_NOT_CACHED; - } - if (EXT3_I(inode)->i_default_acl && - EXT3_I(inode)->i_default_acl != EXT3_ACL_NOT_CACHED) { - posix_acl_release(EXT3_I(inode)->i_default_acl); - EXT3_I(inode)->i_default_acl = EXT3_ACL_NOT_CACHED; - } -#endif ext3_discard_reservation(inode); EXT3_I(inode)->i_block_alloc_info = NULL; if (unlikely(rsv)) diff --git a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h index 7894dd0f3b77..ca1bfe90004f 100644 --- a/include/linux/ext3_fs_i.h +++ b/include/linux/ext3_fs_i.h @@ -103,10 +103,6 @@ struct ext3_inode_info { */ struct rw_semaphore xattr_sem; #endif -#ifdef CONFIG_EXT3_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; -#endif struct list_head i_orphan; /* unlinked but open inodes */ -- cgit v1.2.3 From d4bfe2f76d785cc77611a4bda8cedaff358d8c7d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 19:54:26 -0400 Subject: switch ext4 to inode->i_acl Signed-off-by: Al Viro --- fs/ext4/acl.c | 22 ++++++++++------------ fs/ext4/acl.h | 4 ---- fs/ext4/ext4.h | 4 ---- fs/ext4/inode.c | 4 ---- fs/ext4/super.c | 16 ---------------- 5 files changed, 10 insertions(+), 40 deletions(-) diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 605aeed96d68..0084e3a19d86 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -134,7 +134,7 @@ ext4_iget_acl(struct inode *inode, struct posix_acl **i_acl) if (acl) { spin_lock(&inode->i_lock); acl = *i_acl; - if (acl != EXT4_ACL_NOT_CACHED) + if (acl != ACL_NOT_CACHED) acl = posix_acl_dup(acl); spin_unlock(&inode->i_lock); } @@ -147,7 +147,7 @@ ext4_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct posix_acl *acl) { spin_lock(&inode->i_lock); - if (*i_acl != EXT4_ACL_NOT_CACHED) + if (*i_acl != ACL_NOT_CACHED) posix_acl_release(*i_acl); *i_acl = posix_acl_dup(acl); spin_unlock(&inode->i_lock); @@ -161,7 +161,6 @@ ext4_iset_acl(struct inode *inode, struct posix_acl **i_acl, static struct posix_acl * ext4_get_acl(struct inode *inode, int type) { - struct ext4_inode_info *ei = EXT4_I(inode); int name_index; char *value = NULL; struct posix_acl *acl; @@ -172,15 +171,15 @@ ext4_get_acl(struct inode *inode, int type) switch (type) { case ACL_TYPE_ACCESS: - acl = ext4_iget_acl(inode, &ei->i_acl); - if (acl != EXT4_ACL_NOT_CACHED) + acl = ext4_iget_acl(inode, &inode->i_acl); + if (acl != ACL_NOT_CACHED) return acl; name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: - acl = ext4_iget_acl(inode, &ei->i_default_acl); - if (acl != EXT4_ACL_NOT_CACHED) + acl = ext4_iget_acl(inode, &inode->i_default_acl); + if (acl != ACL_NOT_CACHED) return acl; name_index = EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT; break; @@ -206,11 +205,11 @@ ext4_get_acl(struct inode *inode, int type) if (!IS_ERR(acl)) { switch (type) { case ACL_TYPE_ACCESS: - ext4_iset_acl(inode, &ei->i_acl, acl); + ext4_iset_acl(inode, &inode->i_acl, acl); break; case ACL_TYPE_DEFAULT: - ext4_iset_acl(inode, &ei->i_default_acl, acl); + ext4_iset_acl(inode, &inode->i_default_acl, acl); break; } } @@ -226,7 +225,6 @@ static int ext4_set_acl(handle_t *handle, struct inode *inode, int type, struct posix_acl *acl) { - struct ext4_inode_info *ei = EXT4_I(inode); int name_index; void *value = NULL; size_t size = 0; @@ -274,11 +272,11 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type, if (!error) { switch (type) { case ACL_TYPE_ACCESS: - ext4_iset_acl(inode, &ei->i_acl, acl); + ext4_iset_acl(inode, &inode->i_acl, acl); break; case ACL_TYPE_DEFAULT: - ext4_iset_acl(inode, &ei->i_default_acl, acl); + ext4_iset_acl(inode, &inode->i_default_acl, acl); break; } } diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h index cb45257a246e..949789d2bba6 100644 --- a/fs/ext4/acl.h +++ b/fs/ext4/acl.h @@ -53,10 +53,6 @@ static inline int ext4_acl_count(size_t size) #ifdef CONFIG_EXT4_FS_POSIX_ACL -/* Value for inode->u.ext4_i.i_acl and inode->u.ext4_i.i_default_acl - if the ACL has not been cached */ -#define EXT4_ACL_NOT_CACHED ((void *)-1) - /* acl.c */ extern int ext4_permission(struct inode *, int); extern int ext4_acl_chmod(struct inode *); diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 17b9998680e3..0ddf7e55abe1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -595,10 +595,6 @@ struct ext4_inode_info { */ struct rw_semaphore xattr_sem; #endif -#ifdef CONFIG_EXT4_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; -#endif struct list_head i_orphan; /* unlinked but open inodes */ diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7c17ae275af4..60a26f3a6f8b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4453,10 +4453,6 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) return inode; ei = EXT4_I(inode); -#ifdef CONFIG_EXT4_FS_POSIX_ACL - ei->i_acl = EXT4_ACL_NOT_CACHED; - ei->i_default_acl = EXT4_ACL_NOT_CACHED; -#endif ret = __ext4_get_inode_loc(inode, &iloc, 0); if (ret < 0) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8bb9e2d3e4b8..8f4f079e6b9a 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -666,10 +666,6 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) if (!ei) return NULL; -#ifdef CONFIG_EXT4_FS_POSIX_ACL - ei->i_acl = EXT4_ACL_NOT_CACHED; - ei->i_default_acl = EXT4_ACL_NOT_CACHED; -#endif ei->vfs_inode.i_version = 1; ei->vfs_inode.i_data.writeback_index = 0; memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); @@ -735,18 +731,6 @@ static void destroy_inodecache(void) static void ext4_clear_inode(struct inode *inode) { -#ifdef CONFIG_EXT4_FS_POSIX_ACL - if (EXT4_I(inode)->i_acl && - EXT4_I(inode)->i_acl != EXT4_ACL_NOT_CACHED) { - posix_acl_release(EXT4_I(inode)->i_acl); - EXT4_I(inode)->i_acl = EXT4_ACL_NOT_CACHED; - } - if (EXT4_I(inode)->i_default_acl && - EXT4_I(inode)->i_default_acl != EXT4_ACL_NOT_CACHED) { - posix_acl_release(EXT4_I(inode)->i_default_acl); - EXT4_I(inode)->i_default_acl = EXT4_ACL_NOT_CACHED; - } -#endif ext4_discard_preallocations(inode); if (EXT4_JOURNAL(inode)) jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, -- cgit v1.2.3 From 05fc0790b6c9c611129f2f712d00b6a8a364e8d2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 19:54:52 -0400 Subject: switch jfs to inode->i_acl Signed-off-by: Al Viro --- fs/jfs/acl.c | 22 +++++++++------------- fs/jfs/jfs_incore.h | 6 ------ fs/jfs/super.c | 16 ---------------- fs/jfs/xattr.c | 12 ++++++------ 4 files changed, 15 insertions(+), 41 deletions(-) diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 06ca1b8d2054..5fcfc9857c11 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -31,7 +31,6 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type) { struct posix_acl *acl; char *ea_name; - struct jfs_inode_info *ji = JFS_IP(inode); struct posix_acl **p_acl; int size; char *value = NULL; @@ -39,17 +38,17 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type) switch(type) { case ACL_TYPE_ACCESS: ea_name = POSIX_ACL_XATTR_ACCESS; - p_acl = &ji->i_acl; + p_acl = &inode->i_acl; break; case ACL_TYPE_DEFAULT: ea_name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &ji->i_default_acl; + p_acl = &inode->i_default_acl; break; default: return ERR_PTR(-EINVAL); } - if (*p_acl != JFS_ACL_NOT_CACHED) + if (*p_acl != ACL_NOT_CACHED) return posix_acl_dup(*p_acl); size = __jfs_getxattr(inode, ea_name, NULL, 0); @@ -80,7 +79,6 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type, struct posix_acl *acl) { char *ea_name; - struct jfs_inode_info *ji = JFS_IP(inode); struct posix_acl **p_acl; int rc; int size = 0; @@ -92,11 +90,11 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type, switch(type) { case ACL_TYPE_ACCESS: ea_name = POSIX_ACL_XATTR_ACCESS; - p_acl = &ji->i_acl; + p_acl = &inode->i_acl; break; case ACL_TYPE_DEFAULT: ea_name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &ji->i_default_acl; + p_acl = &inode->i_default_acl; if (!S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; break; @@ -117,7 +115,7 @@ out: kfree(value); if (!rc) { - if (*p_acl && (*p_acl != JFS_ACL_NOT_CACHED)) + if (*p_acl && (*p_acl != ACL_NOT_CACHED)) posix_acl_release(*p_acl); *p_acl = posix_acl_dup(acl); } @@ -126,17 +124,15 @@ out: static int jfs_check_acl(struct inode *inode, int mask) { - struct jfs_inode_info *ji = JFS_IP(inode); - - if (ji->i_acl == JFS_ACL_NOT_CACHED) { + if (inode->i_acl == ACL_NOT_CACHED) { struct posix_acl *acl = jfs_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); posix_acl_release(acl); } - if (ji->i_acl) - return posix_acl_permission(inode, ji->i_acl, mask); + if (inode->i_acl) + return posix_acl_permission(inode, inode->i_acl, mask); return -EAGAIN; } diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h index 439901d205fe..1439f119ec83 100644 --- a/fs/jfs/jfs_incore.h +++ b/fs/jfs/jfs_incore.h @@ -74,10 +74,6 @@ struct jfs_inode_info { /* xattr_sem allows us to access the xattrs without taking i_mutex */ struct rw_semaphore xattr_sem; lid_t xtlid; /* lid of xtree lock on directory */ -#ifdef CONFIG_JFS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; -#endif union { struct { xtpage_t _xtroot; /* 288: xtree root */ @@ -107,8 +103,6 @@ struct jfs_inode_info { #define i_inline u.link._inline #define i_inline_ea u.link._inline_ea -#define JFS_ACL_NOT_CACHED ((void *)-1) - #define IREAD_LOCK(ip, subclass) \ down_read_nested(&JFS_IP(ip)->rdwrlock, subclass) #define IREAD_UNLOCK(ip) up_read(&JFS_IP(ip)->rdwrlock) diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 09b1b6ee2186..37e6dcda8fc8 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -128,18 +128,6 @@ static void jfs_destroy_inode(struct inode *inode) ji->active_ag = -1; } spin_unlock_irq(&ji->ag_lock); - -#ifdef CONFIG_JFS_POSIX_ACL - if (ji->i_acl != JFS_ACL_NOT_CACHED) { - posix_acl_release(ji->i_acl); - ji->i_acl = JFS_ACL_NOT_CACHED; - } - if (ji->i_default_acl != JFS_ACL_NOT_CACHED) { - posix_acl_release(ji->i_default_acl); - ji->i_default_acl = JFS_ACL_NOT_CACHED; - } -#endif - kmem_cache_free(jfs_inode_cachep, ji); } @@ -798,10 +786,6 @@ static void init_once(void *foo) init_rwsem(&jfs_ip->xattr_sem); spin_lock_init(&jfs_ip->ag_lock); jfs_ip->active_ag = -1; -#ifdef CONFIG_JFS_POSIX_ACL - jfs_ip->i_acl = JFS_ACL_NOT_CACHED; - jfs_ip->i_default_acl = JFS_ACL_NOT_CACHED; -#endif inode_init_once(&jfs_ip->vfs_inode); } diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 61dfa8173ebc..f6e90e343593 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -727,10 +727,10 @@ static int can_set_system_xattr(struct inode *inode, const char *name, /* * We're changing the ACL. Get rid of the cached one */ - acl =JFS_IP(inode)->i_acl; - if (acl != JFS_ACL_NOT_CACHED) + acl =inode->i_acl; + if (acl != ACL_NOT_CACHED) posix_acl_release(acl); - JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED; + inode->i_acl = ACL_NOT_CACHED; return 0; } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) { @@ -746,10 +746,10 @@ static int can_set_system_xattr(struct inode *inode, const char *name, /* * We're changing the default ACL. Get rid of the cached one */ - acl =JFS_IP(inode)->i_default_acl; - if (acl && (acl != JFS_ACL_NOT_CACHED)) + acl = inode->i_default_acl; + if (acl && (acl != ACL_NOT_CACHED)) posix_acl_release(acl); - JFS_IP(inode)->i_default_acl = JFS_ACL_NOT_CACHED; + inode->i_default_acl = ACL_NOT_CACHED; return 0; } -- cgit v1.2.3 From 290c263bf83cd78e53b1aa3b42165f588163f2be Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 19:55:12 -0400 Subject: switch jffs2 to inode->i_acl Signed-off-by: Al Viro --- fs/jffs2/acl.c | 54 ++++++++++++++++++--------------------------------- fs/jffs2/acl.h | 4 ---- fs/jffs2/jffs2_fs_i.h | 4 ---- fs/jffs2/os-linux.h | 4 ---- fs/jffs2/readinode.c | 1 - 5 files changed, 19 insertions(+), 48 deletions(-) diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 043740dde20c..ac16589ebbd1 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -158,10 +158,10 @@ static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size) static struct posix_acl *jffs2_iget_acl(struct inode *inode, struct posix_acl **i_acl) { - struct posix_acl *acl = JFFS2_ACL_NOT_CACHED; + struct posix_acl *acl = ACL_NOT_CACHED; spin_lock(&inode->i_lock); - if (*i_acl != JFFS2_ACL_NOT_CACHED) + if (*i_acl != ACL_NOT_CACHED) acl = posix_acl_dup(*i_acl); spin_unlock(&inode->i_lock); return acl; @@ -170,7 +170,7 @@ static struct posix_acl *jffs2_iget_acl(struct inode *inode, struct posix_acl ** static void jffs2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct posix_acl *acl) { spin_lock(&inode->i_lock); - if (*i_acl != JFFS2_ACL_NOT_CACHED) + if (*i_acl != ACL_NOT_CACHED) posix_acl_release(*i_acl); *i_acl = posix_acl_dup(acl); spin_unlock(&inode->i_lock); @@ -178,21 +178,20 @@ static void jffs2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct static struct posix_acl *jffs2_get_acl(struct inode *inode, int type) { - struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct posix_acl *acl; char *value = NULL; int rc, xprefix; switch (type) { case ACL_TYPE_ACCESS: - acl = jffs2_iget_acl(inode, &f->i_acl_access); - if (acl != JFFS2_ACL_NOT_CACHED) + acl = jffs2_iget_acl(inode, &inode->i_acl); + if (acl != ACL_NOT_CACHED) return acl; xprefix = JFFS2_XPREFIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: - acl = jffs2_iget_acl(inode, &f->i_acl_default); - if (acl != JFFS2_ACL_NOT_CACHED) + acl = jffs2_iget_acl(inode, &inode->i_default_acl); + if (acl != ACL_NOT_CACHED) return acl; xprefix = JFFS2_XPREFIX_ACL_DEFAULT; break; @@ -218,10 +217,10 @@ static struct posix_acl *jffs2_get_acl(struct inode *inode, int type) if (!IS_ERR(acl)) { switch (type) { case ACL_TYPE_ACCESS: - jffs2_iset_acl(inode, &f->i_acl_access, acl); + jffs2_iset_acl(inode, &inode->i_acl, acl); break; case ACL_TYPE_DEFAULT: - jffs2_iset_acl(inode, &f->i_acl_default, acl); + jffs2_iset_acl(inode, &inode->i_default_acl, acl); break; } } @@ -249,7 +248,6 @@ static int __jffs2_set_acl(struct inode *inode, int xprefix, struct posix_acl *a static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) { - struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); int rc, xprefix; if (S_ISLNK(inode->i_mode)) @@ -288,10 +286,10 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) if (!rc) { switch(type) { case ACL_TYPE_ACCESS: - jffs2_iset_acl(inode, &f->i_acl_access, acl); + jffs2_iset_acl(inode, &inode->i_acl, acl); break; case ACL_TYPE_DEFAULT: - jffs2_iset_acl(inode, &f->i_acl_default, acl); + jffs2_iset_acl(inode, &inode->i_default_acl, acl); break; } } @@ -321,12 +319,11 @@ int jffs2_permission(struct inode *inode, int mask) int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) { - struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct posix_acl *acl, *clone; int rc; - f->i_acl_default = NULL; - f->i_acl_access = NULL; + inode->i_default_acl = NULL; + inode->i_acl = NULL; if (S_ISLNK(*i_mode)) return 0; /* Symlink always has no-ACL */ @@ -339,7 +336,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) *i_mode &= ~current_umask(); } else { if (S_ISDIR(*i_mode)) - jffs2_iset_acl(inode, &f->i_acl_default, acl); + jffs2_iset_acl(inode, &inode->i_default_acl, acl); clone = posix_acl_clone(acl, GFP_KERNEL); if (!clone) @@ -350,7 +347,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) return rc; } if (rc > 0) - jffs2_iset_acl(inode, &f->i_acl_access, clone); + jffs2_iset_acl(inode, &inode->i_acl, clone); posix_acl_release(clone); } @@ -359,17 +356,16 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) int jffs2_init_acl_post(struct inode *inode) { - struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); int rc; - if (f->i_acl_default) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, f->i_acl_default); + if (inode->i_default_acl) { + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl); if (rc) return rc; } - if (f->i_acl_access) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, f->i_acl_access); + if (inode->i_acl) { + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl); if (rc) return rc; } @@ -377,18 +373,6 @@ int jffs2_init_acl_post(struct inode *inode) return 0; } -void jffs2_clear_acl(struct jffs2_inode_info *f) -{ - if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) { - posix_acl_release(f->i_acl_access); - f->i_acl_access = JFFS2_ACL_NOT_CACHED; - } - if (f->i_acl_default && f->i_acl_default != JFFS2_ACL_NOT_CACHED) { - posix_acl_release(f->i_acl_default); - f->i_acl_default = JFFS2_ACL_NOT_CACHED; - } -} - int jffs2_acl_chmod(struct inode *inode) { struct posix_acl *acl, *clone; diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h index 8ca058aed384..fc929f2a14f6 100644 --- a/fs/jffs2/acl.h +++ b/fs/jffs2/acl.h @@ -26,13 +26,10 @@ struct jffs2_acl_header { #ifdef CONFIG_JFFS2_FS_POSIX_ACL -#define JFFS2_ACL_NOT_CACHED ((void *)-1) - extern int jffs2_permission(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_post(struct inode *); -extern void jffs2_clear_acl(struct jffs2_inode_info *); extern struct xattr_handler jffs2_acl_access_xattr_handler; extern struct xattr_handler jffs2_acl_default_xattr_handler; @@ -43,6 +40,5 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler; #define jffs2_acl_chmod(inode) (0) #define jffs2_init_acl_pre(dir_i,inode,mode) (0) #define jffs2_init_acl_post(inode) (0) -#define jffs2_clear_acl(f) #endif /* CONFIG_JFFS2_FS_POSIX_ACL */ diff --git a/fs/jffs2/jffs2_fs_i.h b/fs/jffs2/jffs2_fs_i.h index 4c41db91eaa4..c6923da98263 100644 --- a/fs/jffs2/jffs2_fs_i.h +++ b/fs/jffs2/jffs2_fs_i.h @@ -50,10 +50,6 @@ struct jffs2_inode_info { uint16_t flags; uint8_t usercompr; struct inode vfs_inode; -#ifdef CONFIG_JFFS2_FS_POSIX_ACL - struct posix_acl *i_acl_access; - struct posix_acl *i_acl_default; -#endif }; #endif /* _JFFS2_FS_I */ diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 2228380c47b9..a7f03b7ebcb3 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h @@ -56,10 +56,6 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) f->target = NULL; f->flags = 0; f->usercompr = 0; -#ifdef CONFIG_JFFS2_FS_POSIX_ACL - f->i_acl_access = JFFS2_ACL_NOT_CACHED; - f->i_acl_default = JFFS2_ACL_NOT_CACHED; -#endif } diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 1fc1e92356ee..1a80301004b8 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -1424,7 +1424,6 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) struct jffs2_full_dirent *fd, *fds; int deleted; - jffs2_clear_acl(f); jffs2_xattr_delete_inode(c, f->inocache); mutex_lock(&f->sem); deleted = f->inocache && !f->inocache->pino_nlink; -- cgit v1.2.3 From 5affd88a104af43f0063a12ad1ee4c7a587945dc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 19:55:32 -0400 Subject: switch btrfs to inode->i_acl Signed-off-by: Al Viro --- fs/btrfs/acl.c | 14 +++++++------- fs/btrfs/btrfs_inode.h | 4 ---- fs/btrfs/ctree.h | 2 -- fs/btrfs/inode.c | 16 ++-------------- 4 files changed, 9 insertions(+), 27 deletions(-) diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 603972576f0f..6db8a42a3e5e 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -34,7 +34,7 @@ static void btrfs_update_cached_acl(struct inode *inode, struct posix_acl *acl) { spin_lock(&inode->i_lock); - if (*p_acl && *p_acl != BTRFS_ACL_NOT_CACHED) + if (*p_acl && *p_acl != ACL_NOT_CACHED) posix_acl_release(*p_acl); *p_acl = posix_acl_dup(acl); spin_unlock(&inode->i_lock); @@ -50,11 +50,11 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) switch (type) { case ACL_TYPE_ACCESS: name = POSIX_ACL_XATTR_ACCESS; - p_acl = &BTRFS_I(inode)->i_acl; + p_acl = &inode->i_acl; break; case ACL_TYPE_DEFAULT: name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &BTRFS_I(inode)->i_default_acl; + p_acl = &inode->i_default_acl; break; default: return ERR_PTR(-EINVAL); @@ -67,11 +67,11 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) spin_lock(&inode->i_lock); acl = *p_acl; - if (acl != BTRFS_ACL_NOT_CACHED) + if (acl != ACL_NOT_CACHED) acl = posix_acl_dup(acl); spin_unlock(&inode->i_lock); - if (acl != BTRFS_ACL_NOT_CACHED) + if (acl != ACL_NOT_CACHED) return acl; size = __btrfs_getxattr(inode, name, "", 0); @@ -141,13 +141,13 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) ret = 0; inode->i_mode = mode; name = POSIX_ACL_XATTR_ACCESS; - p_acl = &BTRFS_I(inode)->i_acl; + p_acl = &inode->i_acl; break; case ACL_TYPE_DEFAULT: if (!S_ISDIR(inode->i_mode)) return acl ? -EINVAL : 0; name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &BTRFS_I(inode)->i_default_acl; + p_acl = &inode->i_default_acl; break; default: return -EINVAL; diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index acb4f3517582..ea1ea0af8c0e 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -53,10 +53,6 @@ struct btrfs_inode { /* used to order data wrt metadata */ struct btrfs_ordered_inode_tree ordered_tree; - /* standard acl pointers */ - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; - /* for keeping track of orphaned inodes */ struct list_head i_orphan; diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 03441a99ea38..2779c2f5360a 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -41,8 +41,6 @@ struct btrfs_ordered_sum; #define BTRFS_MAGIC "_BHRfS_M" -#define BTRFS_ACL_NOT_CACHED ((void *)-1) - #define BTRFS_MAX_LEVEL 8 #define BTRFS_COMPAT_EXTENT_TREE_V0 diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8612b3a09811..78ad38ddd01f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2123,8 +2123,8 @@ static void btrfs_read_locked_inode(struct inode *inode) */ maybe_acls = acls_after_inode_item(leaf, path->slots[0], inode->i_ino); if (!maybe_acls) { - BTRFS_I(inode)->i_acl = NULL; - BTRFS_I(inode)->i_default_acl = NULL; + inode->i_acl = NULL; + inode->i_default_acl = NULL; } BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0, @@ -3141,9 +3141,6 @@ static noinline void init_btrfs_i(struct inode *inode) { struct btrfs_inode *bi = BTRFS_I(inode); - bi->i_acl = BTRFS_ACL_NOT_CACHED; - bi->i_default_acl = BTRFS_ACL_NOT_CACHED; - bi->generation = 0; bi->sequence = 0; bi->last_trans = 0; @@ -4640,8 +4637,6 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) ei->last_trans = 0; ei->logged_trans = 0; btrfs_ordered_inode_tree_init(&ei->ordered_tree); - ei->i_acl = BTRFS_ACL_NOT_CACHED; - ei->i_default_acl = BTRFS_ACL_NOT_CACHED; INIT_LIST_HEAD(&ei->i_orphan); INIT_LIST_HEAD(&ei->ordered_operations); return &ei->vfs_inode; @@ -4655,13 +4650,6 @@ void btrfs_destroy_inode(struct inode *inode) WARN_ON(!list_empty(&inode->i_dentry)); WARN_ON(inode->i_data.nrpages); - if (BTRFS_I(inode)->i_acl && - BTRFS_I(inode)->i_acl != BTRFS_ACL_NOT_CACHED) - posix_acl_release(BTRFS_I(inode)->i_acl); - if (BTRFS_I(inode)->i_default_acl && - BTRFS_I(inode)->i_default_acl != BTRFS_ACL_NOT_CACHED) - posix_acl_release(BTRFS_I(inode)->i_default_acl); - /* * Make sure we're properly removed from the ordered operation * lists. -- cgit v1.2.3 From d441b1c293149212045de00f346c8ea6cd41cce4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 19:56:34 -0400 Subject: switch nilfs2 to inode->i_acl Actually, get rid of private analog, since nothing in there is using ACLs at all so far. Signed-off-by: Al Viro --- fs/nilfs2/inode.c | 8 -------- fs/nilfs2/nilfs.h | 4 ---- fs/nilfs2/super.c | 10 ---------- 3 files changed, 22 deletions(-) diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 2696d6b513b7..fe9d8f2a13f8 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -309,10 +309,6 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) /* ii->i_file_acl = 0; */ /* ii->i_dir_acl = 0; */ ii->i_dir_start_lookup = 0; -#ifdef CONFIG_NILFS_FS_POSIX_ACL - ii->i_acl = NULL; - ii->i_default_acl = NULL; -#endif ii->i_cno = 0; nilfs_set_inode_flags(inode); spin_lock(&sbi->s_next_gen_lock); @@ -434,10 +430,6 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh); -#ifdef CONFIG_NILFS_FS_POSIX_ACL - ii->i_acl = NILFS_ACL_NOT_CACHED; - ii->i_default_acl = NILFS_ACL_NOT_CACHED; -#endif if (nilfs_read_inode_common(inode, raw_inode)) goto failed_unmap; diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index edf6a59d9f2a..724c63766e82 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h @@ -57,10 +57,6 @@ struct nilfs_inode_info { * EAs. */ struct rw_semaphore xattr_sem; -#endif -#ifdef CONFIG_NILFS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; #endif struct buffer_head *i_bh; /* i_bh contains a new or dirty disk inode */ diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index ab785f85aa50..8e2ec43b18f4 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -189,16 +189,6 @@ static void nilfs_clear_inode(struct inode *inode) { struct nilfs_inode_info *ii = NILFS_I(inode); -#ifdef CONFIG_NILFS_POSIX_ACL - if (ii->i_acl && ii->i_acl != NILFS_ACL_NOT_CACHED) { - posix_acl_release(ii->i_acl); - ii->i_acl = NILFS_ACL_NOT_CACHED; - } - if (ii->i_default_acl && ii->i_default_acl != NILFS_ACL_NOT_CACHED) { - posix_acl_release(ii->i_default_acl); - ii->i_default_acl = NILFS_ACL_NOT_CACHED; - } -#endif /* * Free resources allocated in nilfs_read_inode(), here. */ -- cgit v1.2.3 From e68888bcb60ccba4dc21df9f2d8cd7325b64dce7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 20:46:54 -0400 Subject: reiserfs: minimal fix for ACL caching reiserfs uses NULL as "unknown" and ERR_PTR(-ENODATA) as "no ACL"; several codepaths store the former instead of the latter. All those codepaths go through iset_acl() and all cases when it's called with NULL acl are for the second variety, so the minimal fix is to teach iset_acl() to deal with that. Proper fix is to switch to more usual conventions and avoid back and forth between internally used ERR_PTR(-ENODATA) and NULL expected by the rest of the kernel. Signed-off-by: Al Viro --- fs/reiserfs/xattr_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index c303c426fe2b..a1a7e3530e17 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -194,7 +194,7 @@ static inline void iset_acl(struct inode *inode, struct posix_acl **i_acl, spin_lock(&inode->i_lock); if (*i_acl != ERR_PTR(-ENODATA)) posix_acl_release(*i_acl); - *i_acl = posix_acl_dup(acl); + *i_acl = acl ? posix_acl_dup(acl) : ERR_PTR(-ENODATA); spin_unlock(&inode->i_lock); } -- cgit v1.2.3 From 7a77b15d9294749809de918e24bebc39e0fbc9ab Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 21:01:13 -0400 Subject: switch reiserfs to usual conventions for caching ACLs Signed-off-by: Al Viro --- fs/reiserfs/super.c | 12 ++++++------ fs/reiserfs/xattr_acl.c | 21 ++++++++------------- include/linux/reiserfs_acl.h | 4 ++-- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 2969773cfc22..b194451fc04b 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -530,8 +530,8 @@ static void init_once(void *foo) INIT_LIST_HEAD(&ei->i_prealloc_list); inode_init_once(&ei->vfs_inode); #ifdef CONFIG_REISERFS_FS_POSIX_ACL - ei->i_acl_access = NULL; - ei->i_acl_default = NULL; + ei->i_acl_access = ACL_NOT_CACHED; + ei->i_acl_default = ACL_NOT_CACHED; #endif } @@ -586,14 +586,14 @@ static void reiserfs_clear_inode(struct inode *inode) struct posix_acl *acl; acl = REISERFS_I(inode)->i_acl_access; - if (acl && !IS_ERR(acl)) + if (acl && acl != ACL_NOT_CACHED) posix_acl_release(acl); - REISERFS_I(inode)->i_acl_access = NULL; + REISERFS_I(inode)->i_acl_access = ACL_NOT_CACHED; acl = REISERFS_I(inode)->i_acl_default; - if (acl && !IS_ERR(acl)) + if (acl && acl != ACL_NOT_CACHED) posix_acl_release(acl); - REISERFS_I(inode)->i_acl_default = NULL; + REISERFS_I(inode)->i_acl_default = ACL_NOT_CACHED; } #else #define reiserfs_clear_inode NULL diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index a1a7e3530e17..7b3aeb9327d3 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -192,19 +192,19 @@ static inline void iset_acl(struct inode *inode, struct posix_acl **i_acl, struct posix_acl *acl) { spin_lock(&inode->i_lock); - if (*i_acl != ERR_PTR(-ENODATA)) + if (*i_acl != ACL_NOT_CACHED) posix_acl_release(*i_acl); - *i_acl = acl ? posix_acl_dup(acl) : ERR_PTR(-ENODATA); + *i_acl = posix_acl_dup(acl); spin_unlock(&inode->i_lock); } static inline struct posix_acl *iget_acl(struct inode *inode, struct posix_acl **i_acl) { - struct posix_acl *acl = ERR_PTR(-ENODATA); + struct posix_acl *acl = ACL_NOT_CACHED; spin_lock(&inode->i_lock); - if (*i_acl != ERR_PTR(-ENODATA)) + if (*i_acl != ACL_NOT_CACHED) acl = posix_acl_dup(*i_acl); spin_unlock(&inode->i_lock); @@ -239,15 +239,13 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) } acl = iget_acl(inode, p_acl); - if (acl && !IS_ERR(acl)) + if (acl != ACL_NOT_CACHED) return acl; - else if (PTR_ERR(acl) == -ENODATA) - return NULL; size = reiserfs_xattr_get(inode, name, NULL, 0); if (size < 0) { if (size == -ENODATA || size == -ENOSYS) { - *p_acl = ERR_PTR(-ENODATA); + *p_acl = NULL; return NULL; } return ERR_PTR(size); @@ -262,7 +260,7 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) /* This shouldn't actually happen as it should have been caught above.. but just in case */ acl = NULL; - *p_acl = ERR_PTR(-ENODATA); + *p_acl = acl; } else if (retval < 0) { acl = ERR_PTR(retval); } else { @@ -379,11 +377,8 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, } acl = reiserfs_get_acl(dir, ACL_TYPE_DEFAULT); - if (IS_ERR(acl)) { - if (PTR_ERR(acl) == -ENODATA) - goto apply_umask; + if (IS_ERR(acl)) return PTR_ERR(acl); - } if (acl) { struct posix_acl *acl_copy; diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h index 8cc65757e47a..8f4d8d718b10 100644 --- a/include/linux/reiserfs_acl.h +++ b/include/linux/reiserfs_acl.h @@ -58,12 +58,12 @@ extern struct xattr_handler reiserfs_posix_acl_access_handler; static inline void reiserfs_init_acl_access(struct inode *inode) { - REISERFS_I(inode)->i_acl_access = NULL; + REISERFS_I(inode)->i_acl_access = ACL_NOT_CACHED; } static inline void reiserfs_init_acl_default(struct inode *inode) { - REISERFS_I(inode)->i_acl_default = NULL; + REISERFS_I(inode)->i_acl_default = ACL_NOT_CACHED; } #else -- cgit v1.2.3 From 281eede0328c84a8f20e0e85b807d5b51c3de4f2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 21:07:04 -0400 Subject: switch reiserfs to inode->i_acl Signed-off-by: Al Viro --- fs/reiserfs/inode.c | 4 ---- fs/reiserfs/super.c | 24 ------------------------ fs/reiserfs/xattr_acl.c | 10 ++++------ include/linux/reiserfs_acl.h | 17 ----------------- include/linux/reiserfs_fs_i.h | 4 ---- 5 files changed, 4 insertions(+), 55 deletions(-) diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 6fd0f47e45db..a14d6cd9eeda 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1131,8 +1131,6 @@ static void init_inode(struct inode *inode, struct treepath *path) REISERFS_I(inode)->i_trans_id = 0; REISERFS_I(inode)->i_jl = NULL; mutex_init(&(REISERFS_I(inode)->i_mmap)); - reiserfs_init_acl_access(inode); - reiserfs_init_acl_default(inode); reiserfs_init_xattr_rwsem(inode); if (stat_data_v1(ih)) { @@ -1834,8 +1832,6 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); mutex_init(&(REISERFS_I(inode)->i_mmap)); - reiserfs_init_acl_access(inode); - reiserfs_init_acl_default(inode); reiserfs_init_xattr_rwsem(inode); /* key to search for correct place for new stat data */ diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b194451fc04b..d3aeb061612b 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -529,10 +529,6 @@ static void init_once(void *foo) INIT_LIST_HEAD(&ei->i_prealloc_list); inode_init_once(&ei->vfs_inode); -#ifdef CONFIG_REISERFS_FS_POSIX_ACL - ei->i_acl_access = ACL_NOT_CACHED; - ei->i_acl_default = ACL_NOT_CACHED; -#endif } static int init_inodecache(void) @@ -580,25 +576,6 @@ static void reiserfs_dirty_inode(struct inode *inode) reiserfs_write_unlock(inode->i_sb); } -#ifdef CONFIG_REISERFS_FS_POSIX_ACL -static void reiserfs_clear_inode(struct inode *inode) -{ - struct posix_acl *acl; - - acl = REISERFS_I(inode)->i_acl_access; - if (acl && acl != ACL_NOT_CACHED) - posix_acl_release(acl); - REISERFS_I(inode)->i_acl_access = ACL_NOT_CACHED; - - acl = REISERFS_I(inode)->i_acl_default; - if (acl && acl != ACL_NOT_CACHED) - posix_acl_release(acl); - REISERFS_I(inode)->i_acl_default = ACL_NOT_CACHED; -} -#else -#define reiserfs_clear_inode NULL -#endif - #ifdef CONFIG_QUOTA static ssize_t reiserfs_quota_write(struct super_block *, int, const char *, size_t, loff_t); @@ -612,7 +589,6 @@ static const struct super_operations reiserfs_sops = { .write_inode = reiserfs_write_inode, .dirty_inode = reiserfs_dirty_inode, .delete_inode = reiserfs_delete_inode, - .clear_inode = reiserfs_clear_inode, .put_super = reiserfs_put_super, .write_super = reiserfs_write_super, .sync_fs = reiserfs_sync_fs, diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 7b3aeb9327d3..b6e473faa8b8 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -223,16 +223,15 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) struct posix_acl *acl, **p_acl; int size; int retval; - struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); switch (type) { case ACL_TYPE_ACCESS: name = POSIX_ACL_XATTR_ACCESS; - p_acl = &reiserfs_i->i_acl_access; + p_acl = &inode->i_acl; break; case ACL_TYPE_DEFAULT: name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &reiserfs_i->i_acl_default; + p_acl = &inode->i_default_acl; break; default: return ERR_PTR(-EINVAL); @@ -288,7 +287,6 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, struct posix_acl **p_acl; size_t size = 0; int error; - struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; @@ -296,7 +294,7 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, switch (type) { case ACL_TYPE_ACCESS: name = POSIX_ACL_XATTR_ACCESS; - p_acl = &reiserfs_i->i_acl_access; + p_acl = &inode->i_acl; if (acl) { mode_t mode = inode->i_mode; error = posix_acl_equiv_mode(acl, &mode); @@ -311,7 +309,7 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, break; case ACL_TYPE_DEFAULT: name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &reiserfs_i->i_acl_default; + p_acl = &inode->i_default_acl; if (!S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; break; diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h index 8f4d8d718b10..b4448853900e 100644 --- a/include/linux/reiserfs_acl.h +++ b/include/linux/reiserfs_acl.h @@ -56,15 +56,6 @@ int reiserfs_cache_default_acl(struct inode *dir); extern struct xattr_handler reiserfs_posix_acl_default_handler; extern struct xattr_handler reiserfs_posix_acl_access_handler; -static inline void reiserfs_init_acl_access(struct inode *inode) -{ - REISERFS_I(inode)->i_acl_access = ACL_NOT_CACHED; -} - -static inline void reiserfs_init_acl_default(struct inode *inode) -{ - REISERFS_I(inode)->i_acl_default = ACL_NOT_CACHED; -} #else #define reiserfs_cache_default_acl(inode) 0 @@ -86,12 +77,4 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, { return 0; } - -static inline void reiserfs_init_acl_access(struct inode *inode) -{ -} - -static inline void reiserfs_init_acl_default(struct inode *inode) -{ -} #endif diff --git a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h index 76360b36ac33..89f4d3abbf5a 100644 --- a/include/linux/reiserfs_fs_i.h +++ b/include/linux/reiserfs_fs_i.h @@ -54,10 +54,6 @@ struct reiserfs_inode_info { unsigned int i_trans_id; struct reiserfs_journal_list *i_jl; struct mutex i_mmap; -#ifdef CONFIG_REISERFS_FS_POSIX_ACL - struct posix_acl *i_acl_access; - struct posix_acl *i_acl_default; -#endif #ifdef CONFIG_REISERFS_FS_XATTR struct rw_semaphore i_xattr_sem; #endif -- cgit v1.2.3 From 06b16e9f68edaa1e71aee943d3c030bcf7380af1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Jun 2009 19:56:00 -0400 Subject: switch shmem to inode->i_acl Signed-off-by: Al Viro --- include/linux/shmem_fs.h | 8 -------- mm/shmem.c | 9 ++++----- mm/shmem_acl.c | 29 ++++++----------------------- 3 files changed, 10 insertions(+), 36 deletions(-) diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index fd83f2584b15..abff6c9b413c 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -19,10 +19,6 @@ struct shmem_inode_info { swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* first blocks */ struct list_head swaplist; /* chain of maybes on swap */ struct inode vfs_inode; -#ifdef CONFIG_TMPFS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; -#endif }; struct shmem_sb_info { @@ -45,7 +41,6 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) #ifdef CONFIG_TMPFS_POSIX_ACL int shmem_permission(struct inode *, int); int shmem_acl_init(struct inode *, struct inode *); -void shmem_acl_destroy_inode(struct inode *); extern struct xattr_handler shmem_xattr_acl_access_handler; extern struct xattr_handler shmem_xattr_acl_default_handler; @@ -57,9 +52,6 @@ static inline int shmem_acl_init(struct inode *inode, struct inode *dir) { return 0; } -static inline void shmem_acl_destroy_inode(struct inode *inode) -{ -} #endif /* CONFIG_TMPFS_POSIX_ACL */ #endif diff --git a/mm/shmem.c b/mm/shmem.c index e89d7ec18eda..5f2019fc7895 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2379,6 +2379,10 @@ static struct inode *shmem_alloc_inode(struct super_block *sb) p = (struct shmem_inode_info *)kmem_cache_alloc(shmem_inode_cachep, GFP_KERNEL); if (!p) return NULL; +#ifdef CONFIG_TMPFS_POSIX_ACL + p->vfs_inode.i_acl = NULL; + p->vfs_inode.i_default_acl = NULL; +#endif return &p->vfs_inode; } @@ -2388,7 +2392,6 @@ static void shmem_destroy_inode(struct inode *inode) /* only struct inode is valid if it's an inline symlink */ mpol_free_shared_policy(&SHMEM_I(inode)->policy); } - shmem_acl_destroy_inode(inode); kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode)); } @@ -2397,10 +2400,6 @@ static void init_once(void *foo) struct shmem_inode_info *p = (struct shmem_inode_info *) foo; inode_init_once(&p->vfs_inode); -#ifdef CONFIG_TMPFS_POSIX_ACL - p->i_acl = NULL; - p->i_default_acl = NULL; -#endif } static int init_inodecache(void) diff --git a/mm/shmem_acl.c b/mm/shmem_acl.c index 8e5aadd7dcd6..606a8e757a42 100644 --- a/mm/shmem_acl.c +++ b/mm/shmem_acl.c @@ -22,11 +22,11 @@ shmem_get_acl(struct inode *inode, int type) spin_lock(&inode->i_lock); switch(type) { case ACL_TYPE_ACCESS: - acl = posix_acl_dup(SHMEM_I(inode)->i_acl); + acl = posix_acl_dup(inode->i_acl); break; case ACL_TYPE_DEFAULT: - acl = posix_acl_dup(SHMEM_I(inode)->i_default_acl); + acl = posix_acl_dup(inode->i_default_acl); break; } spin_unlock(&inode->i_lock); @@ -45,13 +45,13 @@ shmem_set_acl(struct inode *inode, int type, struct posix_acl *acl) spin_lock(&inode->i_lock); switch(type) { case ACL_TYPE_ACCESS: - free = SHMEM_I(inode)->i_acl; - SHMEM_I(inode)->i_acl = posix_acl_dup(acl); + free = inode->i_acl; + inode->i_acl = posix_acl_dup(acl); break; case ACL_TYPE_DEFAULT: - free = SHMEM_I(inode)->i_default_acl; - SHMEM_I(inode)->i_default_acl = posix_acl_dup(acl); + free = inode->i_default_acl; + inode->i_default_acl = posix_acl_dup(acl); break; } spin_unlock(&inode->i_lock); @@ -154,23 +154,6 @@ shmem_acl_init(struct inode *inode, struct inode *dir) return generic_acl_init(inode, dir, &shmem_acl_ops); } -/** - * shmem_acl_destroy_inode - destroy acls hanging off the in-memory inode - * - * This is done before destroying the actual inode. - */ - -void -shmem_acl_destroy_inode(struct inode *inode) -{ - if (SHMEM_I(inode)->i_acl) - posix_acl_release(SHMEM_I(inode)->i_acl); - SHMEM_I(inode)->i_acl = NULL; - if (SHMEM_I(inode)->i_default_acl) - posix_acl_release(SHMEM_I(inode)->i_default_acl); - SHMEM_I(inode)->i_default_acl = NULL; -} - /** * shmem_check_acl - check_acl() callback for generic_permission() */ -- cgit v1.2.3 From 073aaa1b142461d91f83da66db1184d7c1b1edea Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 9 Jun 2009 12:11:54 -0400 Subject: helpers for acl caching + switch to those helpers: get_cached_acl(inode, type), set_cached_acl(inode, type, acl), forget_cached_acl(inode, type). ubifs/xattr.c needed includes reordered, the rest is a plain switchover. Signed-off-by: Al Viro --- fs/btrfs/acl.c | 44 +++++-------------------- fs/ext2/acl.c | 79 ++++++++++---------------------------------- fs/ext3/acl.c | 83 +++++++++++------------------------------------ fs/ext4/acl.c | 65 +++++-------------------------------- fs/jffs2/acl.c | 60 +++++++--------------------------- fs/jfs/acl.c | 32 ++++++++---------- fs/jfs/xattr.c | 10 ++---- fs/reiserfs/xattr_acl.c | 49 ++++++---------------------- fs/ubifs/xattr.c | 2 +- include/linux/posix_acl.h | 64 ++++++++++++++++++++++++++++++++++++ 10 files changed, 155 insertions(+), 333 deletions(-) diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 6db8a42a3e5e..f128427b995b 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -29,51 +29,28 @@ #ifdef CONFIG_FS_POSIX_ACL -static void btrfs_update_cached_acl(struct inode *inode, - struct posix_acl **p_acl, - struct posix_acl *acl) -{ - spin_lock(&inode->i_lock); - if (*p_acl && *p_acl != ACL_NOT_CACHED) - posix_acl_release(*p_acl); - *p_acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); -} - static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) { int size; const char *name; char *value = NULL; - struct posix_acl *acl = NULL, **p_acl; + struct posix_acl *acl; + + acl = get_cached_acl(inode, type); + if (acl != ACL_NOT_CACHED) + return acl; switch (type) { case ACL_TYPE_ACCESS: name = POSIX_ACL_XATTR_ACCESS; - p_acl = &inode->i_acl; break; case ACL_TYPE_DEFAULT: name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &inode->i_default_acl; break; default: - return ERR_PTR(-EINVAL); + BUG(); } - /* Handle the cached NULL acl case without locking */ - acl = ACCESS_ONCE(*p_acl); - if (!acl) - return acl; - - spin_lock(&inode->i_lock); - acl = *p_acl; - if (acl != ACL_NOT_CACHED) - acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); - - if (acl != ACL_NOT_CACHED) - return acl; - size = __btrfs_getxattr(inode, name, "", 0); if (size > 0) { value = kzalloc(size, GFP_NOFS); @@ -82,13 +59,13 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) size = __btrfs_getxattr(inode, name, value, size); if (size > 0) { acl = posix_acl_from_xattr(value, size); - btrfs_update_cached_acl(inode, p_acl, acl); + set_cached_acl(inode, type, acl); } kfree(value); } else if (size == -ENOENT || size == -ENODATA || size == 0) { /* FIXME, who returns -ENOENT? I think nobody */ acl = NULL; - btrfs_update_cached_acl(inode, p_acl, acl); + set_cached_acl(inode, type, acl); } else { acl = ERR_PTR(-EIO); } @@ -121,7 +98,6 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) { int ret, size = 0; const char *name; - struct posix_acl **p_acl; char *value = NULL; mode_t mode; @@ -141,13 +117,11 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) ret = 0; inode->i_mode = mode; name = POSIX_ACL_XATTR_ACCESS; - p_acl = &inode->i_acl; break; case ACL_TYPE_DEFAULT: if (!S_ISDIR(inode->i_mode)) return acl ? -EINVAL : 0; name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &inode->i_default_acl; break; default: return -EINVAL; @@ -172,7 +146,7 @@ out: kfree(value); if (!ret) - btrfs_update_cached_acl(inode, p_acl, acl); + set_cached_acl(inode, type, acl); return ret; } diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index d2ffddc12117..d636e1297cad 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -125,30 +125,6 @@ fail: return ERR_PTR(-EINVAL); } -static inline struct posix_acl * -ext2_iget_acl(struct inode *inode, struct posix_acl **i_acl) -{ - struct posix_acl *acl = ACL_NOT_CACHED; - - spin_lock(&inode->i_lock); - if (*i_acl != ACL_NOT_CACHED) - acl = posix_acl_dup(*i_acl); - spin_unlock(&inode->i_lock); - - return acl; -} - -static inline void -ext2_iset_acl(struct inode *inode, struct posix_acl **i_acl, - struct posix_acl *acl) -{ - spin_lock(&inode->i_lock); - if (*i_acl != ACL_NOT_CACHED) - posix_acl_release(*i_acl); - *i_acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); -} - /* * inode->i_mutex: don't care */ @@ -163,23 +139,19 @@ ext2_get_acl(struct inode *inode, int type) if (!test_opt(inode->i_sb, POSIX_ACL)) return NULL; - switch(type) { - case ACL_TYPE_ACCESS: - acl = ext2_iget_acl(inode, &inode->i_acl); - if (acl != ACL_NOT_CACHED) - return acl; - name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; - break; - - case ACL_TYPE_DEFAULT: - acl = ext2_iget_acl(inode, &inode->i_default_acl); - if (acl != ACL_NOT_CACHED) - return acl; - name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT; - break; - - default: - return ERR_PTR(-EINVAL); + acl = get_cached_acl(inode, type); + if (acl != ACL_NOT_CACHED) + return acl; + + switch (type) { + case ACL_TYPE_ACCESS: + name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; + break; + case ACL_TYPE_DEFAULT: + name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT; + break; + default: + BUG(); } retval = ext2_xattr_get(inode, name_index, "", NULL, 0); if (retval > 0) { @@ -196,17 +168,9 @@ ext2_get_acl(struct inode *inode, int type) acl = ERR_PTR(retval); kfree(value); - if (!IS_ERR(acl)) { - switch(type) { - case ACL_TYPE_ACCESS: - ext2_iset_acl(inode, &inode->i_acl, acl); - break; + if (!IS_ERR(acl)) + set_cached_acl(inode, type, acl); - case ACL_TYPE_DEFAULT: - ext2_iset_acl(inode, &inode->i_default_acl, acl); - break; - } - } return acl; } @@ -261,17 +225,8 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) error = ext2_xattr_set(inode, name_index, "", value, size, 0); kfree(value); - if (!error) { - switch(type) { - case ACL_TYPE_ACCESS: - ext2_iset_acl(inode, &inode->i_acl, acl); - break; - - case ACL_TYPE_DEFAULT: - ext2_iset_acl(inode, &inode->i_default_acl, acl); - break; - } - } + if (!error) + set_cached_acl(inode, type, acl); return error; } diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index a9707689d9e1..e167bae37ef0 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -126,33 +126,6 @@ fail: return ERR_PTR(-EINVAL); } -static inline struct posix_acl * -ext3_iget_acl(struct inode *inode, struct posix_acl **i_acl) -{ - struct posix_acl *acl = ACCESS_ONCE(*i_acl); - - if (acl) { - spin_lock(&inode->i_lock); - acl = *i_acl; - if (acl != ACL_NOT_CACHED) - acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); - } - - return acl; -} - -static inline void -ext3_iset_acl(struct inode *inode, struct posix_acl **i_acl, - struct posix_acl *acl) -{ - spin_lock(&inode->i_lock); - if (*i_acl != ACL_NOT_CACHED) - posix_acl_release(*i_acl); - *i_acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); -} - /* * Inode operation get_posix_acl(). * @@ -169,24 +142,21 @@ ext3_get_acl(struct inode *inode, int type) if (!test_opt(inode->i_sb, POSIX_ACL)) return NULL; - switch(type) { - case ACL_TYPE_ACCESS: - acl = ext3_iget_acl(inode, &inode->i_acl); - if (acl != ACL_NOT_CACHED) - return acl; - name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; - break; - - case ACL_TYPE_DEFAULT: - acl = ext3_iget_acl(inode, &inode->i_default_acl); - if (acl != ACL_NOT_CACHED) - return acl; - name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT; - break; - - default: - return ERR_PTR(-EINVAL); + acl = get_cached_acl(inode, type); + if (acl != ACL_NOT_CACHED) + return acl; + + switch (type) { + case ACL_TYPE_ACCESS: + name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; + break; + case ACL_TYPE_DEFAULT: + name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT; + break; + default: + BUG(); } + retval = ext3_xattr_get(inode, name_index, "", NULL, 0); if (retval > 0) { value = kmalloc(retval, GFP_NOFS); @@ -202,17 +172,9 @@ ext3_get_acl(struct inode *inode, int type) acl = ERR_PTR(retval); kfree(value); - if (!IS_ERR(acl)) { - switch(type) { - case ACL_TYPE_ACCESS: - ext3_iset_acl(inode, &inode->i_acl, acl); - break; + if (!IS_ERR(acl)) + set_cached_acl(inode, type, acl); - case ACL_TYPE_DEFAULT: - ext3_iset_acl(inode, &inode->i_default_acl, acl); - break; - } - } return acl; } @@ -269,17 +231,10 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type, value, size, 0); kfree(value); - if (!error) { - switch(type) { - case ACL_TYPE_ACCESS: - ext3_iset_acl(inode, &inode->i_acl, acl); - break; - case ACL_TYPE_DEFAULT: - ext3_iset_acl(inode, &inode->i_default_acl, acl); - break; - } - } + if (!error) + set_cached_acl(inode, type, acl); + return error; } diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 0084e3a19d86..f6d8967149ca 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -126,33 +126,6 @@ fail: return ERR_PTR(-EINVAL); } -static inline struct posix_acl * -ext4_iget_acl(struct inode *inode, struct posix_acl **i_acl) -{ - struct posix_acl *acl = ACCESS_ONCE(*i_acl); - - if (acl) { - spin_lock(&inode->i_lock); - acl = *i_acl; - if (acl != ACL_NOT_CACHED) - acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); - } - - return acl; -} - -static inline void -ext4_iset_acl(struct inode *inode, struct posix_acl **i_acl, - struct posix_acl *acl) -{ - spin_lock(&inode->i_lock); - if (*i_acl != ACL_NOT_CACHED) - posix_acl_release(*i_acl); - *i_acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); -} - /* * Inode operation get_posix_acl(). * @@ -169,23 +142,19 @@ ext4_get_acl(struct inode *inode, int type) if (!test_opt(inode->i_sb, POSIX_ACL)) return NULL; + acl = get_cached_acl(inode, type); + if (acl != ACL_NOT_CACHED) + return acl; + switch (type) { case ACL_TYPE_ACCESS: - acl = ext4_iget_acl(inode, &inode->i_acl); - if (acl != ACL_NOT_CACHED) - return acl; name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; break; - case ACL_TYPE_DEFAULT: - acl = ext4_iget_acl(inode, &inode->i_default_acl); - if (acl != ACL_NOT_CACHED) - return acl; name_index = EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT; break; - default: - return ERR_PTR(-EINVAL); + BUG(); } retval = ext4_xattr_get(inode, name_index, "", NULL, 0); if (retval > 0) { @@ -202,17 +171,9 @@ ext4_get_acl(struct inode *inode, int type) acl = ERR_PTR(retval); kfree(value); - if (!IS_ERR(acl)) { - switch (type) { - case ACL_TYPE_ACCESS: - ext4_iset_acl(inode, &inode->i_acl, acl); - break; + if (!IS_ERR(acl)) + set_cached_acl(inode, type, acl); - case ACL_TYPE_DEFAULT: - ext4_iset_acl(inode, &inode->i_default_acl, acl); - break; - } - } return acl; } @@ -269,17 +230,9 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type, value, size, 0); kfree(value); - if (!error) { - switch (type) { - case ACL_TYPE_ACCESS: - ext4_iset_acl(inode, &inode->i_acl, acl); - break; + if (!error) + set_cached_acl(inode, type, acl); - case ACL_TYPE_DEFAULT: - ext4_iset_acl(inode, &inode->i_default_acl, acl); - break; - } - } return error; } diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index ac16589ebbd1..edd2ad6416d8 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -156,47 +156,25 @@ static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size) return ERR_PTR(-EINVAL); } -static struct posix_acl *jffs2_iget_acl(struct inode *inode, struct posix_acl **i_acl) -{ - struct posix_acl *acl = ACL_NOT_CACHED; - - spin_lock(&inode->i_lock); - if (*i_acl != ACL_NOT_CACHED) - acl = posix_acl_dup(*i_acl); - spin_unlock(&inode->i_lock); - return acl; -} - -static void jffs2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct posix_acl *acl) -{ - spin_lock(&inode->i_lock); - if (*i_acl != ACL_NOT_CACHED) - posix_acl_release(*i_acl); - *i_acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); -} - static struct posix_acl *jffs2_get_acl(struct inode *inode, int type) { struct posix_acl *acl; char *value = NULL; int rc, xprefix; + acl = get_cached_acl(inode, type); + if (acl != ACL_NOT_CACHED) + return acl; + switch (type) { case ACL_TYPE_ACCESS: - acl = jffs2_iget_acl(inode, &inode->i_acl); - if (acl != ACL_NOT_CACHED) - return acl; xprefix = JFFS2_XPREFIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: - acl = jffs2_iget_acl(inode, &inode->i_default_acl); - if (acl != ACL_NOT_CACHED) - return acl; xprefix = JFFS2_XPREFIX_ACL_DEFAULT; break; default: - return ERR_PTR(-EINVAL); + BUG(); } rc = do_jffs2_getxattr(inode, xprefix, "", NULL, 0); if (rc > 0) { @@ -214,16 +192,8 @@ static struct posix_acl *jffs2_get_acl(struct inode *inode, int type) } if (value) kfree(value); - if (!IS_ERR(acl)) { - switch (type) { - case ACL_TYPE_ACCESS: - jffs2_iset_acl(inode, &inode->i_acl, acl); - break; - case ACL_TYPE_DEFAULT: - jffs2_iset_acl(inode, &inode->i_default_acl, acl); - break; - } - } + if (!IS_ERR(acl)) + set_cached_acl(inode, type, acl); return acl; } @@ -283,16 +253,8 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) return -EINVAL; } rc = __jffs2_set_acl(inode, xprefix, acl); - if (!rc) { - switch(type) { - case ACL_TYPE_ACCESS: - jffs2_iset_acl(inode, &inode->i_acl, acl); - break; - case ACL_TYPE_DEFAULT: - jffs2_iset_acl(inode, &inode->i_default_acl, acl); - break; - } - } + if (!rc) + set_cached_acl(inode, type, acl); return rc; } @@ -336,7 +298,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) *i_mode &= ~current_umask(); } else { if (S_ISDIR(*i_mode)) - jffs2_iset_acl(inode, &inode->i_default_acl, acl); + set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); clone = posix_acl_clone(acl, GFP_KERNEL); if (!clone) @@ -347,7 +309,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) return rc; } if (rc > 0) - jffs2_iset_acl(inode, &inode->i_acl, clone); + set_cached_acl(inode, ACL_TYPE_ACCESS, clone); posix_acl_release(clone); } diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 5fcfc9857c11..f272bf032e1e 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -31,26 +31,24 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type) { struct posix_acl *acl; char *ea_name; - struct posix_acl **p_acl; int size; char *value = NULL; + acl = get_cached_acl(inode, type); + if (acl != ACL_NOT_CACHED) + return acl; + switch(type) { case ACL_TYPE_ACCESS: ea_name = POSIX_ACL_XATTR_ACCESS; - p_acl = &inode->i_acl; break; case ACL_TYPE_DEFAULT: ea_name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &inode->i_default_acl; break; default: return ERR_PTR(-EINVAL); } - if (*p_acl != ACL_NOT_CACHED) - return posix_acl_dup(*p_acl); - size = __jfs_getxattr(inode, ea_name, NULL, 0); if (size > 0) { @@ -61,17 +59,18 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type) } if (size < 0) { - if (size == -ENODATA) { - *p_acl = NULL; + if (size == -ENODATA) acl = NULL; - } else + else acl = ERR_PTR(size); } else { acl = posix_acl_from_xattr(value, size); - if (!IS_ERR(acl)) - *p_acl = posix_acl_dup(acl); } kfree(value); + if (!IS_ERR(acl)) { + set_cached_acl(inode, type, acl); + posix_acl_release(acl); + } return acl; } @@ -79,7 +78,6 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type, struct posix_acl *acl) { char *ea_name; - struct posix_acl **p_acl; int rc; int size = 0; char *value = NULL; @@ -90,11 +88,9 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type, switch(type) { case ACL_TYPE_ACCESS: ea_name = POSIX_ACL_XATTR_ACCESS; - p_acl = &inode->i_acl; break; case ACL_TYPE_DEFAULT: ea_name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &inode->i_default_acl; if (!S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; break; @@ -114,11 +110,9 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type, out: kfree(value); - if (!rc) { - if (*p_acl && (*p_acl != ACL_NOT_CACHED)) - posix_acl_release(*p_acl); - *p_acl = posix_acl_dup(acl); - } + if (!rc) + set_cached_acl(inode, type, acl); + return rc; } diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index f6e90e343593..fad364548bc9 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -727,10 +727,7 @@ static int can_set_system_xattr(struct inode *inode, const char *name, /* * We're changing the ACL. Get rid of the cached one */ - acl =inode->i_acl; - if (acl != ACL_NOT_CACHED) - posix_acl_release(acl); - inode->i_acl = ACL_NOT_CACHED; + forget_cached_acl(inode, ACL_TYPE_ACCESS); return 0; } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) { @@ -746,10 +743,7 @@ static int can_set_system_xattr(struct inode *inode, const char *name, /* * We're changing the default ACL. Get rid of the cached one */ - acl = inode->i_default_acl; - if (acl && (acl != ACL_NOT_CACHED)) - posix_acl_release(acl); - inode->i_default_acl = ACL_NOT_CACHED; + forget_cached_acl(inode, ACL_TYPE_DEFAULT); return 0; } diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index b6e473faa8b8..35d6e672a279 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -188,29 +188,6 @@ static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size) return ERR_PTR(-EINVAL); } -static inline void iset_acl(struct inode *inode, struct posix_acl **i_acl, - struct posix_acl *acl) -{ - spin_lock(&inode->i_lock); - if (*i_acl != ACL_NOT_CACHED) - posix_acl_release(*i_acl); - *i_acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); -} - -static inline struct posix_acl *iget_acl(struct inode *inode, - struct posix_acl **i_acl) -{ - struct posix_acl *acl = ACL_NOT_CACHED; - - spin_lock(&inode->i_lock); - if (*i_acl != ACL_NOT_CACHED) - acl = posix_acl_dup(*i_acl); - spin_unlock(&inode->i_lock); - - return acl; -} - /* * Inode operation get_posix_acl(). * @@ -220,31 +197,29 @@ static inline struct posix_acl *iget_acl(struct inode *inode, struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) { char *name, *value; - struct posix_acl *acl, **p_acl; + struct posix_acl *acl; int size; int retval; + acl = get_cached_acl(inode, type); + if (acl != ACL_NOT_CACHED) + return acl; + switch (type) { case ACL_TYPE_ACCESS: name = POSIX_ACL_XATTR_ACCESS; - p_acl = &inode->i_acl; break; case ACL_TYPE_DEFAULT: name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &inode->i_default_acl; break; default: - return ERR_PTR(-EINVAL); + BUG(); } - acl = iget_acl(inode, p_acl); - if (acl != ACL_NOT_CACHED) - return acl; - size = reiserfs_xattr_get(inode, name, NULL, 0); if (size < 0) { if (size == -ENODATA || size == -ENOSYS) { - *p_acl = NULL; + set_cached_acl(inode, type, NULL); return NULL; } return ERR_PTR(size); @@ -259,14 +234,13 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) /* This shouldn't actually happen as it should have been caught above.. but just in case */ acl = NULL; - *p_acl = acl; } else if (retval < 0) { acl = ERR_PTR(retval); } else { acl = posix_acl_from_disk(value, retval); - if (!IS_ERR(acl)) - iset_acl(inode, p_acl, acl); } + if (!IS_ERR(acl)) + set_cached_acl(inode, type, acl); kfree(value); return acl; @@ -284,7 +258,6 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, { char *name; void *value = NULL; - struct posix_acl **p_acl; size_t size = 0; int error; @@ -294,7 +267,6 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, switch (type) { case ACL_TYPE_ACCESS: name = POSIX_ACL_XATTR_ACCESS; - p_acl = &inode->i_acl; if (acl) { mode_t mode = inode->i_mode; error = posix_acl_equiv_mode(acl, &mode); @@ -309,7 +281,6 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, break; case ACL_TYPE_DEFAULT: name = POSIX_ACL_XATTR_DEFAULT; - p_acl = &inode->i_default_acl; if (!S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; break; @@ -342,7 +313,7 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, kfree(value); if (!error) - iset_acl(inode, p_acl, acl); + set_cached_acl(inode, type, acl); return error; } diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index cfd31e229c89..adafcf556531 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c @@ -55,9 +55,9 @@ * ACL support is not implemented. */ +#include "ubifs.h" #include #include -#include "ubifs.h" /* * Limit the number of extended attributes per inode so that the total size diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 4bc241290c24..0cdba01b7756 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -83,4 +83,68 @@ extern int posix_acl_chmod_masq(struct posix_acl *, mode_t); extern struct posix_acl *get_posix_acl(struct inode *, int); extern int set_posix_acl(struct inode *, int, struct posix_acl *); +static inline struct posix_acl *get_cached_acl(struct inode *inode, int type) +{ + struct posix_acl **p, *acl; + switch (type) { + case ACL_TYPE_ACCESS: + p = &inode->i_acl; + break; + case ACL_TYPE_DEFAULT: + p = &inode->i_default_acl; + break; + default: + return ERR_PTR(-EINVAL); + } + acl = ACCESS_ONCE(*p); + if (acl) { + spin_lock(&inode->i_lock); + acl = *p; + if (acl != ACL_NOT_CACHED) + acl = posix_acl_dup(acl); + spin_unlock(&inode->i_lock); + } + return acl; +} + +static inline void set_cached_acl(struct inode *inode, + int type, + struct posix_acl *acl) +{ + struct posix_acl *old = NULL; + spin_lock(&inode->i_lock); + switch (type) { + case ACL_TYPE_ACCESS: + old = inode->i_acl; + inode->i_acl = posix_acl_dup(acl); + break; + case ACL_TYPE_DEFAULT: + old = inode->i_default_acl; + inode->i_default_acl = posix_acl_dup(acl); + break; + } + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + posix_acl_release(old); +} + +static inline void forget_cached_acl(struct inode *inode, int type) +{ + struct posix_acl *old = NULL; + spin_lock(&inode->i_lock); + switch (type) { + case ACL_TYPE_ACCESS: + old = inode->i_acl; + inode->i_acl = ACL_NOT_CACHED; + break; + case ACL_TYPE_DEFAULT: + old = inode->i_default_acl; + inode->i_default_acl = ACL_NOT_CACHED; + break; + } + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + posix_acl_release(old); +} + #endif /* __LINUX_POSIX_ACL_H */ -- cgit v1.2.3 From 1cbd20d820c36f52543e3e4cd0067ebf52aa388f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 9 Jun 2009 13:29:39 -0400 Subject: switch xfs to generic acl caching helpers Signed-off-by: Al Viro --- fs/xfs/linux-2.6/xfs_acl.c | 73 ++++++---------------------------------------- fs/xfs/xfs_acl.h | 4 --- fs/xfs/xfs_iget.c | 2 -- fs/xfs/xfs_inode.h | 5 ---- 4 files changed, 9 insertions(+), 75 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index 1e9d1246eebc..b23a54506446 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c @@ -25,14 +25,10 @@ #include -#define XFS_ACL_NOT_CACHED ((void *)-1) - /* * Locking scheme: * - all ACL updates are protected by inode->i_mutex, which is taken before * calling into this file. - * - access and updates to the ip->i_acl and ip->i_default_acl pointers are - * protected by inode->i_lock. */ STATIC struct posix_acl * @@ -102,59 +98,35 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl) } } -/* - * Update the cached ACL pointer in the inode. - * - * Because we don't hold any locks while reading/writing the attribute - * from/to disk another thread could have raced and updated the cached - * ACL value before us. In that case we release the previous cached value - * and update it with our new value. - */ -STATIC void -xfs_update_cached_acl(struct inode *inode, struct posix_acl **p_acl, - struct posix_acl *acl) -{ - spin_lock(&inode->i_lock); - if (*p_acl && *p_acl != XFS_ACL_NOT_CACHED) - posix_acl_release(*p_acl); - *p_acl = posix_acl_dup(acl); - spin_unlock(&inode->i_lock); -} - struct posix_acl * xfs_get_acl(struct inode *inode, int type) { struct xfs_inode *ip = XFS_I(inode); - struct posix_acl *acl = NULL, **p_acl; + struct posix_acl *acl; struct xfs_acl *xfs_acl; int len = sizeof(struct xfs_acl); char *ea_name; int error; + acl = get_cached_acl(inode, type); + if (acl != ACL_NOT_CACHED) + return acl; + switch (type) { case ACL_TYPE_ACCESS: ea_name = SGI_ACL_FILE; - p_acl = &ip->i_acl; break; case ACL_TYPE_DEFAULT: ea_name = SGI_ACL_DEFAULT; - p_acl = &ip->i_default_acl; break; default: - return ERR_PTR(-EINVAL); + BUG(); } - spin_lock(&inode->i_lock); - if (*p_acl != XFS_ACL_NOT_CACHED) - acl = posix_acl_dup(*p_acl); - spin_unlock(&inode->i_lock); - /* * If we have a cached ACLs value just return it, not need to * go out to the disk. */ - if (acl) - return acl; xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL); if (!xfs_acl) @@ -165,7 +137,7 @@ xfs_get_acl(struct inode *inode, int type) /* * If the attribute doesn't exist make sure we have a negative * cache entry, for any other error assume it is transient and - * leave the cache entry as XFS_ACL_NOT_CACHED. + * leave the cache entry as ACL_NOT_CACHED. */ if (error == -ENOATTR) { acl = NULL; @@ -179,7 +151,7 @@ xfs_get_acl(struct inode *inode, int type) goto out; out_update_cache: - xfs_update_cached_acl(inode, p_acl, acl); + set_cached_acl(inode, type, acl); out: kfree(xfs_acl); return acl; @@ -189,7 +161,6 @@ STATIC int xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) { struct xfs_inode *ip = XFS_I(inode); - struct posix_acl **p_acl; char *ea_name; int error; @@ -199,13 +170,11 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) switch (type) { case ACL_TYPE_ACCESS: ea_name = SGI_ACL_FILE; - p_acl = &ip->i_acl; break; case ACL_TYPE_DEFAULT: if (!S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; ea_name = SGI_ACL_DEFAULT; - p_acl = &ip->i_default_acl; break; default: return -EINVAL; @@ -242,7 +211,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) } if (!error) - xfs_update_cached_acl(inode, p_acl, acl); + set_cached_acl(inode, type, acl); return error; } @@ -384,30 +353,6 @@ xfs_acl_chmod(struct inode *inode) return error; } -void -xfs_inode_init_acls(struct xfs_inode *ip) -{ - /* - * No need for locking, inode is not live yet. - */ - ip->i_acl = XFS_ACL_NOT_CACHED; - ip->i_default_acl = XFS_ACL_NOT_CACHED; -} - -void -xfs_inode_clear_acls(struct xfs_inode *ip) -{ - /* - * No need for locking here, the inode is not live anymore - * and just about to be freed. - */ - if (ip->i_acl != XFS_ACL_NOT_CACHED) - posix_acl_release(ip->i_acl); - if (ip->i_default_acl != XFS_ACL_NOT_CACHED) - posix_acl_release(ip->i_default_acl); -} - - /* * System xattr handlers. * diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 63dc1f2efad5..947b150df8ed 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -46,8 +46,6 @@ 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); -extern void xfs_inode_init_acls(struct xfs_inode *ip); -extern void xfs_inode_clear_acls(struct xfs_inode *ip); extern int posix_acl_access_exists(struct inode *inode); extern int posix_acl_default_exists(struct inode *inode); @@ -57,8 +55,6 @@ extern struct xattr_handler xfs_xattr_system_handler; # define xfs_get_acl(inode, type) NULL # define xfs_inherit_acl(inode, default_acl) 0 # define xfs_acl_chmod(inode) 0 -# define xfs_inode_init_acls(ip) -# define xfs_inode_clear_acls(ip) # define posix_acl_access_exists(inode) 0 # define posix_acl_default_exists(inode) 0 #endif /* CONFIG_XFS_POSIX_ACL */ diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 76c540f719e4..5fcec6f020a7 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -83,7 +83,6 @@ xfs_inode_alloc( memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); ip->i_size = 0; ip->i_new_size = 0; - xfs_inode_init_acls(ip); /* * Initialize inode's trace buffers. @@ -560,7 +559,6 @@ xfs_ireclaim( ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(!spin_is_locked(&ip->i_flags_lock)); ASSERT(completion_done(&ip->i_flush)); - xfs_inode_clear_acls(ip); kmem_zone_free(xfs_inode_zone, ip); } diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 77016702938b..1804f866a71d 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -273,11 +273,6 @@ typedef struct xfs_inode { /* VFS inode */ struct inode i_vnode; /* embedded VFS inode */ -#ifdef CONFIG_XFS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; -#endif - /* Trace buffers per inode. */ #ifdef XFS_INODE_TRACE struct ktrace *i_trace; /* general inode trace */ -- cgit v1.2.3