diff options
| -rw-r--r-- | fs/btrfs/inode.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index dc812ec551f6..90c23eb28829 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -2016,6 +2016,57 @@ void btrfs_orphan_cleanup(struct btrfs_root *root) | |||
| 2016 | } | 2016 | } |
| 2017 | 2017 | ||
| 2018 | /* | 2018 | /* |
| 2019 | * very simple check to peek ahead in the leaf looking for xattrs. If we | ||
| 2020 | * don't find any xattrs, we know there can't be any acls. | ||
| 2021 | * | ||
| 2022 | * slot is the slot the inode is in, objectid is the objectid of the inode | ||
| 2023 | */ | ||
| 2024 | static noinline int acls_after_inode_item(struct extent_buffer *leaf, | ||
| 2025 | int slot, u64 objectid) | ||
| 2026 | { | ||
| 2027 | u32 nritems = btrfs_header_nritems(leaf); | ||
| 2028 | struct btrfs_key found_key; | ||
| 2029 | int scanned = 0; | ||
| 2030 | |||
| 2031 | slot++; | ||
| 2032 | while (slot < nritems) { | ||
| 2033 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | ||
| 2034 | |||
| 2035 | /* we found a different objectid, there must not be acls */ | ||
| 2036 | if (found_key.objectid != objectid) | ||
| 2037 | return 0; | ||
| 2038 | |||
| 2039 | /* we found an xattr, assume we've got an acl */ | ||
| 2040 | if (found_key.type == BTRFS_XATTR_ITEM_KEY) | ||
| 2041 | return 1; | ||
| 2042 | |||
| 2043 | /* | ||
| 2044 | * we found a key greater than an xattr key, there can't | ||
| 2045 | * be any acls later on | ||
| 2046 | */ | ||
| 2047 | if (found_key.type > BTRFS_XATTR_ITEM_KEY) | ||
| 2048 | return 0; | ||
| 2049 | |||
| 2050 | slot++; | ||
| 2051 | scanned++; | ||
| 2052 | |||
| 2053 | /* | ||
| 2054 | * it goes inode, inode backrefs, xattrs, extents, | ||
| 2055 | * so if there are a ton of hard links to an inode there can | ||
| 2056 | * be a lot of backrefs. Don't waste time searching too hard, | ||
| 2057 | * this is just an optimization | ||
| 2058 | */ | ||
| 2059 | if (scanned >= 8) | ||
| 2060 | break; | ||
| 2061 | } | ||
| 2062 | /* we hit the end of the leaf before we found an xattr or | ||
| 2063 | * something larger than an xattr. We have to assume the inode | ||
| 2064 | * has acls | ||
| 2065 | */ | ||
| 2066 | return 1; | ||
| 2067 | } | ||
| 2068 | |||
| 2069 | /* | ||
| 2019 | * read an inode from the btree into the in-memory inode | 2070 | * read an inode from the btree into the in-memory inode |
| 2020 | */ | 2071 | */ |
| 2021 | void btrfs_read_locked_inode(struct inode *inode) | 2072 | void btrfs_read_locked_inode(struct inode *inode) |
| @@ -2026,6 +2077,7 @@ void btrfs_read_locked_inode(struct inode *inode) | |||
| 2026 | struct btrfs_timespec *tspec; | 2077 | struct btrfs_timespec *tspec; |
| 2027 | struct btrfs_root *root = BTRFS_I(inode)->root; | 2078 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 2028 | struct btrfs_key location; | 2079 | struct btrfs_key location; |
| 2080 | int maybe_acls; | ||
| 2029 | u64 alloc_group_block; | 2081 | u64 alloc_group_block; |
| 2030 | u32 rdev; | 2082 | u32 rdev; |
| 2031 | int ret; | 2083 | int ret; |
| @@ -2072,6 +2124,16 @@ void btrfs_read_locked_inode(struct inode *inode) | |||
| 2072 | 2124 | ||
| 2073 | alloc_group_block = btrfs_inode_block_group(leaf, inode_item); | 2125 | alloc_group_block = btrfs_inode_block_group(leaf, inode_item); |
| 2074 | 2126 | ||
| 2127 | /* | ||
| 2128 | * try to precache a NULL acl entry for files that don't have | ||
| 2129 | * any xattrs or acls | ||
| 2130 | */ | ||
| 2131 | maybe_acls = acls_after_inode_item(leaf, path->slots[0], inode->i_ino); | ||
| 2132 | if (!maybe_acls) { | ||
| 2133 | BTRFS_I(inode)->i_acl = NULL; | ||
| 2134 | BTRFS_I(inode)->i_default_acl = NULL; | ||
| 2135 | } | ||
| 2136 | |||
| 2075 | BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0, | 2137 | BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0, |
| 2076 | alloc_group_block, 0); | 2138 | alloc_group_block, 0); |
| 2077 | btrfs_free_path(path); | 2139 | btrfs_free_path(path); |
