Btrfs: look for acls during btrfs_read_locked_inode
This changes btrfs_read_locked_inode() to peek ahead in the btree for acl items. If it is certain a given inode has no acls, it will set the in memory acl fields to null to avoid acl lookups completely. Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
7b1a14bbb0
commit
46a53cca82
@ -2015,6 +2015,57 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
|
|||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* very simple check to peek ahead in the leaf looking for xattrs. If we
|
||||||
|
* don't find any xattrs, we know there can't be any acls.
|
||||||
|
*
|
||||||
|
* slot is the slot the inode is in, objectid is the objectid of the inode
|
||||||
|
*/
|
||||||
|
static noinline int acls_after_inode_item(struct extent_buffer *leaf,
|
||||||
|
int slot, u64 objectid)
|
||||||
|
{
|
||||||
|
u32 nritems = btrfs_header_nritems(leaf);
|
||||||
|
struct btrfs_key found_key;
|
||||||
|
int scanned = 0;
|
||||||
|
|
||||||
|
slot++;
|
||||||
|
while (slot < nritems) {
|
||||||
|
btrfs_item_key_to_cpu(leaf, &found_key, slot);
|
||||||
|
|
||||||
|
/* we found a different objectid, there must not be acls */
|
||||||
|
if (found_key.objectid != objectid)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* we found an xattr, assume we've got an acl */
|
||||||
|
if (found_key.type == BTRFS_XATTR_ITEM_KEY)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we found a key greater than an xattr key, there can't
|
||||||
|
* be any acls later on
|
||||||
|
*/
|
||||||
|
if (found_key.type > BTRFS_XATTR_ITEM_KEY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
slot++;
|
||||||
|
scanned++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* it goes inode, inode backrefs, xattrs, extents,
|
||||||
|
* so if there are a ton of hard links to an inode there can
|
||||||
|
* be a lot of backrefs. Don't waste time searching too hard,
|
||||||
|
* this is just an optimization
|
||||||
|
*/
|
||||||
|
if (scanned >= 8)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* we hit the end of the leaf before we found an xattr or
|
||||||
|
* something larger than an xattr. We have to assume the inode
|
||||||
|
* has acls
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read an inode from the btree into the in-memory inode
|
* read an inode from the btree into the in-memory inode
|
||||||
*/
|
*/
|
||||||
@ -2026,6 +2077,7 @@ void btrfs_read_locked_inode(struct inode *inode)
|
|||||||
struct btrfs_timespec *tspec;
|
struct btrfs_timespec *tspec;
|
||||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||||
struct btrfs_key location;
|
struct btrfs_key location;
|
||||||
|
int maybe_acls;
|
||||||
u64 alloc_group_block;
|
u64 alloc_group_block;
|
||||||
u32 rdev;
|
u32 rdev;
|
||||||
int ret;
|
int ret;
|
||||||
@ -2072,6 +2124,16 @@ void btrfs_read_locked_inode(struct inode *inode)
|
|||||||
|
|
||||||
alloc_group_block = btrfs_inode_block_group(leaf, inode_item);
|
alloc_group_block = btrfs_inode_block_group(leaf, inode_item);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* try to precache a NULL acl entry for files that don't have
|
||||||
|
* any xattrs or acls
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
|
BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
|
||||||
alloc_group_block, 0);
|
alloc_group_block, 0);
|
||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
|
Loading…
Reference in New Issue
Block a user