Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (23 commits)
  switch xfs to generic acl caching helpers
  helpers for acl caching + switch to those
  switch shmem to inode->i_acl
  switch reiserfs to inode->i_acl
  switch reiserfs to usual conventions for caching ACLs
  reiserfs: minimal fix for ACL caching
  switch nilfs2 to inode->i_acl
  switch btrfs to inode->i_acl
  switch jffs2 to inode->i_acl
  switch jfs to inode->i_acl
  switch ext4 to inode->i_acl
  switch ext3 to inode->i_acl
  switch ext2 to inode->i_acl
  add caching of ACLs in struct inode
  fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls
  cleanup __writeback_single_inode
  ... and the same for vfsmount id/mount group id
  Make allocation of anon devices cheaper
  update Documentation/filesystems/Locking
  devpts: remove module-related code
  ...
This commit is contained in:
Linus Torvalds 2009-06-24 10:03:12 -07:00
commit 936940a9c7
58 changed files with 453 additions and 820 deletions

View file

@ -109,27 +109,28 @@ prototypes:
locking rules: locking rules:
All may block. All may block.
BKL s_lock s_umount None have BKL
alloc_inode: no no no s_umount
destroy_inode: no alloc_inode:
dirty_inode: no (must not sleep) destroy_inode:
write_inode: no dirty_inode: (must not sleep)
drop_inode: no !!!inode_lock!!! write_inode:
delete_inode: no drop_inode: !!!inode_lock!!!
put_super: yes yes no delete_inode:
write_super: no yes read put_super: write
sync_fs: no no read write_super: read
freeze_fs: ? sync_fs: read
unfreeze_fs: ? freeze_fs: read
statfs: no no no unfreeze_fs: read
remount_fs: yes yes maybe (see below) statfs: no
clear_inode: no remount_fs: maybe (see below)
umount_begin: yes no no clear_inode:
show_options: no (vfsmount->sem) umount_begin: no
quota_read: no no no (see below) show_options: no (namespace_sem)
quota_write: no no no (see below) quota_read: no (see below)
quota_write: no (see below)
->remount_fs() will have the s_umount lock if it's already mounted. ->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. When called from get_sb_single, it does NOT have the s_umount lock.
->quota_read() and ->quota_write() functions are both guaranteed to ->quota_read() and ->quota_write() functions are both guaranteed to
be the only ones operating on the quota file by the quota code (via be the only ones operating on the quota file by the quota code (via

View file

@ -29,51 +29,28 @@
#ifdef CONFIG_FS_POSIX_ACL #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 != BTRFS_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) static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
{ {
int size; int size;
const char *name; const char *name;
char *value = NULL; 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) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = POSIX_ACL_XATTR_ACCESS;
p_acl = &BTRFS_I(inode)->i_acl;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT; name = POSIX_ACL_XATTR_DEFAULT;
p_acl = &BTRFS_I(inode)->i_default_acl;
break; break;
default: 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 != BTRFS_ACL_NOT_CACHED)
acl = posix_acl_dup(acl);
spin_unlock(&inode->i_lock);
if (acl != BTRFS_ACL_NOT_CACHED)
return acl;
size = __btrfs_getxattr(inode, name, "", 0); size = __btrfs_getxattr(inode, name, "", 0);
if (size > 0) { if (size > 0) {
value = kzalloc(size, GFP_NOFS); 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); size = __btrfs_getxattr(inode, name, value, size);
if (size > 0) { if (size > 0) {
acl = posix_acl_from_xattr(value, size); acl = posix_acl_from_xattr(value, size);
btrfs_update_cached_acl(inode, p_acl, acl); set_cached_acl(inode, type, acl);
} }
kfree(value); kfree(value);
} else if (size == -ENOENT || size == -ENODATA || size == 0) { } else if (size == -ENOENT || size == -ENODATA || size == 0) {
/* FIXME, who returns -ENOENT? I think nobody */ /* FIXME, who returns -ENOENT? I think nobody */
acl = NULL; acl = NULL;
btrfs_update_cached_acl(inode, p_acl, acl); set_cached_acl(inode, type, acl);
} else { } else {
acl = ERR_PTR(-EIO); 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; int ret, size = 0;
const char *name; const char *name;
struct posix_acl **p_acl;
char *value = NULL; char *value = NULL;
mode_t mode; mode_t mode;
@ -141,13 +117,11 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
ret = 0; ret = 0;
inode->i_mode = mode; inode->i_mode = mode;
name = POSIX_ACL_XATTR_ACCESS; name = POSIX_ACL_XATTR_ACCESS;
p_acl = &BTRFS_I(inode)->i_acl;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
return acl ? -EINVAL : 0; return acl ? -EINVAL : 0;
name = POSIX_ACL_XATTR_DEFAULT; name = POSIX_ACL_XATTR_DEFAULT;
p_acl = &BTRFS_I(inode)->i_default_acl;
break; break;
default: default:
return -EINVAL; return -EINVAL;
@ -172,7 +146,7 @@ out:
kfree(value); kfree(value);
if (!ret) if (!ret)
btrfs_update_cached_acl(inode, p_acl, acl); set_cached_acl(inode, type, acl);
return ret; return ret;
} }

View file

@ -53,10 +53,6 @@ struct btrfs_inode {
/* used to order data wrt metadata */ /* used to order data wrt metadata */
struct btrfs_ordered_inode_tree ordered_tree; 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 */ /* for keeping track of orphaned inodes */
struct list_head i_orphan; struct list_head i_orphan;

View file

@ -41,8 +41,6 @@ struct btrfs_ordered_sum;
#define BTRFS_MAGIC "_BHRfS_M" #define BTRFS_MAGIC "_BHRfS_M"
#define BTRFS_ACL_NOT_CACHED ((void *)-1)
#define BTRFS_MAX_LEVEL 8 #define BTRFS_MAX_LEVEL 8
#define BTRFS_COMPAT_EXTENT_TREE_V0 #define BTRFS_COMPAT_EXTENT_TREE_V0

View file

@ -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); maybe_acls = acls_after_inode_item(leaf, path->slots[0], inode->i_ino);
if (!maybe_acls) { if (!maybe_acls) {
BTRFS_I(inode)->i_acl = NULL; inode->i_acl = NULL;
BTRFS_I(inode)->i_default_acl = NULL; inode->i_default_acl = NULL;
} }
BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0, 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); 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->generation = 0;
bi->sequence = 0; bi->sequence = 0;
bi->last_trans = 0; bi->last_trans = 0;
@ -4640,8 +4637,6 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
ei->last_trans = 0; ei->last_trans = 0;
ei->logged_trans = 0; ei->logged_trans = 0;
btrfs_ordered_inode_tree_init(&ei->ordered_tree); 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->i_orphan);
INIT_LIST_HEAD(&ei->ordered_operations); INIT_LIST_HEAD(&ei->ordered_operations);
return &ei->vfs_inode; return &ei->vfs_inode;
@ -4655,13 +4650,6 @@ void btrfs_destroy_inode(struct inode *inode)
WARN_ON(!list_empty(&inode->i_dentry)); WARN_ON(!list_empty(&inode->i_dentry));
WARN_ON(inode->i_data.nrpages); 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 * Make sure we're properly removed from the ordered operation
* lists. * lists.

View file

@ -31,6 +31,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/vt.h> #include <linux/vt.h>
#include <linux/falloc.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/ppp_defs.h> #include <linux/ppp_defs.h>
@ -1779,6 +1780,41 @@ lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
return sys_ioctl(fd, cmd, (unsigned long)tn); 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, typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int,
unsigned long, struct file *); unsigned long, struct file *);
@ -2756,6 +2792,18 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
case FIOQSIZE: case FIOQSIZE:
break; 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 FIBMAP:
case FIGETBSZ: case FIGETBSZ:
case FIONREAD: case FIONREAD:

View file

@ -423,7 +423,6 @@ static void devpts_kill_sb(struct super_block *sb)
} }
static struct file_system_type devpts_fs_type = { static struct file_system_type devpts_fs_type = {
.owner = THIS_MODULE,
.name = "devpts", .name = "devpts",
.get_sb = devpts_get_sb, .get_sb = devpts_get_sb,
.kill_sb = devpts_kill_sb, .kill_sb = devpts_kill_sb,
@ -564,13 +563,4 @@ static int __init init_devpts_fs(void)
} }
return err; return err;
} }
static void __exit exit_devpts_fs(void)
{
unregister_filesystem(&devpts_fs_type);
mntput(devpts_mnt);
}
module_init(init_devpts_fs) module_init(init_devpts_fs)
module_exit(exit_devpts_fs)
MODULE_LICENSE("GPL");

