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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
@ -2026,6 +2077,7 @@ void btrfs_read_locked_inode(struct inode *inode)
|
||||
struct btrfs_timespec *tspec;
|
||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||
struct btrfs_key location;
|
||||
int maybe_acls;
|
||||
u64 alloc_group_block;
|
||||
u32 rdev;
|
||||
int ret;
|
||||
@ -2072,6 +2124,16 @@ void btrfs_read_locked_inode(struct inode *inode)
|
||||
|
||||
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,
|
||||
alloc_group_block, 0);
|
||||
btrfs_free_path(path);
|
||||
|
Loading…
Reference in New Issue
Block a user