Loading fs/btrfs/raid56.c +18 −8 Original line number Diff line number Diff line Loading @@ -1136,20 +1136,27 @@ static void validate_rbio_for_rmw(struct btrfs_raid_bio *rbio) static void index_rbio_pages(struct btrfs_raid_bio *rbio) { struct bio *bio; struct bio_vec *bvec; u64 start; unsigned long stripe_offset; unsigned long page_index; int i; spin_lock_irq(&rbio->bio_list_lock); bio_list_for_each(bio, &rbio->bio_list) { struct bio_vec bvec; struct bvec_iter iter; int i = 0; start = (u64)bio->bi_iter.bi_sector << 9; stripe_offset = start - rbio->bbio->raid_map[0]; page_index = stripe_offset >> PAGE_SHIFT; bio_for_each_segment_all(bvec, bio, i) rbio->bio_pages[page_index + i] = bvec->bv_page; if (bio_flagged(bio, BIO_CLONED)) bio->bi_iter = btrfs_io_bio(bio)->iter; bio_for_each_segment(bvec, bio, iter) { rbio->bio_pages[page_index + i] = bvec.bv_page; i++; } } spin_unlock_irq(&rbio->bio_list_lock); } Loading Loading @@ -1423,11 +1430,14 @@ static int fail_bio_stripe(struct btrfs_raid_bio *rbio, */ static void set_bio_pages_uptodate(struct bio *bio) { struct bio_vec *bvec; int i; struct bio_vec bvec; struct bvec_iter iter; if (bio_flagged(bio, BIO_CLONED)) bio->bi_iter = btrfs_io_bio(bio)->iter; bio_for_each_segment_all(bvec, bio, i) SetPageUptodate(bvec->bv_page); bio_for_each_segment(bvec, bio, iter) SetPageUptodate(bvec.bv_page); } /* Loading fs/btrfs/send.c +55 −33 Original line number Diff line number Diff line Loading @@ -1856,7 +1856,7 @@ static int is_first_ref(struct btrfs_root *root, */ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, const char *name, int name_len, u64 *who_ino, u64 *who_gen) u64 *who_ino, u64 *who_gen, u64 *who_mode) { int ret = 0; u64 gen; Loading Loading @@ -1905,7 +1905,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, if (other_inode > sctx->send_progress || is_waiting_for_move(sctx, other_inode)) { ret = get_inode_info(sctx->parent_root, other_inode, NULL, who_gen, NULL, NULL, NULL, NULL); who_gen, who_mode, NULL, NULL, NULL); if (ret < 0) goto out; Loading Loading @@ -3683,6 +3683,36 @@ static int wait_for_parent_move(struct send_ctx *sctx, return ret; } static int update_ref_path(struct send_ctx *sctx, struct recorded_ref *ref) { int ret; struct fs_path *new_path; /* * Our reference's name member points to its full_path member string, so * we use here a new path. */ new_path = fs_path_alloc(); if (!new_path) return -ENOMEM; ret = get_cur_path(sctx, ref->dir, ref->dir_gen, new_path); if (ret < 0) { fs_path_free(new_path); return ret; } ret = fs_path_add(new_path, ref->name, ref->name_len); if (ret < 0) { fs_path_free(new_path); return ret; } fs_path_free(ref->full_path); set_ref_path(ref, new_path); return 0; } /* * This does all the move/link/unlink/rmdir magic. */ Loading @@ -3696,10 +3726,12 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) struct fs_path *valid_path = NULL; u64 ow_inode = 0; u64 ow_gen; u64 ow_mode; int did_overwrite = 0; int is_orphan = 0; u64 last_dir_ino_rm = 0; bool can_rename = true; bool orphanized_dir = false; bool orphanized_ancestor = false; btrfs_debug(fs_info, "process_recorded_refs %llu", sctx->cur_ino); Loading Loading @@ -3798,7 +3830,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) */ ret = will_overwrite_ref(sctx, cur->dir, cur->dir_gen, cur->name, cur->name_len, &ow_inode, &ow_gen); &ow_inode, &ow_gen, &ow_mode); if (ret < 0) goto out; if (ret) { Loading @@ -3815,6 +3847,8 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) cur->full_path); if (ret < 0) goto out; if (S_ISDIR(ow_mode)) orphanized_dir = true; /* * If ow_inode has its rename operation delayed Loading Loading @@ -3920,6 +3954,18 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) if (ret < 0) goto out; } else { /* * We might have previously orphanized an inode * which is an ancestor of our current inode, * so our reference's full path, which was * computed before any such orphanizations, must * be updated. */ if (orphanized_dir) { ret = update_ref_path(sctx, cur); if (ret < 0) goto out; } ret = send_link(sctx, cur->full_path, valid_path); if (ret < 0) Loading Loading @@ -3990,35 +4036,10 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) * ancestor inode. */ if (orphanized_ancestor) { struct fs_path *new_path; /* * Our reference's name member points to * its full_path member string, so we * use here a new path. */ new_path = fs_path_alloc(); if (!new_path) { ret = -ENOMEM; goto out; } ret = get_cur_path(sctx, cur->dir, cur->dir_gen, new_path); if (ret < 0) { fs_path_free(new_path); goto out; } ret = fs_path_add(new_path, cur->name, cur->name_len); if (ret < 0) { fs_path_free(new_path); ret = update_ref_path(sctx, cur); if (ret < 0) goto out; } fs_path_free(cur->full_path); set_ref_path(cur, new_path); } ret = send_unlink(sctx, cur->full_path); if (ret < 0) goto out; Loading Loading @@ -5249,15 +5270,12 @@ static int is_extent_unchanged(struct send_ctx *sctx, goto out; } right_disknr = btrfs_file_extent_disk_bytenr(eb, ei); if (right_type == BTRFS_FILE_EXTENT_INLINE) { right_len = btrfs_file_extent_inline_len(eb, slot, ei); right_len = PAGE_ALIGN(right_len); } else { right_len = btrfs_file_extent_num_bytes(eb, ei); } right_offset = btrfs_file_extent_offset(eb, ei); right_gen = btrfs_file_extent_generation(eb, ei); /* * Are we at extent 8? If yes, we know the extent is changed. Loading @@ -5282,6 +5300,10 @@ static int is_extent_unchanged(struct send_ctx *sctx, goto out; } right_disknr = btrfs_file_extent_disk_bytenr(eb, ei); right_offset = btrfs_file_extent_offset(eb, ei); right_gen = btrfs_file_extent_generation(eb, ei); left_offset_fixed = left_offset; if (key.offset < ekey->offset) { /* Fix the right offset for 2a and 7. */ Loading Loading
fs/btrfs/raid56.c +18 −8 Original line number Diff line number Diff line Loading @@ -1136,20 +1136,27 @@ static void validate_rbio_for_rmw(struct btrfs_raid_bio *rbio) static void index_rbio_pages(struct btrfs_raid_bio *rbio) { struct bio *bio; struct bio_vec *bvec; u64 start; unsigned long stripe_offset; unsigned long page_index; int i; spin_lock_irq(&rbio->bio_list_lock); bio_list_for_each(bio, &rbio->bio_list) { struct bio_vec bvec; struct bvec_iter iter; int i = 0; start = (u64)bio->bi_iter.bi_sector << 9; stripe_offset = start - rbio->bbio->raid_map[0]; page_index = stripe_offset >> PAGE_SHIFT; bio_for_each_segment_all(bvec, bio, i) rbio->bio_pages[page_index + i] = bvec->bv_page; if (bio_flagged(bio, BIO_CLONED)) bio->bi_iter = btrfs_io_bio(bio)->iter; bio_for_each_segment(bvec, bio, iter) { rbio->bio_pages[page_index + i] = bvec.bv_page; i++; } } spin_unlock_irq(&rbio->bio_list_lock); } Loading Loading @@ -1423,11 +1430,14 @@ static int fail_bio_stripe(struct btrfs_raid_bio *rbio, */ static void set_bio_pages_uptodate(struct bio *bio) { struct bio_vec *bvec; int i; struct bio_vec bvec; struct bvec_iter iter; if (bio_flagged(bio, BIO_CLONED)) bio->bi_iter = btrfs_io_bio(bio)->iter; bio_for_each_segment_all(bvec, bio, i) SetPageUptodate(bvec->bv_page); bio_for_each_segment(bvec, bio, iter) SetPageUptodate(bvec.bv_page); } /* Loading
fs/btrfs/send.c +55 −33 Original line number Diff line number Diff line Loading @@ -1856,7 +1856,7 @@ static int is_first_ref(struct btrfs_root *root, */ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, const char *name, int name_len, u64 *who_ino, u64 *who_gen) u64 *who_ino, u64 *who_gen, u64 *who_mode) { int ret = 0; u64 gen; Loading Loading @@ -1905,7 +1905,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, if (other_inode > sctx->send_progress || is_waiting_for_move(sctx, other_inode)) { ret = get_inode_info(sctx->parent_root, other_inode, NULL, who_gen, NULL, NULL, NULL, NULL); who_gen, who_mode, NULL, NULL, NULL); if (ret < 0) goto out; Loading Loading @@ -3683,6 +3683,36 @@ static int wait_for_parent_move(struct send_ctx *sctx, return ret; } static int update_ref_path(struct send_ctx *sctx, struct recorded_ref *ref) { int ret; struct fs_path *new_path; /* * Our reference's name member points to its full_path member string, so * we use here a new path. */ new_path = fs_path_alloc(); if (!new_path) return -ENOMEM; ret = get_cur_path(sctx, ref->dir, ref->dir_gen, new_path); if (ret < 0) { fs_path_free(new_path); return ret; } ret = fs_path_add(new_path, ref->name, ref->name_len); if (ret < 0) { fs_path_free(new_path); return ret; } fs_path_free(ref->full_path); set_ref_path(ref, new_path); return 0; } /* * This does all the move/link/unlink/rmdir magic. */ Loading @@ -3696,10 +3726,12 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) struct fs_path *valid_path = NULL; u64 ow_inode = 0; u64 ow_gen; u64 ow_mode; int did_overwrite = 0; int is_orphan = 0; u64 last_dir_ino_rm = 0; bool can_rename = true; bool orphanized_dir = false; bool orphanized_ancestor = false; btrfs_debug(fs_info, "process_recorded_refs %llu", sctx->cur_ino); Loading Loading @@ -3798,7 +3830,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) */ ret = will_overwrite_ref(sctx, cur->dir, cur->dir_gen, cur->name, cur->name_len, &ow_inode, &ow_gen); &ow_inode, &ow_gen, &ow_mode); if (ret < 0) goto out; if (ret) { Loading @@ -3815,6 +3847,8 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) cur->full_path); if (ret < 0) goto out; if (S_ISDIR(ow_mode)) orphanized_dir = true; /* * If ow_inode has its rename operation delayed Loading Loading @@ -3920,6 +3954,18 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) if (ret < 0) goto out; } else { /* * We might have previously orphanized an inode * which is an ancestor of our current inode, * so our reference's full path, which was * computed before any such orphanizations, must * be updated. */ if (orphanized_dir) { ret = update_ref_path(sctx, cur); if (ret < 0) goto out; } ret = send_link(sctx, cur->full_path, valid_path); if (ret < 0) Loading Loading @@ -3990,35 +4036,10 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) * ancestor inode. */ if (orphanized_ancestor) { struct fs_path *new_path; /* * Our reference's name member points to * its full_path member string, so we * use here a new path. */ new_path = fs_path_alloc(); if (!new_path) { ret = -ENOMEM; goto out; } ret = get_cur_path(sctx, cur->dir, cur->dir_gen, new_path); if (ret < 0) { fs_path_free(new_path); goto out; } ret = fs_path_add(new_path, cur->name, cur->name_len); if (ret < 0) { fs_path_free(new_path); ret = update_ref_path(sctx, cur); if (ret < 0) goto out; } fs_path_free(cur->full_path); set_ref_path(cur, new_path); } ret = send_unlink(sctx, cur->full_path); if (ret < 0) goto out; Loading Loading @@ -5249,15 +5270,12 @@ static int is_extent_unchanged(struct send_ctx *sctx, goto out; } right_disknr = btrfs_file_extent_disk_bytenr(eb, ei); if (right_type == BTRFS_FILE_EXTENT_INLINE) { right_len = btrfs_file_extent_inline_len(eb, slot, ei); right_len = PAGE_ALIGN(right_len); } else { right_len = btrfs_file_extent_num_bytes(eb, ei); } right_offset = btrfs_file_extent_offset(eb, ei); right_gen = btrfs_file_extent_generation(eb, ei); /* * Are we at extent 8? If yes, we know the extent is changed. Loading @@ -5282,6 +5300,10 @@ static int is_extent_unchanged(struct send_ctx *sctx, goto out; } right_disknr = btrfs_file_extent_disk_bytenr(eb, ei); right_offset = btrfs_file_extent_offset(eb, ei); right_gen = btrfs_file_extent_generation(eb, ei); left_offset_fixed = left_offset; if (key.offset < ekey->offset) { /* Fix the right offset for 2a and 7. */ Loading