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:
Коммит
936940a9c7
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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");
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
10
fs/inode.c
10
fs/inode.c
|
@ -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
|
||||||
|
|
35
fs/ioctl.c
35
fs/ioctl.c
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
42
fs/jfs/acl.c
42
fs/jfs/acl.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
11
fs/namei.c
11
fs/namei.c
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
58
fs/open.c
58
fs/open.c
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
*/
|
*/
|
||||||
|
|
Загрузка…
Ссылка в новой задаче