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 Diff line number Diff line
@@ -109,27 +109,28 @@ prototypes:

locking rules:
	All may block.
			BKL	s_lock	s_umount
alloc_inode:		no	no	no
destroy_inode:		no
dirty_inode:		no				(must not sleep)
write_inode:		no
drop_inode:		no				!!!inode_lock!!!
delete_inode:		no
put_super:		yes	yes	no
write_super:		no	yes	read
sync_fs:		no	no	read
freeze_fs:		?
unfreeze_fs:		?
statfs:			no	no	no
remount_fs:		yes	yes	maybe		(see below)
clear_inode:		no
umount_begin:		yes	no	no
show_options:		no				(vfsmount->sem)
quota_read:		no	no	no		(see below)
quota_write:		no	no	no		(see below)

->remount_fs() will have the s_umount lock if it's already mounted.
	None have BKL
			s_umount
alloc_inode:
destroy_inode:
dirty_inode:				(must not sleep)
write_inode:
drop_inode:				!!!inode_lock!!!
delete_inode:
put_super:		write
write_super:		read
sync_fs:		read
freeze_fs:		read
unfreeze_fs:		read
statfs:			no
remount_fs:		maybe		(see below)
clear_inode:
umount_begin:		no
show_options:		no		(namespace_sem)
quota_read:		no		(see below)
quota_write:		no		(see below)

->remount_fs() will have the s_umount exclusive lock if it's already mounted.
When called from get_sb_single, it does NOT have the s_umount lock.
->quota_read() and ->quota_write() functions are both guaranteed to
be the only ones operating on the quota file by the quota code (via
+9 −35
Original line number Diff line number Diff line
@@ -29,51 +29,28 @@

#ifdef CONFIG_FS_POSIX_ACL

static void btrfs_update_cached_acl(struct inode *inode,
				    struct posix_acl **p_acl,
				    struct posix_acl *acl)
{
	spin_lock(&inode->i_lock);
	if (*p_acl && *p_acl != 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)
{
	int size;
	const char *name;
	char *value = NULL;
	struct posix_acl *acl = NULL, **p_acl;
	struct posix_acl *acl;

	acl = get_cached_acl(inode, type);
	if (acl != ACL_NOT_CACHED)
		return acl;

	switch (type) {
	case ACL_TYPE_ACCESS:
		name = POSIX_ACL_XATTR_ACCESS;
		p_acl = &BTRFS_I(inode)->i_acl;
		break;
	case ACL_TYPE_DEFAULT:
		name = POSIX_ACL_XATTR_DEFAULT;
		p_acl = &BTRFS_I(inode)->i_default_acl;
		break;
	default:
		return ERR_PTR(-EINVAL);
		BUG();
	}

	/* Handle the cached NULL acl case without locking */
	acl = ACCESS_ONCE(*p_acl);
	if (!acl)
		return acl;

	spin_lock(&inode->i_lock);
	acl = *p_acl;
	if (acl != 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);
	if (size > 0) {
		value = kzalloc(size, GFP_NOFS);
@@ -82,13 +59,13 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
		size = __btrfs_getxattr(inode, name, value, size);
		if (size > 0) {
			acl = posix_acl_from_xattr(value, size);
			btrfs_update_cached_acl(inode, p_acl, acl);
			set_cached_acl(inode, type, acl);
		}
		kfree(value);
	} else if (size == -ENOENT || size == -ENODATA || size == 0) {
		/* FIXME, who returns -ENOENT?  I think nobody */
		acl = NULL;
		btrfs_update_cached_acl(inode, p_acl, acl);
		set_cached_acl(inode, type, acl);
	} else {
		acl = ERR_PTR(-EIO);
	}
@@ -121,7 +98,6 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
	int ret, size = 0;
	const char *name;
	struct posix_acl **p_acl;
	char *value = NULL;
	mode_t mode;

@@ -141,13 +117,11 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
		ret = 0;
		inode->i_mode = mode;
		name = POSIX_ACL_XATTR_ACCESS;
		p_acl = &BTRFS_I(inode)->i_acl;
		break;
	case ACL_TYPE_DEFAULT:
		if (!S_ISDIR(inode->i_mode))
			return acl ? -EINVAL : 0;
		name = POSIX_ACL_XATTR_DEFAULT;
		p_acl = &BTRFS_I(inode)->i_default_acl;
		break;
	default:
		return -EINVAL;
@@ -172,7 +146,7 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
	kfree(value);

	if (!ret)
		btrfs_update_cached_acl(inode, p_acl, acl);
		set_cached_acl(inode, type, acl);

	return ret;
}
+0 −4
Original line number Diff line number Diff line
@@ -53,10 +53,6 @@ struct btrfs_inode {
	/* used to order data wrt metadata */
	struct btrfs_ordered_inode_tree ordered_tree;

	/* standard acl pointers */
	struct posix_acl *i_acl;
	struct posix_acl *i_default_acl;

	/* for keeping track of orphaned inodes */
	struct list_head i_orphan;

+0 −2
Original line number Diff line number Diff line
@@ -41,8 +41,6 @@ struct btrfs_ordered_sum;

#define BTRFS_MAGIC "_BHRfS_M"

#define BTRFS_ACL_NOT_CACHED    ((void *)-1)

#define BTRFS_MAX_LEVEL 8

#define BTRFS_COMPAT_EXTENT_TREE_V0
+2 −14
Original line number 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);
	if (!maybe_acls) {
		BTRFS_I(inode)->i_acl = NULL;
		BTRFS_I(inode)->i_default_acl = NULL;
		inode->i_acl = NULL;
		inode->i_default_acl = NULL;
	}

	BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
@@ -3141,9 +3141,6 @@ static noinline void init_btrfs_i(struct inode *inode)
{
	struct btrfs_inode *bi = BTRFS_I(inode);

	bi->i_acl = BTRFS_ACL_NOT_CACHED;
	bi->i_default_acl = BTRFS_ACL_NOT_CACHED;

	bi->generation = 0;
	bi->sequence = 0;
	bi->last_trans = 0;
@@ -4640,8 +4637,6 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
	ei->last_trans = 0;
	ei->logged_trans = 0;
	btrfs_ordered_inode_tree_init(&ei->ordered_tree);
	ei->i_acl = BTRFS_ACL_NOT_CACHED;
	ei->i_default_acl = BTRFS_ACL_NOT_CACHED;
	INIT_LIST_HEAD(&ei->i_orphan);
	INIT_LIST_HEAD(&ei->ordered_operations);
	return &ei->vfs_inode;
@@ -4655,13 +4650,6 @@ void btrfs_destroy_inode(struct inode *inode)
	WARN_ON(!list_empty(&inode->i_dentry));
	WARN_ON(inode->i_data.nrpages);

	if (BTRFS_I(inode)->i_acl &&
	    BTRFS_I(inode)->i_acl != BTRFS_ACL_NOT_CACHED)
		posix_acl_release(BTRFS_I(inode)->i_acl);
	if (BTRFS_I(inode)->i_default_acl &&
	    BTRFS_I(inode)->i_default_acl != BTRFS_ACL_NOT_CACHED)
		posix_acl_release(BTRFS_I(inode)->i_default_acl);

	/*
	 * Make sure we're properly removed from the ordered operation
	 * lists.
Loading