Skip to content

Commit d488cf1

Browse files
fdmananakdave
authored andcommitted
btrfs: split inode rextef processing from __add_inode_ref() into a helper
The __add_inode_ref() function is quite big and with too much nesting, so move the code that processes inode extrefs into a helper function, to make the function easier to read and reduce the level of indentation too. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent a5f2f4d commit d488cf1

File tree

1 file changed

+74
-57
lines changed

1 file changed

+74
-57
lines changed

fs/btrfs/tree-log.c

Lines changed: 74 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,73 @@ static int unlink_refs_not_in_log(struct btrfs_trans_handle *trans,
10941094
return 0;
10951095
}
10961096

1097+
static int unlink_extrefs_not_in_log(struct btrfs_trans_handle *trans,
1098+
struct btrfs_path *path,
1099+
struct btrfs_root *root,
1100+
struct btrfs_root *log_root,
1101+
struct btrfs_key *search_key,
1102+
struct btrfs_inode *inode,
1103+
u64 inode_objectid,
1104+
u64 parent_objectid)
1105+
{
1106+
struct extent_buffer *leaf = path->nodes[0];
1107+
const unsigned long base = btrfs_item_ptr_offset(leaf, path->slots[0]);
1108+
const u32 item_size = btrfs_item_size(leaf, path->slots[0]);
1109+
u32 cur_offset = 0;
1110+
1111+
while (cur_offset < item_size) {
1112+
struct btrfs_inode_extref *extref;
1113+
struct btrfs_inode *victim_parent;
1114+
struct fscrypt_str victim_name;
1115+
int ret;
1116+
1117+
extref = (struct btrfs_inode_extref *)(base + cur_offset);
1118+
victim_name.len = btrfs_inode_extref_name_len(leaf, extref);
1119+
1120+
if (btrfs_inode_extref_parent(leaf, extref) != parent_objectid)
1121+
goto next;
1122+
1123+
ret = read_alloc_one_name(leaf, &extref->name, victim_name.len,
1124+
&victim_name);
1125+
if (ret)
1126+
return ret;
1127+
1128+
search_key->objectid = inode_objectid;
1129+
search_key->type = BTRFS_INODE_EXTREF_KEY;
1130+
search_key->offset = btrfs_extref_hash(parent_objectid,
1131+
victim_name.name,
1132+
victim_name.len);
1133+
ret = backref_in_log(log_root, search_key, parent_objectid, &victim_name);
1134+
if (ret) {
1135+
kfree(victim_name.name);
1136+
if (ret < 0)
1137+
return ret;
1138+
next:
1139+
cur_offset += victim_name.len + sizeof(*extref);
1140+
continue;
1141+
}
1142+
1143+
victim_parent = btrfs_iget_logging(parent_objectid, root);
1144+
if (IS_ERR(victim_parent)) {
1145+
kfree(victim_name.name);
1146+
return PTR_ERR(victim_parent);
1147+
}
1148+
1149+
inc_nlink(&inode->vfs_inode);
1150+
btrfs_release_path(path);
1151+
1152+
ret = unlink_inode_for_log_replay(trans, victim_parent, inode,
1153+
&victim_name);
1154+
iput(&victim_parent->vfs_inode);
1155+
kfree(victim_name.name);
1156+
if (ret)
1157+
return ret;
1158+
return -EAGAIN;
1159+
}
1160+
1161+
return 0;
1162+
}
1163+
10971164
static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
10981165
struct btrfs_root *root,
10991166
struct btrfs_path *path,
@@ -1104,7 +1171,6 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
11041171
u64 ref_index, struct fscrypt_str *name)
11051172
{
11061173
int ret;
1107-
struct extent_buffer *leaf;
11081174
struct btrfs_dir_item *di;
11091175
struct btrfs_key search_key;
11101176
struct btrfs_inode_extref *extref;
@@ -1139,62 +1205,13 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
11391205
if (IS_ERR(extref)) {
11401206
return PTR_ERR(extref);
11411207
} else if (extref) {
1142-
u32 item_size;
1143-
u32 cur_offset = 0;
1144-
unsigned long base;
1145-
struct btrfs_inode *victim_parent;
1146-
1147-
leaf = path->nodes[0];
1148-
1149-
item_size = btrfs_item_size(leaf, path->slots[0]);
1150-
base = btrfs_item_ptr_offset(leaf, path->slots[0]);
1151-
1152-
while (cur_offset < item_size) {
1153-
struct fscrypt_str victim_name;
1154-
1155-
extref = (struct btrfs_inode_extref *)(base + cur_offset);
1156-
victim_name.len = btrfs_inode_extref_name_len(leaf, extref);
1157-
1158-
if (btrfs_inode_extref_parent(leaf, extref) != parent_objectid)
1159-
goto next;
1160-
1161-
ret = read_alloc_one_name(leaf, &extref->name,
1162-
victim_name.len, &victim_name);
1163-
if (ret)
1164-
return ret;
1165-
1166-
search_key.objectid = inode_objectid;
1167-
search_key.type = BTRFS_INODE_EXTREF_KEY;
1168-
search_key.offset = btrfs_extref_hash(parent_objectid,
1169-
victim_name.name,
1170-
victim_name.len);
1171-
ret = backref_in_log(log_root, &search_key,
1172-
parent_objectid, &victim_name);
1173-
if (ret < 0) {
1174-
kfree(victim_name.name);
1175-
return ret;
1176-
} else if (!ret) {
1177-
victim_parent = btrfs_iget_logging(parent_objectid, root);
1178-
if (IS_ERR(victim_parent)) {
1179-
ret = PTR_ERR(victim_parent);
1180-
} else {
1181-
inc_nlink(&inode->vfs_inode);
1182-
btrfs_release_path(path);
1183-
1184-
ret = unlink_inode_for_log_replay(trans,
1185-
victim_parent,
1186-
inode, &victim_name);
1187-
iput(&victim_parent->vfs_inode);
1188-
}
1189-
kfree(victim_name.name);
1190-
if (ret)
1191-
return ret;
1192-
goto again;
1193-
}
1194-
kfree(victim_name.name);
1195-
next:
1196-
cur_offset += victim_name.len + sizeof(*extref);
1197-
}
1208+
ret = unlink_extrefs_not_in_log(trans, path, root, log_root,
1209+
&search_key, inode,
1210+
inode_objectid, parent_objectid);
1211+
if (ret == -EAGAIN)
1212+
goto again;
1213+
else if (ret)
1214+
return ret;
11981215
}
11991216
btrfs_release_path(path);
12001217

0 commit comments

Comments
 (0)