Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-4.16-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:

- when NR_CPUS is large, a SRCU structure can significantly inflate
size of the main filesystem structure that would not be possible to
allocate by kmalloc, so the kvalloc fallback is used

- improved error handling

- fix endiannes when printing some filesystem attributes via sysfs,
this is could happen when a filesystem is moved between different
endianity hosts

- send fixes: the NO_HOLE mode should not send a write operation for a
file hole

- fix log replay for for special files followed by file hardlinks

- fix log replay failure after unlink and link combination

- fix max chunk size calculation for DUP allocation

* tag 'for-4.16-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
Btrfs: fix log replay failure after unlink and link combination
Btrfs: fix log replay failure after linking special file and fsync
Btrfs: send, fix issuing write op when processing hole in no data mode
btrfs: use proper endianness accessors for super_copy
btrfs: alloc_chunk: fix DUP stripe size handling
btrfs: Handle btrfs_set_extent_delalloc failure in relocate_file_extent_cluster
btrfs: handle failure of add_pending_csums
btrfs: use kvzalloc to allocate btrfs_fs_info

+191 -47
+5 -2
fs/btrfs/ctree.h
··· 2974 2974 kfree(fs_info->super_copy); 2975 2975 kfree(fs_info->super_for_commit); 2976 2976 security_free_mnt_opts(&fs_info->security_opts); 2977 - kfree(fs_info); 2977 + kvfree(fs_info); 2978 2978 } 2979 2979 2980 2980 /* tree mod log functions from ctree.c */ ··· 3095 3095 u64 inode_objectid, u64 ref_objectid, int ins_len, 3096 3096 int cow); 3097 3097 3098 - int btrfs_find_name_in_ext_backref(struct btrfs_path *path, 3098 + int btrfs_find_name_in_backref(struct extent_buffer *leaf, int slot, 3099 + const char *name, 3100 + int name_len, struct btrfs_inode_ref **ref_ret); 3101 + int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot, 3099 3102 u64 ref_objectid, const char *name, 3100 3103 int name_len, 3101 3104 struct btrfs_inode_extref **extref_ret);
+26 -18
fs/btrfs/inode-item.c
··· 22 22 #include "transaction.h" 23 23 #include "print-tree.h" 24 24 25 - static int find_name_in_backref(struct btrfs_path *path, const char *name, 26 - int name_len, struct btrfs_inode_ref **ref_ret) 25 + int btrfs_find_name_in_backref(struct extent_buffer *leaf, int slot, 26 + const char *name, 27 + int name_len, struct btrfs_inode_ref **ref_ret) 27 28 { 28 - struct extent_buffer *leaf; 29 29 struct btrfs_inode_ref *ref; 30 30 unsigned long ptr; 31 31 unsigned long name_ptr; ··· 33 33 u32 cur_offset = 0; 34 34 int len; 35 35 36 - leaf = path->nodes[0]; 37 - item_size = btrfs_item_size_nr(leaf, path->slots[0]); 38 - ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); 36 + item_size = btrfs_item_size_nr(leaf, slot); 37 + ptr = btrfs_item_ptr_offset(leaf, slot); 39 38 while (cur_offset < item_size) { 40 39 ref = (struct btrfs_inode_ref *)(ptr + cur_offset); 41 40 len = btrfs_inode_ref_name_len(leaf, ref); ··· 43 44 if (len != name_len) 44 45 continue; 45 46 if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) { 46 - *ref_ret = ref; 47 + if (ref_ret) 48 + *ref_ret = ref; 47 49 return 1; 48 50 } 49 51 } 50 52 return 0; 51 53 } 52 54 53 - int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid, 55 + int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot, 56 + u64 ref_objectid, 54 57 const char *name, int name_len, 55 58 struct btrfs_inode_extref **extref_ret) 56 59 { 57 - struct extent_buffer *leaf; 58 60 struct btrfs_inode_extref *extref; 59 61 unsigned long ptr; 60 62 unsigned long name_ptr; ··· 63 63 u32 cur_offset = 0; 64 64 int ref_name_len; 65 65 66 - leaf = path->nodes[0]; 67 - item_size = btrfs_item_size_nr(leaf, path->slots[0]); 68 - ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); 66 + item_size = btrfs_item_size_nr(leaf, slot); 67 + ptr = btrfs_item_ptr_offset(leaf, slot); 69 68 70 69 /* 71 70 * Search all extended backrefs in this item. We're only ··· 112 113 return ERR_PTR(ret); 113 114 if (ret > 0) 114 115 return NULL; 115 - if (!btrfs_find_name_in_ext_backref(path, ref_objectid, name, name_len, &extref)) 116 + if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0], 117 + ref_objectid, name, name_len, 118 + &extref)) 116 119 return NULL; 117 120 return extref; 118 121 } ··· 156 155 * This should always succeed so error here will make the FS 157 156 * readonly. 158 157 */ 159 - if (!btrfs_find_name_in_ext_backref(path, ref_objectid, 158 + if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0], 159 + ref_objectid, 160 160 name, name_len, &extref)) { 161 161 btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL); 162 162 ret = -EROFS; ··· 227 225 } else if (ret < 0) { 228 226 goto out; 229 227 } 230 - if (!find_name_in_backref(path, name, name_len, &ref)) { 228 + if (!btrfs_find_name_in_backref(path->nodes[0], path->slots[0], 229 + name, name_len, &ref)) { 231 230 ret = -ENOENT; 232 231 search_ext_refs = 1; 233 232 goto out; ··· 296 293 ret = btrfs_insert_empty_item(trans, root, path, &key, 297 294 ins_len); 298 295 if (ret == -EEXIST) { 299 - if (btrfs_find_name_in_ext_backref(path, ref_objectid, 296 + if (btrfs_find_name_in_ext_backref(path->nodes[0], 297 + path->slots[0], 298 + ref_objectid, 300 299 name, name_len, NULL)) 301 300 goto out; 302 301 ··· 356 351 if (ret == -EEXIST) { 357 352 u32 old_size; 358 353 359 - if (find_name_in_backref(path, name, name_len, &ref)) 354 + if (btrfs_find_name_in_backref(path->nodes[0], path->slots[0], 355 + name, name_len, &ref)) 360 356 goto out; 361 357 362 358 old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]); ··· 371 365 ret = 0; 372 366 } else if (ret < 0) { 373 367 if (ret == -EOVERFLOW) { 374 - if (find_name_in_backref(path, name, name_len, &ref)) 368 + if (btrfs_find_name_in_backref(path->nodes[0], 369 + path->slots[0], 370 + name, name_len, &ref)) 375 371 ret = -EEXIST; 376 372 else 377 373 ret = -EMLINK;
+9 -2
fs/btrfs/inode.c
··· 2043 2043 struct inode *inode, struct list_head *list) 2044 2044 { 2045 2045 struct btrfs_ordered_sum *sum; 2046 + int ret; 2046 2047 2047 2048 list_for_each_entry(sum, list, list) { 2048 2049 trans->adding_csums = true; 2049 - btrfs_csum_file_blocks(trans, 2050 + ret = btrfs_csum_file_blocks(trans, 2050 2051 BTRFS_I(inode)->root->fs_info->csum_root, sum); 2051 2052 trans->adding_csums = false; 2053 + if (ret) 2054 + return ret; 2052 2055 } 2053 2056 return 0; 2054 2057 } ··· 3065 3062 goto out; 3066 3063 } 3067 3064 3068 - add_pending_csums(trans, inode, &ordered_extent->list); 3065 + ret = add_pending_csums(trans, inode, &ordered_extent->list); 3066 + if (ret) { 3067 + btrfs_abort_transaction(trans, ret); 3068 + goto out; 3069 + } 3069 3070 3070 3071 btrfs_ordered_update_i_size(inode, 0, ordered_extent); 3071 3072 ret = btrfs_update_inode_fallback(trans, root, inode);
+16 -2
fs/btrfs/relocation.c
··· 3268 3268 nr++; 3269 3269 } 3270 3270 3271 - btrfs_set_extent_delalloc(inode, page_start, page_end, 0, NULL, 3272 - 0); 3271 + ret = btrfs_set_extent_delalloc(inode, page_start, page_end, 0, 3272 + NULL, 0); 3273 + if (ret) { 3274 + unlock_page(page); 3275 + put_page(page); 3276 + btrfs_delalloc_release_metadata(BTRFS_I(inode), 3277 + PAGE_SIZE); 3278 + btrfs_delalloc_release_extents(BTRFS_I(inode), 3279 + PAGE_SIZE); 3280 + 3281 + clear_extent_bits(&BTRFS_I(inode)->io_tree, 3282 + page_start, page_end, 3283 + EXTENT_LOCKED | EXTENT_BOUNDARY); 3284 + goto out; 3285 + 3286 + } 3273 3287 set_page_dirty(page); 3274 3288 3275 3289 unlock_extent(&BTRFS_I(inode)->io_tree,
+3
fs/btrfs/send.c
··· 5005 5005 u64 len; 5006 5006 int ret = 0; 5007 5007 5008 + if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA) 5009 + return send_update_extent(sctx, offset, end - offset); 5010 + 5008 5011 p = fs_path_alloc(); 5009 5012 if (!p) 5010 5013 return -ENOMEM;
+1 -1
fs/btrfs/super.c
··· 1545 1545 * it for searching for existing supers, so this lets us do that and 1546 1546 * then open_ctree will properly initialize everything later. 1547 1547 */ 1548 - fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL); 1548 + fs_info = kvzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL); 1549 1549 if (!fs_info) { 1550 1550 error = -ENOMEM; 1551 1551 goto error_sec_opts;
+3 -5
fs/btrfs/sysfs.c
··· 423 423 { 424 424 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 425 425 426 - return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->super_copy->nodesize); 426 + return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->nodesize); 427 427 } 428 428 429 429 BTRFS_ATTR(, nodesize, btrfs_nodesize_show); ··· 433 433 { 434 434 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 435 435 436 - return snprintf(buf, PAGE_SIZE, "%u\n", 437 - fs_info->super_copy->sectorsize); 436 + return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->sectorsize); 438 437 } 439 438 440 439 BTRFS_ATTR(, sectorsize, btrfs_sectorsize_show); ··· 443 444 { 444 445 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 445 446 446 - return snprintf(buf, PAGE_SIZE, "%u\n", 447 - fs_info->super_copy->sectorsize); 447 + return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->sectorsize); 448 448 } 449 449 450 450 BTRFS_ATTR(, clone_alignment, btrfs_clone_alignment_show);
+12 -8
fs/btrfs/transaction.c
··· 1722 1722 1723 1723 super = fs_info->super_copy; 1724 1724 1725 + /* update latest btrfs_super_block::chunk_root refs */ 1725 1726 root_item = &fs_info->chunk_root->root_item; 1726 - super->chunk_root = root_item->bytenr; 1727 - super->chunk_root_generation = root_item->generation; 1728 - super->chunk_root_level = root_item->level; 1727 + btrfs_set_super_chunk_root(super, root_item->bytenr); 1728 + btrfs_set_super_chunk_root_generation(super, root_item->generation); 1729 + btrfs_set_super_chunk_root_level(super, root_item->level); 1729 1730 1731 + /* update latest btrfs_super_block::root refs */ 1730 1732 root_item = &fs_info->tree_root->root_item; 1731 - super->root = root_item->bytenr; 1732 - super->generation = root_item->generation; 1733 - super->root_level = root_item->level; 1733 + btrfs_set_super_root(super, root_item->bytenr); 1734 + btrfs_set_super_generation(super, root_item->generation); 1735 + btrfs_set_super_root_level(super, root_item->level); 1736 + 1734 1737 if (btrfs_test_opt(fs_info, SPACE_CACHE)) 1735 - super->cache_generation = root_item->generation; 1738 + btrfs_set_super_cache_generation(super, root_item->generation); 1736 1739 if (test_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags)) 1737 - super->uuid_tree_generation = root_item->generation; 1740 + btrfs_set_super_uuid_tree_generation(super, 1741 + root_item->generation); 1738 1742 } 1739 1743 1740 1744 int btrfs_transaction_in_commit(struct btrfs_fs_info *info)
+110 -4
fs/btrfs/tree-log.c
··· 967 967 ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]); 968 968 969 969 if (key->type == BTRFS_INODE_EXTREF_KEY) { 970 - if (btrfs_find_name_in_ext_backref(path, ref_objectid, 970 + if (btrfs_find_name_in_ext_backref(path->nodes[0], 971 + path->slots[0], 972 + ref_objectid, 971 973 name, namelen, NULL)) 972 974 match = 1; 973 975 ··· 1193 1191 read_extent_buffer(eb, *name, (unsigned long)&extref->name, 1194 1192 *namelen); 1195 1193 1196 - *index = btrfs_inode_extref_index(eb, extref); 1194 + if (index) 1195 + *index = btrfs_inode_extref_index(eb, extref); 1197 1196 if (parent_objectid) 1198 1197 *parent_objectid = btrfs_inode_extref_parent(eb, extref); 1199 1198 ··· 1215 1212 1216 1213 read_extent_buffer(eb, *name, (unsigned long)(ref + 1), *namelen); 1217 1214 1218 - *index = btrfs_inode_ref_index(eb, ref); 1215 + if (index) 1216 + *index = btrfs_inode_ref_index(eb, ref); 1219 1217 1220 1218 return 0; 1219 + } 1220 + 1221 + /* 1222 + * Take an inode reference item from the log tree and iterate all names from the 1223 + * inode reference item in the subvolume tree with the same key (if it exists). 1224 + * For any name that is not in the inode reference item from the log tree, do a 1225 + * proper unlink of that name (that is, remove its entry from the inode 1226 + * reference item and both dir index keys). 1227 + */ 1228 + static int unlink_old_inode_refs(struct btrfs_trans_handle *trans, 1229 + struct btrfs_root *root, 1230 + struct btrfs_path *path, 1231 + struct btrfs_inode *inode, 1232 + struct extent_buffer *log_eb, 1233 + int log_slot, 1234 + struct btrfs_key *key) 1235 + { 1236 + int ret; 1237 + unsigned long ref_ptr; 1238 + unsigned long ref_end; 1239 + struct extent_buffer *eb; 1240 + 1241 + again: 1242 + btrfs_release_path(path); 1243 + ret = btrfs_search_slot(NULL, root, key, path, 0, 0); 1244 + if (ret > 0) { 1245 + ret = 0; 1246 + goto out; 1247 + } 1248 + if (ret < 0) 1249 + goto out; 1250 + 1251 + eb = path->nodes[0]; 1252 + ref_ptr = btrfs_item_ptr_offset(eb, path->slots[0]); 1253 + ref_end = ref_ptr + btrfs_item_size_nr(eb, path->slots[0]); 1254 + while (ref_ptr < ref_end) { 1255 + char *name = NULL; 1256 + int namelen; 1257 + u64 parent_id; 1258 + 1259 + if (key->type == BTRFS_INODE_EXTREF_KEY) { 1260 + ret = extref_get_fields(eb, ref_ptr, &namelen, &name, 1261 + NULL, &parent_id); 1262 + } else { 1263 + parent_id = key->offset; 1264 + ret = ref_get_fields(eb, ref_ptr, &namelen, &name, 1265 + NULL); 1266 + } 1267 + if (ret) 1268 + goto out; 1269 + 1270 + if (key->type == BTRFS_INODE_EXTREF_KEY) 1271 + ret = btrfs_find_name_in_ext_backref(log_eb, log_slot, 1272 + parent_id, name, 1273 + namelen, NULL); 1274 + else 1275 + ret = btrfs_find_name_in_backref(log_eb, log_slot, name, 1276 + namelen, NULL); 1277 + 1278 + if (!ret) { 1279 + struct inode *dir; 1280 + 1281 + btrfs_release_path(path); 1282 + dir = read_one_inode(root, parent_id); 1283 + if (!dir) { 1284 + ret = -ENOENT; 1285 + kfree(name); 1286 + goto out; 1287 + } 1288 + ret = btrfs_unlink_inode(trans, root, BTRFS_I(dir), 1289 + inode, name, namelen); 1290 + kfree(name); 1291 + iput(dir); 1292 + if (ret) 1293 + goto out; 1294 + goto again; 1295 + } 1296 + 1297 + kfree(name); 1298 + ref_ptr += namelen; 1299 + if (key->type == BTRFS_INODE_EXTREF_KEY) 1300 + ref_ptr += sizeof(struct btrfs_inode_extref); 1301 + else 1302 + ref_ptr += sizeof(struct btrfs_inode_ref); 1303 + } 1304 + ret = 0; 1305 + out: 1306 + btrfs_release_path(path); 1307 + return ret; 1221 1308 } 1222 1309 1223 1310 /* ··· 1437 1344 dir = NULL; 1438 1345 } 1439 1346 } 1347 + 1348 + /* 1349 + * Before we overwrite the inode reference item in the subvolume tree 1350 + * with the item from the log tree, we must unlink all names from the 1351 + * parent directory that are in the subvolume's tree inode reference 1352 + * item, otherwise we end up with an inconsistent subvolume tree where 1353 + * dir index entries exist for a name but there is no inode reference 1354 + * item with the same name. 1355 + */ 1356 + ret = unlink_old_inode_refs(trans, root, path, BTRFS_I(inode), eb, slot, 1357 + key); 1358 + if (ret) 1359 + goto out; 1440 1360 1441 1361 /* finally write the back reference in the inode */ 1442 1362 ret = overwrite_item(trans, root, path, eb, slot, key); ··· 5959 5853 * this will force the logging code to walk the dentry chain 5960 5854 * up for the file 5961 5855 */ 5962 - if (S_ISREG(inode->vfs_inode.i_mode)) 5856 + if (!S_ISDIR(inode->vfs_inode.i_mode)) 5963 5857 inode->last_unlink_trans = trans->transid; 5964 5858 5965 5859 /*
+6 -5
fs/btrfs/volumes.c
··· 4829 4829 ndevs = min(ndevs, devs_max); 4830 4830 4831 4831 /* 4832 - * the primary goal is to maximize the number of stripes, so use as many 4833 - * devices as possible, even if the stripes are not maximum sized. 4832 + * The primary goal is to maximize the number of stripes, so use as 4833 + * many devices as possible, even if the stripes are not maximum sized. 4834 + * 4835 + * The DUP profile stores more than one stripe per device, the 4836 + * max_avail is the total size so we have to adjust. 4834 4837 */ 4835 - stripe_size = devices_info[ndevs-1].max_avail; 4838 + stripe_size = div_u64(devices_info[ndevs - 1].max_avail, dev_stripes); 4836 4839 num_stripes = ndevs * dev_stripes; 4837 4840 4838 4841 /* ··· 4869 4866 if (stripe_size > devices_info[ndevs-1].max_avail) 4870 4867 stripe_size = devices_info[ndevs-1].max_avail; 4871 4868 } 4872 - 4873 - stripe_size = div_u64(stripe_size, dev_stripes); 4874 4869 4875 4870 /* align to BTRFS_STRIPE_LEN */ 4876 4871 stripe_size = round_down(stripe_size, BTRFS_STRIPE_LEN);