Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 936940a9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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
  ...
parents 09ce42d3 1cbd20d8
Loading
Loading
Loading
Loading
+22 −21
Original line number Original line Diff line number Diff line
@@ -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
+9 −35
Original line number Original line Diff line number Diff line
@@ -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;
}
}
+0 −4
Original line number Original line Diff line number Diff line
@@ -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;


+0 −2
Original line number Original line Diff line number Diff line
@@ -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
+2 −14
Original line number Original line Diff line number Diff line
@@ -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.
Loading