View file

@ -125,37 +125,12 @@ fail:
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
static inline struct posix_acl *
ext2_iget_acl(struct inode *inode, struct posix_acl **i_acl)
{
struct posix_acl *acl = EXT2_ACL_NOT_CACHED;
spin_lock(&inode->i_lock);
if (*i_acl != EXT2_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 != EXT2_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 * inode->i_mutex: don't care
*/ */
static struct posix_acl * static struct posix_acl *
ext2_get_acl(struct inode *inode, int type) ext2_get_acl(struct inode *inode, int type)
{ {
struct ext2_inode_info *ei = EXT2_I(inode);
int name_index; int name_index;
char *value = NULL; char *value = NULL;
struct posix_acl *acl; struct posix_acl *acl;
@ -164,23 +139,19 @@ ext2_get_acl(struct inode *inode, int type)
if (!test_opt(inode->i_sb, POSIX_ACL)) if (!test_opt(inode->i_sb, POSIX_ACL))
return NULL; return NULL;
switch(type) { acl = get_cached_acl(inode, type);
case ACL_TYPE_ACCESS: if (acl != ACL_NOT_CACHED)
acl = ext2_iget_acl(inode, &ei->i_acl); return acl;
if (acl != EXT2_ACL_NOT_CACHED)
return acl;
name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
break;
case ACL_TYPE_DEFAULT: switch (type) {
acl = ext2_iget_acl(inode, &ei->i_default_acl); case ACL_TYPE_ACCESS:
if (acl != EXT2_ACL_NOT_CACHED) name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
return acl; break;
name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT; case ACL_TYPE_DEFAULT:
break; name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT;
break;
default: default:
return ERR_PTR(-EINVAL); BUG();
} }
retval = ext2_xattr_get(inode, name_index, "", NULL, 0); retval = ext2_xattr_get(inode, name_index, "", NULL, 0);
if (retval > 0) { if (retval > 0) {
@ -197,17 +168,9 @@ ext2_get_acl(struct inode *inode, int type)
acl = ERR_PTR(retval); acl = ERR_PTR(retval);
kfree(value); kfree(value);
if (!IS_ERR(acl)) { if (!IS_ERR(acl))
switch(type) { set_cached_acl(inode, type, acl);
case ACL_TYPE_ACCESS:
ext2_iset_acl(inode, &ei->i_acl, acl);
break;
case ACL_TYPE_DEFAULT:
ext2_iset_acl(inode, &ei->i_default_acl, acl);
break;
}
}
return acl; return acl;
} }
@ -217,7 +180,6 @@ ext2_get_acl(struct inode *inode, int type)
static int static int
ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
{ {
struct ext2_inode_info *ei = EXT2_I(inode);
int name_index; int name_index;
void *value = NULL; void *value = NULL;
size_t size = 0; size_t size = 0;
@ -263,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); error = ext2_xattr_set(inode, name_index, "", value, size, 0);
kfree(value); kfree(value);
if (!error) { if (!error)
switch(type) { set_cached_acl(inode, type, acl);
case ACL_TYPE_ACCESS:
ext2_iset_acl(inode, &ei->i_acl, acl);
break;
case ACL_TYPE_DEFAULT:
ext2_iset_acl(inode, &ei->i_default_acl, acl);
break;
}
}
return error; return error;
} }

View file

@ -53,10 +53,6 @@ static inline int ext2_acl_count(size_t size)
#ifdef CONFIG_EXT2_FS_POSIX_ACL #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 */ /* acl.c */
extern int ext2_permission (struct inode *, int); extern int ext2_permission (struct inode *, int);
extern int ext2_acl_chmod (struct inode *); extern int ext2_acl_chmod (struct inode *);

View file

@ -46,10 +46,6 @@ struct ext2_inode_info {
* EAs. * EAs.
*/ */
struct rw_semaphore xattr_sem; struct rw_semaphore xattr_sem;
#endif
#ifdef CONFIG_EXT2_FS_POSIX_ACL
struct posix_acl *i_acl;
struct posix_acl *i_default_acl;
#endif #endif
rwlock_t i_meta_lock; rwlock_t i_meta_lock;

View file

@ -1224,10 +1224,6 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
return inode; return inode;
ei = EXT2_I(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; ei->i_block_alloc_info = NULL;
raw_inode = ext2_get_inode(inode->i_sb, ino, &bh); raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);

View file

@ -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); ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, GFP_KERNEL);
if (!ei) if (!ei)
return NULL; 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->i_block_alloc_info = NULL;
ei->vfs_inode.i_version = 1; ei->vfs_inode.i_version = 1;
return &ei->vfs_inode; return &ei->vfs_inode;
@ -198,18 +194,6 @@ static void destroy_inodecache(void)
static void ext2_clear_inode(struct inode *inode) static void ext2_clear_inode(struct inode *inode)
{ {
struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info; 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_discard_reservation(inode);
EXT2_I(inode)->i_block_alloc_info = NULL; EXT2_I(inode)->i_block_alloc_info = NULL;
if (unlikely(rsv)) if (unlikely(rsv))

View file

@ -126,33 +126,6 @@ fail:
return ERR_PTR(-EINVAL); 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 != EXT3_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 != EXT3_ACL_NOT_CACHED)
posix_acl_release(*i_acl);
*i_acl = posix_acl_dup(acl);
spin_unlock(&inode->i_lock);
}
/* /*
* Inode operation get_posix_acl(). * Inode operation get_posix_acl().
* *
@ -161,7 +134,6 @@ ext3_iset_acl(struct inode *inode, struct posix_acl **i_acl,
static struct posix_acl * static struct posix_acl *
ext3_get_acl(struct inode *inode, int type) ext3_get_acl(struct inode *inode, int type)
{ {
struct ext3_inode_info *ei = EXT3_I(inode);
int name_index; int name_index;
char *value = NULL; char *value = NULL;
struct posix_acl *acl; struct posix_acl *acl;
@ -170,24 +142,21 @@ ext3_get_acl(struct inode *inode, int type)
if (!test_opt(inode->i_sb, POSIX_ACL)) if (!test_opt(inode->i_sb, POSIX_ACL))
return NULL; return NULL;
switch(type) { acl = get_cached_acl(inode, type);
case ACL_TYPE_ACCESS: if (acl != ACL_NOT_CACHED)
acl = ext3_iget_acl(inode, &ei->i_acl); return acl;
if (acl != EXT3_ACL_NOT_CACHED)
return acl;
name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
break;
case ACL_TYPE_DEFAULT: switch (type) {
acl = ext3_iget_acl(inode, &ei->i_default_acl); case ACL_TYPE_ACCESS:
if (acl != EXT3_ACL_NOT_CACHED) name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
return acl; break;
name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT; case ACL_TYPE_DEFAULT:
break; name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT;
break;
default: default:
return ERR_PTR(-EINVAL); BUG();
} }
retval = ext3_xattr_get(inode, name_index, "", NULL, 0); retval = ext3_xattr_get(inode, name_index, "", NULL, 0);
if (retval > 0) { if (retval > 0) {
value = kmalloc(retval, GFP_NOFS); value = kmalloc(retval, GFP_NOFS);
@ -203,17 +172,9 @@ ext3_get_acl(struct inode *inode, int type)
acl = ERR_PTR(retval); acl = ERR_PTR(retval);
kfree(value); kfree(value);
if (!IS_ERR(acl)) { if (!IS_ERR(acl))
switch(type) { set_cached_acl(inode, type, acl);
case ACL_TYPE_ACCESS:
ext3_iset_acl(inode, &ei->i_acl, acl);
break;
case ACL_TYPE_DEFAULT:
ext3_iset_acl(inode, &ei->i_default_acl, acl);
break;
}
}
return acl; return acl;
} }
@ -226,7 +187,6 @@ static int
ext3_set_acl(handle_t *handle, struct inode *inode, int type, ext3_set_acl(handle_t *handle, struct inode *inode, int type,
struct posix_acl *acl) struct posix_acl *acl)
{ {
struct ext3_inode_info *ei = EXT3_I(inode);
int name_index; int name_index;
void *value = NULL; void *value = NULL;
size_t size = 0; size_t size = 0;
@ -271,17 +231,10 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
value, size, 0); value, size, 0);
kfree(value); kfree(value);
if (!error) {
switch(type) {
case ACL_TYPE_ACCESS:
ext3_iset_acl(inode, &ei->i_acl, acl);
break;
case ACL_TYPE_DEFAULT: if (!error)
ext3_iset_acl(inode, &ei->i_default_acl, acl); set_cached_acl(inode, type, acl);
break;
}
}
return error; return error;
} }

View file

@ -53,10 +53,6 @@ static inline int ext3_acl_count(size_t size)
#ifdef CONFIG_EXT3_FS_POSIX_ACL #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 */ /* acl.c */
extern int ext3_permission (struct inode *, int); extern int ext3_permission (struct inode *, int);
extern int ext3_acl_chmod (struct inode *); extern int ext3_acl_chmod (struct inode *);

View file

@ -2752,10 +2752,6 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
return inode; return inode;
ei = EXT3_I(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; ei->i_block_alloc_info = NULL;
ret = __ext3_get_inode_loc(inode, &iloc, 0); ret = __ext3_get_inode_loc(inode, &iloc, 0);

View file

@ -464,10 +464,6 @@ static struct inode *ext3_alloc_inode(struct super_block *sb)
ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS); ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS);
if (!ei) if (!ei)
return NULL; 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->i_block_alloc_info = NULL;
ei->vfs_inode.i_version = 1; ei->vfs_inode.i_version = 1;
return &ei->vfs_inode; return &ei->vfs_inode;
@ -518,18 +514,6 @@ static void destroy_inodecache(void)
static void ext3_clear_inode(struct inode *inode) static void ext3_clear_inode(struct inode *inode)
{ {
struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info; 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_discard_reservation(inode);
EXT3_I(inode)->i_block_alloc_info = NULL; EXT3_I(inode)->i_block_alloc_info = NULL;
if (unlikely(rsv)) if (unlikely(rsv))

View file

@ -126,33 +126,6 @@ fail:
return ERR_PTR(-EINVAL); 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 != EXT4_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 != EXT4_ACL_NOT_CACHED)
posix_acl_release(*i_acl);
*i_acl = posix_acl_dup(acl);
spin_unlock(&inode->i_lock);
}
/* /*
* Inode operation get_posix_acl(). * Inode operation get_posix_acl().
* *
@ -161,7 +134,6 @@ ext4_iset_acl(struct inode *inode, struct posix_acl **i_acl,
static struct posix_acl * static struct posix_acl *
ext4_get_acl(struct inode *inode, int type) ext4_get_acl(struct inode *inode, int type)
{ {
struct ext4_inode_info *ei = EXT4_I(inode);
int name_index; int name_index;
char *value = NULL; char *value = NULL;
struct posix_acl *acl; struct posix_acl *acl;
@ -170,23 +142,19 @@ ext4_get_acl(struct inode *inode, int type)
if (!test_opt(inode->i_sb, POSIX_ACL)) if (!test_opt(inode->i_sb, POSIX_ACL))
return NULL; return NULL;
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
acl = ext4_iget_acl(inode, &ei->i_acl);
if (acl != EXT4_ACL_NOT_CACHED)
return acl;
name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
acl = ext4_iget_acl(inode, &ei->i_default_acl);
if (acl != EXT4_ACL_NOT_CACHED)
return acl;
name_index = EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT; name_index = EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT;
break; break;
default: default:
return ERR_PTR(-EINVAL); BUG();
} }
retval = ext4_xattr_get(inode, name_index, "", NULL, 0); retval = ext4_xattr_get(inode, name_index, "", NULL, 0);
if (retval > 0) { if (retval > 0) {
@ -203,17 +171,9 @@ ext4_get_acl(struct inode *inode, int type)
acl = ERR_PTR(retval); acl = ERR_PTR(retval);
kfree(value); kfree(value);
if (!IS_ERR(acl)) { if (!IS_ERR(acl))
switch (type) { set_cached_acl(inode, type, acl);
case ACL_TYPE_ACCESS:
ext4_iset_acl(inode, &ei->i_acl, acl);
break;
case ACL_TYPE_DEFAULT:
ext4_iset_acl(inode, &ei->i_default_acl, acl);
break;
}
}
return acl; return acl;
} }
@ -226,7 +186,6 @@ static int
ext4_set_acl(handle_t *handle, struct inode *inode, int type, ext4_set_acl(handle_t *handle, struct inode *inode, int type,
struct posix_acl *acl) struct posix_acl *acl)
{ {
struct ext4_inode_info *ei = EXT4_I(inode);
int name_index; int name_index;
void *value = NULL; void *value = NULL;
size_t size = 0; size_t size = 0;
@ -271,17 +230,9 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
value, size, 0); value, size, 0);
kfree(value); kfree(value);
if (!error) { if (!error)
switch (type) { set_cached_acl(inode, type, acl);
case ACL_TYPE_ACCESS:
ext4_iset_acl(inode, &ei->i_acl, acl);
break;
case ACL_TYPE_DEFAULT:
ext4_iset_acl(inode, &ei->i_default_acl, acl);
break;
}
}
return error; return error;
} }

View file

@ -53,10 +53,6 @@ static inline int ext4_acl_count(size_t size)
#ifdef CONFIG_EXT4_FS_POSIX_ACL #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 */ /* acl.c */
extern int ext4_permission(struct inode *, int); extern int ext4_permission(struct inode *, int);
extern int ext4_acl_chmod(struct inode *); extern int ext4_acl_chmod(struct inode *);

View file

@ -595,10 +595,6 @@ struct ext4_inode_info {
*/ */
struct rw_semaphore xattr_sem; struct rw_semaphore xattr_sem;
#endif #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 */ struct list_head i_orphan; /* unlinked but open inodes */

View file

@ -4453,10 +4453,6 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
return inode; return inode;
ei = EXT4_I(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); ret = __ext4_get_inode_loc(inode, &iloc, 0);
if (ret < 0) if (ret < 0)

View file

@ -666,10 +666,6 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
if (!ei) if (!ei)
return NULL; 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_version = 1;
ei->vfs_inode.i_data.writeback_index = 0; ei->vfs_inode.i_data.writeback_index = 0;
memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); 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) 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); ext4_discard_preallocations(inode);
if (EXT4_JOURNAL(inode)) if (EXT4_JOURNAL(inode))
jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal,

View file

@ -278,7 +278,26 @@ int sb_has_dirty_inodes(struct super_block *sb)
EXPORT_SYMBOL(sb_has_dirty_inodes); 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. * If `wait' is set, wait on the writeout.
* *
* The whole writeout design is quite complex and fragile. We want to avoid * 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. * Called under inode_lock.
*/ */
static int 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; struct address_space *mapping = inode->i_mapping;
int wait = wbc->sync_mode == WB_SYNC_ALL; int wait = wbc->sync_mode == WB_SYNC_ALL;
unsigned dirty;
int ret; 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); BUG_ON(inode->i_state & I_SYNC);
/* Set I_SYNC, reset I_DIRTY */ /* Set I_SYNC, reset I_DIRTY */
@ -389,50 +433,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
return ret; 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 * 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. * 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)); BUG_ON(inode->i_state & (I_FREEING | I_CLEAR));
__iget(inode); __iget(inode);
pages_skipped = wbc->pages_skipped; pages_skipped = wbc->pages_skipped;
__writeback_single_inode(inode, wbc); writeback_single_inode(inode, wbc);
if (current_is_pdflush()) if (current_is_pdflush())
writeback_release(bdi); writeback_release(bdi);
if (wbc->pages_skipped != pages_skipped) { if (wbc->pages_skipped != pages_skipped) {
@ -708,7 +708,7 @@ int write_inode_now(struct inode *inode, int sync)
might_sleep(); might_sleep();
spin_lock(&inode_lock); spin_lock(&inode_lock);
ret = __writeback_single_inode(inode, &wbc); ret = writeback_single_inode(inode, &wbc);
spin_unlock(&inode_lock); spin_unlock(&inode_lock);
if (sync) if (sync)
inode_sync_wait(inode); inode_sync_wait(inode);
@ -732,7 +732,7 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc)
int ret; int ret;
spin_lock(&inode_lock); spin_lock(&inode_lock);
ret = __writeback_single_inode(inode, wbc); ret = writeback_single_inode(inode, wbc);
spin_unlock(&inode_lock); spin_unlock(&inode_lock);
return ret; return ret;
} }

View file

@ -25,6 +25,7 @@
#include <linux/fsnotify.h> #include <linux/fsnotify.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/async.h> #include <linux/async.h>
#include <linux/posix_acl.h>
/* /*
* This is needed for the following functions: * 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_private = NULL;
inode->i_mapping = mapping; inode->i_mapping = mapping;
#ifdef CONFIG_FS_POSIX_ACL
inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
#endif
#ifdef CONFIG_FSNOTIFY #ifdef CONFIG_FSNOTIFY
inode->i_fsnotify_mask = 0; inode->i_fsnotify_mask = 0;
@ -227,6 +231,12 @@ void destroy_inode(struct inode *inode)
ima_inode_free(inode); ima_inode_free(inode);
security_inode_free(inode); security_inode_free(inode);
fsnotify_inode_delete(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) if (inode->i_sb->s_op->destroy_inode)
inode->i_sb->s_op->destroy_inode(inode); inode->i_sb->s_op->destroy_inode(inode);
else else

View file

@ -15,6 +15,7 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/writeback.h> #include <linux/writeback.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/falloc.h>
#include <asm/ioctls.h> #include <asm/ioctls.h>
@ -403,6 +404,37 @@ EXPORT_SYMBOL(generic_block_fiemap);
#endif /* CONFIG_BLOCK */ #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, static int file_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
@ -414,6 +446,9 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
return ioctl_fibmap(filp, p); return ioctl_fibmap(filp, p);
case FIONREAD: case FIONREAD:
return put_user(i_size_read(inode) - filp->f_pos, p); 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); return vfs_ioctl(filp, cmd, arg);

View file

@ -156,48 +156,25 @@ static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
static struct posix_acl *jffs2_iget_acl(struct inode *inode, struct posix_acl **i_acl)
{
struct posix_acl *acl = JFFS2_ACL_NOT_CACHED;
spin_lock(&inode->i_lock);
if (*i_acl != JFFS2_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 != JFFS2_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) 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; struct posix_acl *acl;
char *value = NULL; char *value = NULL;
int rc, xprefix; int rc, xprefix;
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
acl = jffs2_iget_acl(inode, &f->i_acl_access);
if (acl != JFFS2_ACL_NOT_CACHED)
return acl;
xprefix = JFFS2_XPREFIX_ACL_ACCESS; xprefix = JFFS2_XPREFIX_ACL_ACCESS;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
acl = jffs2_iget_acl(inode, &f->i_acl_default);
if (acl != JFFS2_ACL_NOT_CACHED)
return acl;
xprefix = JFFS2_XPREFIX_ACL_DEFAULT; xprefix = JFFS2_XPREFIX_ACL_DEFAULT;
break; break;
default: default:
return ERR_PTR(-EINVAL); BUG();
} }
rc = do_jffs2_getxattr(inode, xprefix, "", NULL, 0); rc = do_jffs2_getxattr(inode, xprefix, "", NULL, 0);
if (rc > 0) { if (rc > 0) {
@ -215,16 +192,8 @@ static struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
} }
if (value) if (value)
kfree(value); kfree(value);
if (!IS_ERR(acl)) { if (!IS_ERR(acl))
switch (type) { set_cached_acl(inode, type, acl);
case ACL_TYPE_ACCESS:
jffs2_iset_acl(inode, &f->i_acl_access, acl);
break;
case ACL_TYPE_DEFAULT:
jffs2_iset_acl(inode, &f->i_acl_default, acl);
break;
}
}
return acl; return acl;
} }
@ -249,7 +218,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) 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; int rc, xprefix;
if (S_ISLNK(inode->i_mode)) if (S_ISLNK(inode->i_mode))
@ -285,16 +253,8 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
return -EINVAL; return -EINVAL;
} }
rc = __jffs2_set_acl(inode, xprefix, acl); rc = __jffs2_set_acl(inode, xprefix, acl);
if (!rc) { if (!rc)
switch(type) { set_cached_acl(inode, type, acl);
case ACL_TYPE_ACCESS:
jffs2_iset_acl(inode, &f->i_acl_access, acl);
break;
case ACL_TYPE_DEFAULT:
jffs2_iset_acl(inode, &f->i_acl_default, acl);
break;
}
}
return rc; return rc;
} }
@ -321,12 +281,11 @@ int jffs2_permission(struct inode *inode, int mask)
int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
{ {
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
struct posix_acl *acl, *clone; struct posix_acl *acl, *clone;
int rc; int rc;
f->i_acl_default = NULL; inode->i_default_acl = NULL;
f->i_acl_access = NULL; inode->i_acl = NULL;
if (S_ISLNK(*i_mode)) if (S_ISLNK(*i_mode))
return 0; /* Symlink always has no-ACL */ return 0; /* Symlink always has no-ACL */
@ -339,7 +298,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
*i_mode &= ~current_umask(); *i_mode &= ~current_umask();
} else { } else {
if (S_ISDIR(*i_mode)) if (S_ISDIR(*i_mode))
jffs2_iset_acl(inode, &f->i_acl_default, acl); set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);
clone = posix_acl_clone(acl, GFP_KERNEL); clone = posix_acl_clone(acl, GFP_KERNEL);
if (!clone) if (!clone)
@ -350,7 +309,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
return rc; return rc;
} }
if (rc > 0) if (rc > 0)
jffs2_iset_acl(inode, &f->i_acl_access, clone); set_cached_acl(inode, ACL_TYPE_ACCESS, clone);
posix_acl_release(clone); posix_acl_release(clone);
} }
@ -359,17 +318,16 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
int jffs2_init_acl_post(struct inode *inode) int jffs2_init_acl_post(struct inode *inode)
{ {
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
int rc; int rc;
if (f->i_acl_default) { if (inode->i_default_acl) {
rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, f->i_acl_default); rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl);
if (rc) if (rc)
return rc; return rc;
} }
if (f->i_acl_access) { if (inode->i_acl) {
rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, f->i_acl_access); rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl);
if (rc) if (rc)
return rc; return rc;
} }
@ -377,18 +335,6 @@ int jffs2_init_acl_post(struct inode *inode)
return 0; 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) int jffs2_acl_chmod(struct inode *inode)
{ {
struct posix_acl *acl, *clone; struct posix_acl *acl, *clone;

View file

@ -26,13 +26,10 @@ struct jffs2_acl_header {
#ifdef CONFIG_JFFS2_FS_POSIX_ACL #ifdef CONFIG_JFFS2_FS_POSIX_ACL
#define JFFS2_ACL_NOT_CACHED ((void *)-1)
extern int jffs2_permission(struct inode *, int); extern int jffs2_permission(struct inode *, int);
extern int jffs2_acl_chmod(struct inode *); extern int jffs2_acl_chmod(struct inode *);
extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *);
extern int jffs2_init_acl_post(struct inode *); 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_access_xattr_handler;
extern struct xattr_handler jffs2_acl_default_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_acl_chmod(inode) (0)
#define jffs2_init_acl_pre(dir_i,inode,mode) (0) #define jffs2_init_acl_pre(dir_i,inode,mode) (0)
#define jffs2_init_acl_post(inode) (0) #define jffs2_init_acl_post(inode) (0)
#define jffs2_clear_acl(f)
#endif /* CONFIG_JFFS2_FS_POSIX_ACL */ #endif /* CONFIG_JFFS2_FS_POSIX_ACL */

View file

@ -50,10 +50,6 @@ struct jffs2_inode_info {
uint16_t flags; uint16_t flags;
uint8_t usercompr; uint8_t usercompr;
struct inode vfs_inode; 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 */ #endif /* _JFFS2_FS_I */

View file

@ -56,10 +56,6 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
f->target = NULL; f->target = NULL;
f->flags = 0; f->flags = 0;
f->usercompr = 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
} }

View file

@ -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; struct jffs2_full_dirent *fd, *fds;
int deleted; int deleted;
jffs2_clear_acl(f);
jffs2_xattr_delete_inode(c, f->inocache); jffs2_xattr_delete_inode(c, f->inocache);
mutex_lock(&f->sem); mutex_lock(&f->sem);
deleted = f->inocache && !f->inocache->pino_nlink; deleted = f->inocache && !f->inocache->pino_nlink;

View file

@ -31,27 +31,24 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type)
{ {
struct posix_acl *acl; struct posix_acl *acl;
char *ea_name; char *ea_name;
struct jfs_inode_info *ji = JFS_IP(inode);
struct posix_acl **p_acl;
int size; int size;
char *value = NULL; char *value = NULL;
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
switch(type) { switch(type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
ea_name = POSIX_ACL_XATTR_ACCESS; ea_name = POSIX_ACL_XATTR_ACCESS;
p_acl = &ji->i_acl;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
ea_name = POSIX_ACL_XATTR_DEFAULT; ea_name = POSIX_ACL_XATTR_DEFAULT;
p_acl = &ji->i_default_acl;
break; break;
default: default:
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
if (*p_acl != JFS_ACL_NOT_CACHED)
return posix_acl_dup(*p_acl);
size = __jfs_getxattr(inode, ea_name, NULL, 0); size = __jfs_getxattr(inode, ea_name, NULL, 0);
if (size > 0) { if (size > 0) {
@ -62,17 +59,18 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type)
} }
if (size < 0) { if (size < 0) {
if (size == -ENODATA) { if (size == -ENODATA)
*p_acl = NULL;
acl = NULL; acl = NULL;
} else else
acl = ERR_PTR(size); acl = ERR_PTR(size);
} else { } else {
acl = posix_acl_from_xattr(value, size); acl = posix_acl_from_xattr(value, size);
if (!IS_ERR(acl))
*p_acl = posix_acl_dup(acl);
} }
kfree(value); kfree(value);
if (!IS_ERR(acl)) {
set_cached_acl(inode, type, acl);
posix_acl_release(acl);
}
return acl; return acl;
} }
@ -80,8 +78,6 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type,
struct posix_acl *acl) struct posix_acl *acl)
{ {
char *ea_name; char *ea_name;
struct jfs_inode_info *ji = JFS_IP(inode);
struct posix_acl **p_acl;
int rc; int rc;
int size = 0; int size = 0;
char *value = NULL; char *value = NULL;
@ -92,11 +88,9 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type,
switch(type) { switch(type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
ea_name = POSIX_ACL_XATTR_ACCESS; ea_name = POSIX_ACL_XATTR_ACCESS;
p_acl = &ji->i_acl;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
ea_name = POSIX_ACL_XATTR_DEFAULT; ea_name = POSIX_ACL_XATTR_DEFAULT;
p_acl = &ji->i_default_acl;
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
return acl ? -EACCES : 0; return acl ? -EACCES : 0;
break; break;
@ -116,27 +110,23 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type,
out: out:
kfree(value); kfree(value);
if (!rc) { if (!rc)
if (*p_acl && (*p_acl != JFS_ACL_NOT_CACHED)) set_cached_acl(inode, type, acl);
posix_acl_release(*p_acl);
*p_acl = posix_acl_dup(acl);
}
return rc; return rc;
} }
static int jfs_check_acl(struct inode *inode, int mask) static int jfs_check_acl(struct inode *inode, int mask)
{ {
struct jfs_inode_info *ji = JFS_IP(inode); if (inode->i_acl == ACL_NOT_CACHED) {
if (ji->i_acl == JFS_ACL_NOT_CACHED) {
struct posix_acl *acl = jfs_get_acl(inode, ACL_TYPE_ACCESS); struct posix_acl *acl = jfs_get_acl(inode, ACL_TYPE_ACCESS);
if (IS_ERR(acl)) if (IS_ERR(acl))
return PTR_ERR(acl); return PTR_ERR(acl);
posix_acl_release(acl); posix_acl_release(acl);
} }
if (ji->i_acl) if (inode->i_acl)
return posix_acl_permission(inode, ji->i_acl, mask); return posix_acl_permission(inode, inode->i_acl, mask);
return -EAGAIN; return -EAGAIN;
} }

View file

@ -74,10 +74,6 @@ struct jfs_inode_info {
/* xattr_sem allows us to access the xattrs without taking i_mutex */ /* xattr_sem allows us to access the xattrs without taking i_mutex */
struct rw_semaphore xattr_sem; struct rw_semaphore xattr_sem;
lid_t xtlid; /* lid of xtree lock on directory */ 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 { union {
struct { struct {
xtpage_t _xtroot; /* 288: xtree root */ xtpage_t _xtroot; /* 288: xtree root */
@ -107,8 +103,6 @@ struct jfs_inode_info {
#define i_inline u.link._inline #define i_inline u.link._inline
#define i_inline_ea u.link._inline_ea #define i_inline_ea u.link._inline_ea
#define JFS_ACL_NOT_CACHED ((void *)-1)
#define IREAD_LOCK(ip, subclass) \ #define IREAD_LOCK(ip, subclass) \
down_read_nested(&JFS_IP(ip)->rdwrlock, subclass) down_read_nested(&JFS_IP(ip)->rdwrlock, subclass)
#define IREAD_UNLOCK(ip) up_read(&JFS_IP(ip)->rdwrlock) #define IREAD_UNLOCK(ip) up_read(&JFS_IP(ip)->rdwrlock)

View file

@ -128,18 +128,6 @@ static void jfs_destroy_inode(struct inode *inode)
ji->active_ag = -1; ji->active_ag = -1;
} }
spin_unlock_irq(&ji->ag_lock); 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); kmem_cache_free(jfs_inode_cachep, ji);
} }
@ -798,10 +786,6 @@ static void init_once(void *foo)
init_rwsem(&jfs_ip->xattr_sem); init_rwsem(&jfs_ip->xattr_sem);
spin_lock_init(&jfs_ip->ag_lock); spin_lock_init(&jfs_ip->ag_lock);
jfs_ip->active_ag = -1; 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); inode_init_once(&jfs_ip->vfs_inode);
} }

View file

@ -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 * We're changing the ACL. Get rid of the cached one
*/ */
acl =JFS_IP(inode)->i_acl; forget_cached_acl(inode, ACL_TYPE_ACCESS);
if (acl != JFS_ACL_NOT_CACHED)
posix_acl_release(acl);
JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED;
return 0; return 0;
} else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 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 * We're changing the default ACL. Get rid of the cached one
*/ */
acl =JFS_IP(inode)->i_default_acl; forget_cached_acl(inode, ACL_TYPE_DEFAULT);
if (acl && (acl != JFS_ACL_NOT_CACHED))
posix_acl_release(acl);
JFS_IP(inode)->i_default_acl = JFS_ACL_NOT_CACHED;
return 0; return 0;
} }

View file

@ -1698,8 +1698,11 @@ struct file *do_filp_open(int dfd, const char *pathname,
if (error) if (error)
return ERR_PTR(error); return ERR_PTR(error);
error = path_walk(pathname, &nd); error = path_walk(pathname, &nd);
if (error) if (error) {
if (nd.root.mnt)
path_put(&nd.root);
return ERR_PTR(error); return ERR_PTR(error);
}
if (unlikely(!audit_dummy_context())) if (unlikely(!audit_dummy_context()))
audit_inode(pathname, nd.path.dentry); audit_inode(pathname, nd.path.dentry);
@ -1759,6 +1762,8 @@ do_last:
} }
filp = nameidata_to_filp(&nd, open_flag); filp = nameidata_to_filp(&nd, open_flag);
mnt_drop_write(nd.path.mnt); mnt_drop_write(nd.path.mnt);
if (nd.root.mnt)
path_put(&nd.root);
return filp; return filp;
} }
@ -1819,6 +1824,8 @@ ok:
*/ */
if (will_write) if (will_write)
mnt_drop_write(nd.path.mnt); mnt_drop_write(nd.path.mnt);
if (nd.root.mnt)
path_put(&nd.root);
return filp; return filp;
exit_mutex_unlock: exit_mutex_unlock:
@ -1859,6 +1866,8 @@ do_link:
* with "intent.open". * with "intent.open".
*/ */
release_open_intent(&nd); release_open_intent(&nd);
if (nd.root.mnt)
path_put(&nd.root);
return ERR_PTR(error); return ERR_PTR(error);
} }
nd.flags &= ~LOOKUP_PARENT; nd.flags &= ~LOOKUP_PARENT;

View file

@ -42,6 +42,8 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
static int event; static int event;
static DEFINE_IDA(mnt_id_ida); static DEFINE_IDA(mnt_id_ida);
static DEFINE_IDA(mnt_group_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 list_head *mount_hashtable __read_mostly;
static struct kmem_cache *mnt_cache __read_mostly; static struct kmem_cache *mnt_cache __read_mostly;
@ -69,7 +71,9 @@ static int mnt_alloc_id(struct vfsmount *mnt)
retry: retry:
ida_pre_get(&mnt_id_ida, GFP_KERNEL); ida_pre_get(&mnt_id_ida, GFP_KERNEL);
spin_lock(&vfsmount_lock); 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); spin_unlock(&vfsmount_lock);
if (res == -EAGAIN) if (res == -EAGAIN)
goto retry; goto retry;
@ -79,8 +83,11 @@ retry:
static void mnt_free_id(struct vfsmount *mnt) static void mnt_free_id(struct vfsmount *mnt)
{ {
int id = mnt->mnt_id;
spin_lock(&vfsmount_lock); 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); 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) static int mnt_alloc_group_id(struct vfsmount *mnt)
{ {
int res;
if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL)) if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL))
return -ENOMEM; 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) 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; mnt->mnt_group_id = 0;
} }
@ -2222,16 +2240,9 @@ static void __init init_mount_tree(void)
mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
if (IS_ERR(mnt)) if (IS_ERR(mnt))
panic("Can't create rootfs"); panic("Can't create rootfs");
ns = kmalloc(sizeof(*ns), GFP_KERNEL); ns = create_mnt_ns(mnt);
if (!ns) if (IS_ERR(ns))
panic("Can't allocate initial namespace"); 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; init_task.nsproxy->mnt_ns = ns;
get_mnt_ns(ns); get_mnt_ns(ns);

View file

@ -309,10 +309,6 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode)
/* ii->i_file_acl = 0; */ /* ii->i_file_acl = 0; */
/* ii->i_dir_acl = 0; */ /* ii->i_dir_acl = 0; */
ii->i_dir_start_lookup = 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; ii->i_cno = 0;
nilfs_set_inode_flags(inode); nilfs_set_inode_flags(inode);
spin_lock(&sbi->s_next_gen_lock); 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); 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)) if (nilfs_read_inode_common(inode, raw_inode))
goto failed_unmap; goto failed_unmap;

View file

@ -57,10 +57,6 @@ struct nilfs_inode_info {
* EAs. * EAs.
*/ */
struct rw_semaphore xattr_sem; struct rw_semaphore xattr_sem;
#endif
#ifdef CONFIG_NILFS_POSIX_ACL
struct posix_acl *i_acl;
struct posix_acl *i_default_acl;
#endif #endif
struct buffer_head *i_bh; /* i_bh contains a new or dirty struct buffer_head *i_bh; /* i_bh contains a new or dirty
disk inode */ disk inode */

View file

@ -189,16 +189,6 @@ static void nilfs_clear_inode(struct inode *inode)
{ {
struct nilfs_inode_info *ii = NILFS_I(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. * Free resources allocated in nilfs_read_inode(), here.
*/ */

View file

@ -378,63 +378,63 @@ SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64);
#endif #endif
#endif /* BITS_PER_LONG == 32 */ #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 = file->f_path.dentry->d_inode;
struct inode *inode; long ret;
long ret = -EINVAL;
if (offset < 0 || len <= 0) if (offset < 0 || len <= 0)
goto out; return -EINVAL;
/* Return error if mode is not supported */ /* Return error if mode is not supported */
ret = -EOPNOTSUPP;
if (mode && !(mode & FALLOC_FL_KEEP_SIZE)) 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)) if (!(file->f_mode & FMODE_WRITE))
goto out_fput; return -EBADF;
/* /*
* Revalidate the write permissions, in case security policy has * Revalidate the write permissions, in case security policy has
* changed since the files were opened. * changed since the files were opened.
*/ */
ret = security_file_permission(file, MAY_WRITE); ret = security_file_permission(file, MAY_WRITE);
if (ret) if (ret)
goto out_fput; return ret;
inode = file->f_path.dentry->d_inode;
ret = -ESPIPE;
if (S_ISFIFO(inode->i_mode)) if (S_ISFIFO(inode->i_mode))
goto out_fput; return -ESPIPE;
ret = -ENODEV;
/* /*
* Let individual file system decide if it supports preallocation * Let individual file system decide if it supports preallocation
* for directories or not. * for directories or not.
*/ */
if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
goto out_fput; return -ENODEV;
ret = -EFBIG;
/* Check for wrap through zero too */ /* Check for wrap through zero too */
if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
goto out_fput; return -EFBIG;
if (inode->i_op->fallocate) if (!inode->i_op->fallocate)
ret = inode->i_op->fallocate(inode, mode, offset, len); return -EOPNOTSUPP;
else
ret = -EOPNOTSUPP;
out_fput: return inode->i_op->fallocate(inode, mode, offset, len);
fput(file);
out:
return ret;
} }
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 #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len) asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len)
{ {

View file

@ -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_trans_id = 0;
REISERFS_I(inode)->i_jl = NULL; REISERFS_I(inode)->i_jl = NULL;
mutex_init(&(REISERFS_I(inode)->i_mmap)); mutex_init(&(REISERFS_I(inode)->i_mmap));
reiserfs_init_acl_access(inode);
reiserfs_init_acl_default(inode);
reiserfs_init_xattr_rwsem(inode); reiserfs_init_xattr_rwsem(inode);
if (stat_data_v1(ih)) { 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; REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode);
mutex_init(&(REISERFS_I(inode)->i_mmap)); mutex_init(&(REISERFS_I(inode)->i_mmap));
reiserfs_init_acl_access(inode);
reiserfs_init_acl_default(inode);
reiserfs_init_xattr_rwsem(inode); reiserfs_init_xattr_rwsem(inode);
/* key to search for correct place for new stat data */ /* key to search for correct place for new stat data */

View file

@ -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) { if (reiserfs_allocate_list_bitmaps(s, jbitmap, bmap_nr_new) < 0) {
printk printk
("reiserfs_resize: unable to allocate memory for journal bitmaps\n"); ("reiserfs_resize: unable to allocate memory for journal bitmaps\n");
unlock_super(s);
return -ENOMEM; return -ENOMEM;
} }
/* the new journal bitmaps are zero filled, now we copy in the bitmap /* the new journal bitmaps are zero filled, now we copy in the bitmap

View file

@ -529,10 +529,6 @@ static void init_once(void *foo)
INIT_LIST_HEAD(&ei->i_prealloc_list); INIT_LIST_HEAD(&ei->i_prealloc_list);
inode_init_once(&ei->vfs_inode); inode_init_once(&ei->vfs_inode);
#ifdef CONFIG_REISERFS_FS_POSIX_ACL
ei->i_acl_access = NULL;
ei->i_acl_default = NULL;
#endif
} }
static int init_inodecache(void) static int init_inodecache(void)
@ -580,25 +576,6 @@ static void reiserfs_dirty_inode(struct inode *inode)
reiserfs_write_unlock(inode->i_sb); 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 && !IS_ERR(acl))
posix_acl_release(acl);
REISERFS_I(inode)->i_acl_access = NULL;
acl = REISERFS_I(inode)->i_acl_default;
if (acl && !IS_ERR(acl))
posix_acl_release(acl);
REISERFS_I(inode)->i_acl_default = NULL;
}
#else
#define reiserfs_clear_inode NULL
#endif
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
static ssize_t reiserfs_quota_write(struct super_block *, int, const char *, static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
size_t, loff_t); size_t, loff_t);
@ -612,7 +589,6 @@ static const struct super_operations reiserfs_sops = {
.write_inode = reiserfs_write_inode, .write_inode = reiserfs_write_inode,
.dirty_inode = reiserfs_dirty_inode, .dirty_inode = reiserfs_dirty_inode,
.delete_inode = reiserfs_delete_inode, .delete_inode = reiserfs_delete_inode,
.clear_inode = reiserfs_clear_inode,
.put_super = reiserfs_put_super, .put_super = reiserfs_put_super,
.write_super = reiserfs_write_super, .write_super = reiserfs_write_super,
.sync_fs = reiserfs_sync_fs, .sync_fs = reiserfs_sync_fs,

View file

@ -188,29 +188,6 @@ static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size)
return ERR_PTR(-EINVAL); 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 != ERR_PTR(-ENODATA))
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 = ERR_PTR(-ENODATA);
spin_lock(&inode->i_lock);
if (*i_acl != ERR_PTR(-ENODATA))
acl = posix_acl_dup(*i_acl);
spin_unlock(&inode->i_lock);
return acl;
}
/* /*
* Inode operation get_posix_acl(). * Inode operation get_posix_acl().
* *
@ -220,34 +197,29 @@ static inline struct posix_acl *iget_acl(struct inode *inode,
struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
{ {
char *name, *value; char *name, *value;
struct posix_acl *acl, **p_acl; struct posix_acl *acl;
int size; int size;
int retval; int retval;
struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = POSIX_ACL_XATTR_ACCESS;
p_acl = &reiserfs_i->i_acl_access;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT; name = POSIX_ACL_XATTR_DEFAULT;
p_acl = &reiserfs_i->i_acl_default;
break; break;
default: default:
return ERR_PTR(-EINVAL); BUG();
} }
acl = iget_acl(inode, p_acl);
if (acl && !IS_ERR(acl))
return acl;
else if (PTR_ERR(acl) == -ENODATA)
return NULL;
size = reiserfs_xattr_get(inode, name, NULL, 0); size = reiserfs_xattr_get(inode, name, NULL, 0);
if (size < 0) { if (size < 0) {
if (size == -ENODATA || size == -ENOSYS) { if (size == -ENODATA || size == -ENOSYS) {
*p_acl = ERR_PTR(-ENODATA); set_cached_acl(inode, type, NULL);
return NULL; return NULL;
} }
return ERR_PTR(size); return ERR_PTR(size);
@ -262,14 +234,13 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
/* This shouldn't actually happen as it should have /* This shouldn't actually happen as it should have
been caught above.. but just in case */ been caught above.. but just in case */
acl = NULL; acl = NULL;
*p_acl = ERR_PTR(-ENODATA);
} else if (retval < 0) { } else if (retval < 0) {
acl = ERR_PTR(retval); acl = ERR_PTR(retval);
} else { } else {
acl = posix_acl_from_disk(value, retval); 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); kfree(value);
return acl; return acl;
@ -287,10 +258,8 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
{ {
char *name; char *name;
void *value = NULL; void *value = NULL;
struct posix_acl **p_acl;
size_t size = 0; size_t size = 0;
int error; int error;
struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
if (S_ISLNK(inode->i_mode)) if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP; return -EOPNOTSUPP;
@ -298,7 +267,6 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS; name = POSIX_ACL_XATTR_ACCESS;
p_acl = &reiserfs_i->i_acl_access;
if (acl) { if (acl) {
mode_t mode = inode->i_mode; mode_t mode = inode->i_mode;
error = posix_acl_equiv_mode(acl, &mode); error = posix_acl_equiv_mode(acl, &mode);
@ -313,7 +281,6 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT; name = POSIX_ACL_XATTR_DEFAULT;
p_acl = &reiserfs_i->i_acl_default;
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
return acl ? -EACCES : 0; return acl ? -EACCES : 0;
break; break;
@ -346,7 +313,7 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
kfree(value); kfree(value);
if (!error) if (!error)
iset_acl(inode, p_acl, acl); set_cached_acl(inode, type, acl);
return error; return error;
} }
@ -379,11 +346,8 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
} }
acl = reiserfs_get_acl(dir, ACL_TYPE_DEFAULT); acl = reiserfs_get_acl(dir, ACL_TYPE_DEFAULT);
if (IS_ERR(acl)) { if (IS_ERR(acl))
if (PTR_ERR(acl) == -ENODATA)
goto apply_umask;
return PTR_ERR(acl); return PTR_ERR(acl);
}
if (acl) { if (acl) {
struct posix_acl *acl_copy; struct posix_acl *acl_copy;

View file

@ -608,6 +608,7 @@ void emergency_remount(void)
static DEFINE_IDA(unnamed_dev_ida); static DEFINE_IDA(unnamed_dev_ida);
static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */ 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) int set_anon_super(struct super_block *s, void *data)
{ {
@ -618,7 +619,9 @@ int set_anon_super(struct super_block *s, void *data)
if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0) if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0)
return -ENOMEM; return -ENOMEM;
spin_lock(&unnamed_dev_lock); 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);
if (!error)
unnamed_dev_start = dev + 1;
spin_unlock(&unnamed_dev_lock); spin_unlock(&unnamed_dev_lock);
if (error == -EAGAIN) if (error == -EAGAIN)
/* We raced and lost with another CPU. */ /* We raced and lost with another CPU. */
@ -629,6 +632,8 @@ int set_anon_super(struct super_block *s, void *data)
if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) { if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) {
spin_lock(&unnamed_dev_lock); spin_lock(&unnamed_dev_lock);
ida_remove(&unnamed_dev_ida, dev); ida_remove(&unnamed_dev_ida, dev);
if (unnamed_dev_start > dev)
unnamed_dev_start = dev;
spin_unlock(&unnamed_dev_lock); spin_unlock(&unnamed_dev_lock);
return -EMFILE; return -EMFILE;
} }
@ -645,6 +650,8 @@ void kill_anon_super(struct super_block *sb)
generic_shutdown_super(sb); generic_shutdown_super(sb);
spin_lock(&unnamed_dev_lock); spin_lock(&unnamed_dev_lock);
ida_remove(&unnamed_dev_ida, slot); ida_remove(&unnamed_dev_ida, slot);
if (slot < unnamed_dev_start)
unnamed_dev_start = slot;
spin_unlock(&unnamed_dev_lock); spin_unlock(&unnamed_dev_lock);
} }

View file

@ -55,9 +55,9 @@
* ACL support is not implemented. * ACL support is not implemented.
*/ */
#include "ubifs.h"
#include <linux/xattr.h> #include <linux/xattr.h>
#include <linux/posix_acl_xattr.h> #include <linux/posix_acl_xattr.h>
#include "ubifs.h"
/* /*
* Limit the number of extended attributes per inode so that the total size * Limit the number of extended attributes per inode so that the total size

View file

@ -25,14 +25,10 @@
#include <linux/posix_acl_xattr.h> #include <linux/posix_acl_xattr.h>
#define XFS_ACL_NOT_CACHED ((void *)-1)
/* /*
* Locking scheme: * Locking scheme:
* - all ACL updates are protected by inode->i_mutex, which is taken before * - all ACL updates are protected by inode->i_mutex, which is taken before
* calling into this file. * 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 * 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 * struct posix_acl *
xfs_get_acl(struct inode *inode, int type) xfs_get_acl(struct inode *inode, int type)
{ {
struct xfs_inode *ip = XFS_I(inode); struct xfs_inode *ip = XFS_I(inode);
struct posix_acl *acl = NULL, **p_acl; struct posix_acl *acl;
struct xfs_acl *xfs_acl; struct xfs_acl *xfs_acl;
int len = sizeof(struct xfs_acl); int len = sizeof(struct xfs_acl);
char *ea_name; char *ea_name;
int error; int error;
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
ea_name = SGI_ACL_FILE; ea_name = SGI_ACL_FILE;
p_acl = &ip->i_acl;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
ea_name = SGI_ACL_DEFAULT; ea_name = SGI_ACL_DEFAULT;
p_acl = &ip->i_default_acl;
break; break;
default: 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 * If we have a cached ACLs value just return it, not need to
* go out to the disk. * go out to the disk.
*/ */
if (acl)
return acl;
xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL); xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
if (!xfs_acl) 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 * If the attribute doesn't exist make sure we have a negative
* cache entry, for any other error assume it is transient and * 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) { if (error == -ENOATTR) {
acl = NULL; acl = NULL;
@ -179,7 +151,7 @@ xfs_get_acl(struct inode *inode, int type)
goto out; goto out;
out_update_cache: out_update_cache:
xfs_update_cached_acl(inode, p_acl, acl); set_cached_acl(inode, type, acl);
out: out:
kfree(xfs_acl); kfree(xfs_acl);
return acl; return acl;
@ -189,7 +161,6 @@ STATIC int
xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
{ {
struct xfs_inode *ip = XFS_I(inode); struct xfs_inode *ip = XFS_I(inode);
struct posix_acl **p_acl;
char *ea_name; char *ea_name;
int error; int error;
@ -199,13 +170,11 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
ea_name = SGI_ACL_FILE; ea_name = SGI_ACL_FILE;
p_acl = &ip->i_acl;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
return acl ? -EACCES : 0; return acl ? -EACCES : 0;
ea_name = SGI_ACL_DEFAULT; ea_name = SGI_ACL_DEFAULT;
p_acl = &ip->i_default_acl;
break; break;
default: default:
return -EINVAL; return -EINVAL;
@ -242,7 +211,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
} }
if (!error) if (!error)
xfs_update_cached_acl(inode, p_acl, acl); set_cached_acl(inode, type, acl);
return error; return error;
} }
@ -384,30 +353,6 @@ xfs_acl_chmod(struct inode *inode)
return error; 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. * System xattr handlers.
* *

View file

@ -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 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_inherit_acl(struct inode *inode, struct posix_acl *default_acl);
extern int xfs_acl_chmod(struct inode *inode); 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_access_exists(struct inode *inode);
extern int posix_acl_default_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_get_acl(inode, type) NULL
# define xfs_inherit_acl(inode, default_acl) 0 # define xfs_inherit_acl(inode, default_acl) 0
# define xfs_acl_chmod(inode) 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_access_exists(inode) 0
# define posix_acl_default_exists(inode) 0 # define posix_acl_default_exists(inode) 0
#endif /* CONFIG_XFS_POSIX_ACL */ #endif /* CONFIG_XFS_POSIX_ACL */

View file

@ -83,7 +83,6 @@ xfs_inode_alloc(
memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
ip->i_size = 0; ip->i_size = 0;
ip->i_new_size = 0; ip->i_new_size = 0;
xfs_inode_init_acls(ip);
/* /*
* Initialize inode's trace buffers. * Initialize inode's trace buffers.
@ -560,7 +559,6 @@ xfs_ireclaim(
ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(atomic_read(&ip->i_pincount) == 0);
ASSERT(!spin_is_locked(&ip->i_flags_lock)); ASSERT(!spin_is_locked(&ip->i_flags_lock));
ASSERT(completion_done(&ip->i_flush)); ASSERT(completion_done(&ip->i_flush));
xfs_inode_clear_acls(ip);
kmem_zone_free(xfs_inode_zone, ip); kmem_zone_free(xfs_inode_zone, ip);
} }

View file

@ -273,11 +273,6 @@ typedef struct xfs_inode {
/* VFS inode */ /* VFS inode */
struct inode i_vnode; /* embedded 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. */ /* Trace buffers per inode. */
#ifdef XFS_INODE_TRACE #ifdef XFS_INODE_TRACE
struct ktrace *i_trace; /* general inode trace */ struct ktrace *i_trace; /* general inode trace */

View file

@ -103,10 +103,6 @@ struct ext3_inode_info {
*/ */
struct rw_semaphore xattr_sem; struct rw_semaphore xattr_sem;
#endif #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 */ struct list_head i_orphan; /* unlinked but open inodes */

View file

@ -3,4 +3,25 @@
#define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */ #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_ */ #endif /* _FALLOC_H_ */

View file

@ -710,6 +710,9 @@ static inline int mapping_writably_mapped(struct address_space *mapping)
#define i_size_ordered_init(inode) do { } while (0) #define i_size_ordered_init(inode) do { } while (0)
#endif #endif
struct posix_acl;
#define ACL_NOT_CACHED ((void *)(-1))
struct inode { struct inode {
struct hlist_node i_hash; struct hlist_node i_hash;
struct list_head i_list; struct list_head i_list;
@ -772,6 +775,10 @@ struct inode {
atomic_t i_writecount; atomic_t i_writecount;
#ifdef CONFIG_SECURITY #ifdef CONFIG_SECURITY
void *i_security; void *i_security;
#endif
#ifdef CONFIG_FS_POSIX_ACL
struct posix_acl *i_acl;
struct posix_acl *i_default_acl;
#endif #endif
void *i_private; /* fs or device private pointer */ void *i_private; /* fs or device private pointer */
}; };
@ -1906,6 +1913,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, extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
struct file *filp); 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, extern long do_sys_open(int dfd, const char __user *filename, int flags,
int mode); int mode);
extern struct file *filp_open(const char *, int, int); extern struct file *filp_open(const char *, int, int);
@ -1914,6 +1923,10 @@ extern struct file * dentry_open(struct dentry *, struct vfsmount *, int,
extern int filp_close(struct file *, fl_owner_t id); extern int filp_close(struct file *, fl_owner_t id);
extern char * getname(const char __user *); extern char * getname(const char __user *);
/* fs/ioctl.c */
extern int ioctl_preallocate(struct file *filp, void __user *argp);
/* fs/dcache.c */ /* fs/dcache.c */
extern void __init vfs_caches_init_early(void); extern void __init vfs_caches_init_early(void);
extern void __init vfs_caches_init(unsigned long); extern void __init vfs_caches_init(unsigned long);

View file

@ -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 struct posix_acl *get_posix_acl(struct inode *, int);
extern int set_posix_acl(struct inode *, int, struct posix_acl *); 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 */ #endif /* __LINUX_POSIX_ACL_H */

View file

@ -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_default_handler;
extern struct xattr_handler reiserfs_posix_acl_access_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 = NULL;
}
static inline void reiserfs_init_acl_default(struct inode *inode)
{
REISERFS_I(inode)->i_acl_default = NULL;
}
#else #else
#define reiserfs_cache_default_acl(inode) 0 #define reiserfs_cache_default_acl(inode) 0
@ -86,12 +77,4 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
{ {
return 0; return 0;
} }
static inline void reiserfs_init_acl_access(struct inode *inode)
{
}
static inline void reiserfs_init_acl_default(struct inode *inode)
{
}
#endif #endif

View file

@ -54,10 +54,6 @@ struct reiserfs_inode_info {
unsigned int i_trans_id; unsigned int i_trans_id;
struct reiserfs_journal_list *i_jl; struct reiserfs_journal_list *i_jl;
struct mutex i_mmap; 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 #ifdef CONFIG_REISERFS_FS_XATTR
struct rw_semaphore i_xattr_sem; struct rw_semaphore i_xattr_sem;
#endif #endif

View file

@ -19,10 +19,6 @@ struct shmem_inode_info {
swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* first blocks */ swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* first blocks */
struct list_head swaplist; /* chain of maybes on swap */ struct list_head swaplist; /* chain of maybes on swap */
struct inode vfs_inode; 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 { struct shmem_sb_info {
@ -45,7 +41,6 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
#ifdef CONFIG_TMPFS_POSIX_ACL #ifdef CONFIG_TMPFS_POSIX_ACL
int shmem_permission(struct inode *, int); int shmem_permission(struct inode *, int);
int shmem_acl_init(struct inode *, struct inode *); 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_access_handler;
extern struct xattr_handler shmem_xattr_acl_default_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; return 0;
} }
static inline void shmem_acl_destroy_inode(struct inode *inode)
{
}
#endif /* CONFIG_TMPFS_POSIX_ACL */ #endif /* CONFIG_TMPFS_POSIX_ACL */
#endif #endif

View file

@ -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); p = (struct shmem_inode_info *)kmem_cache_alloc(shmem_inode_cachep, GFP_KERNEL);
if (!p) if (!p)
return NULL; 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; 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 */ /* only struct inode is valid if it's an inline symlink */
mpol_free_shared_policy(&SHMEM_I(inode)->policy); mpol_free_shared_policy(&SHMEM_I(inode)->policy);
} }
shmem_acl_destroy_inode(inode);
kmem_cache_free(shmem_inode_cachep, SHMEM_I(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; struct shmem_inode_info *p = (struct shmem_inode_info *) foo;
inode_init_once(&p->vfs_inode); 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) static int init_inodecache(void)

View file

@ -22,11 +22,11 @@ shmem_get_acl(struct inode *inode, int type)
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
switch(type) { switch(type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
acl = posix_acl_dup(SHMEM_I(inode)->i_acl); acl = posix_acl_dup(inode->i_acl);
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
acl = posix_acl_dup(SHMEM_I(inode)->i_default_acl); acl = posix_acl_dup(inode->i_default_acl);
break; break;
} }
spin_unlock(&inode->i_lock); 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); spin_lock(&inode->i_lock);
switch(type) { switch(type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
free = SHMEM_I(inode)->i_acl; free = inode->i_acl;
SHMEM_I(inode)->i_acl = posix_acl_dup(acl); inode->i_acl = posix_acl_dup(acl);
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
free = SHMEM_I(inode)->i_default_acl; free = inode->i_default_acl;
SHMEM_I(inode)->i_default_acl = posix_acl_dup(acl); inode->i_default_acl = posix_acl_dup(acl);
break; break;
} }
spin_unlock(&inode->i_lock); 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); 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() * shmem_check_acl - check_acl() callback for generic_permission()
*/ */