bcachefs: Convert io paths for snapshots
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 13 Mar 2021 01:30:39 +0000 (20:30 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:12 +0000 (17:09 -0400)
This plumbs around the subvolume ID as was done previously for other
filesystem code, but now for the IO paths - the control flow in the IO
paths is trickier so the changes in this patch are more involved.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/fs-io.c
fs/bcachefs/io.c
fs/bcachefs/io.h
fs/bcachefs/io_types.h
fs/bcachefs/reflink.c

index 7a07721..736dd71 100644 (file)
@@ -769,23 +769,35 @@ static void readpage_bio_extend(struct readpages_iter *iter,
        }
 }
 
-static void bchfs_read(struct btree_trans *trans, struct btree_iter *iter,
-                      struct bch_read_bio *rbio, u64 inum,
+static void bchfs_read(struct btree_trans *trans,
+                      struct bch_read_bio *rbio,
+                      subvol_inum inum,
                       struct readpages_iter *readpages_iter)
 {
        struct bch_fs *c = trans->c;
+       struct btree_iter iter;
        struct bkey_buf sk;
        int flags = BCH_READ_RETRY_IF_STALE|
                BCH_READ_MAY_PROMOTE;
+       u32 snapshot;
        int ret = 0;
 
        rbio->c = c;
        rbio->start_time = local_clock();
+       rbio->subvol = inum.subvol;
 
        bch2_bkey_buf_init(&sk);
 retry:
        bch2_trans_begin(trans);
+       iter = (struct btree_iter) { NULL };
 
+       ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
+       if (ret)
+               goto err;
+
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
+                            SPOS(inum.inum, rbio->bio.bi_iter.bi_sector, snapshot),
+                            BTREE_ITER_SLOTS|BTREE_ITER_FILTER_SNAPSHOTS);
        while (1) {
                struct bkey_s_c k;
                unsigned bytes, sectors, offset_into_extent;
@@ -800,15 +812,15 @@ retry:
                        break;
                }
 
-               bch2_btree_iter_set_pos(iter,
-                               POS(inum, rbio->bio.bi_iter.bi_sector));
+               bch2_btree_iter_set_pos(&iter,
+                               POS(inum.inum, rbio->bio.bi_iter.bi_sector));
 
-               k = bch2_btree_iter_peek_slot(iter);
+               k = bch2_btree_iter_peek_slot(&iter);
                ret = bkey_err(k);
                if (ret)
                        break;
 
-               offset_into_extent = iter->pos.offset -
+               offset_into_extent = iter.pos.offset -
                        bkey_start_offset(k.k);
                sectors = k.k->size - offset_into_extent;
 
@@ -838,7 +850,7 @@ retry:
                if (bkey_extent_is_allocation(k.k))
                        bch2_add_page_sectors(&rbio->bio, k);
 
-               bch2_read_extent(trans, rbio, iter->pos,
+               bch2_read_extent(trans, rbio, iter.pos,
                                 data_btree, k, offset_into_extent, flags);
 
                if (flags & BCH_READ_LAST_FRAGMENT)
@@ -847,12 +859,14 @@ retry:
                swap(rbio->bio.bi_iter.bi_size, bytes);
                bio_advance(&rbio->bio, bytes);
        }
+err:
+       bch2_trans_iter_exit(trans, &iter);
 
        if (ret == -EINTR)
                goto retry;
 
        if (ret) {
-               bch_err_inum_ratelimited(c, inum,
+               bch_err_inum_ratelimited(c, inum.inum,
                                "read error %i from btree lookup", ret);
                rbio->bio.bi_status = BLK_STS_IOERR;
                bio_endio(&rbio->bio);
@@ -867,7 +881,6 @@ void bch2_readahead(struct readahead_control *ractl)
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        struct bch_io_opts opts = io_opts(c, &inode->ei_inode);
        struct btree_trans trans;
-       struct btree_iter iter;
        struct page *page;
        struct readpages_iter readpages_iter;
        int ret;
@@ -876,8 +889,6 @@ void bch2_readahead(struct readahead_control *ractl)
        BUG_ON(ret);
 
        bch2_trans_init(&trans, c, 0, 0);
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents, POS_MIN,
-                            BTREE_ITER_SLOTS);
 
        bch2_pagecache_add_get(&inode->ei_pagecache_lock);
 
@@ -898,22 +909,20 @@ void bch2_readahead(struct readahead_control *ractl)
                rbio->bio.bi_end_io = bch2_readpages_end_io;
                BUG_ON(!bio_add_page(&rbio->bio, page, PAGE_SIZE, 0));
 
-               bchfs_read(&trans, &iter, rbio, inode->v.i_ino,
+               bchfs_read(&trans, rbio, inode_inum(inode),
                           &readpages_iter);
        }
 
        bch2_pagecache_add_put(&inode->ei_pagecache_lock);
 
-       bch2_trans_iter_exit(&trans, &iter);
        bch2_trans_exit(&trans);
        kfree(readpages_iter.pages);
 }
 
 static void __bchfs_readpage(struct bch_fs *c, struct bch_read_bio *rbio,
-                            u64 inum, struct page *page)
+                            subvol_inum inum, struct page *page)
 {
        struct btree_trans trans;
-       struct btree_iter iter;
 
        bch2_page_state_create(page, __GFP_NOFAIL);
 
@@ -923,12 +932,7 @@ static void __bchfs_readpage(struct bch_fs *c, struct bch_read_bio *rbio,
        BUG_ON(!bio_add_page(&rbio->bio, page, PAGE_SIZE, 0));
 
        bch2_trans_init(&trans, c, 0, 0);
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents, POS_MIN,
-                            BTREE_ITER_SLOTS);
-
-       bchfs_read(&trans, &iter, rbio, inum, NULL);
-
-       bch2_trans_iter_exit(&trans, &iter);
+       bchfs_read(&trans, rbio, inum, NULL);
        bch2_trans_exit(&trans);
 }
 
@@ -951,7 +955,7 @@ static int bch2_read_single_page(struct page *page,
        rbio->bio.bi_private = &done;
        rbio->bio.bi_end_io = bch2_read_single_page_end_io;
 
-       __bchfs_readpage(c, rbio, inode->v.i_ino, page);
+       __bchfs_readpage(c, rbio, inode_inum(inode), page);
        wait_for_completion(&done);
 
        ret = blk_status_to_errno(rbio->bio.bi_status);
@@ -1096,6 +1100,7 @@ static void bch2_writepage_io_alloc(struct bch_fs *c,
        op->nr_replicas         = nr_replicas;
        op->res.nr_replicas     = nr_replicas;
        op->write_point         = writepoint_hashed(inode->ei_last_dirtied);
+       op->subvol              = inode->ei_subvol;
        op->pos                 = POS(inode->v.i_ino, sector);
        op->end_io              = bch2_writepage_io_done;
        op->wbio.bio.bi_iter.bi_sector = sector;
@@ -1733,7 +1738,7 @@ start:
                if (iter->count)
                        closure_get(&dio->cl);
 
-               bch2_read(c, rbio_init(bio, opts), inode->v.i_ino);
+               bch2_read(c, rbio_init(bio, opts), inode_inum(inode));
        }
 
        iter->count += shorten;
@@ -1816,7 +1821,8 @@ retry:
                if (bkey_cmp(bkey_start_pos(k.k), POS(inum.inum, end)) >= 0)
                        break;
 
-               if (nr_replicas > bch2_bkey_replicas(c, k) ||
+               if (k.k->p.snapshot != snapshot ||
+                   nr_replicas > bch2_bkey_replicas(c, k) ||
                    (!compressed && bch2_bkey_sectors_compressed(k))) {
                        ret = false;
                        break;
@@ -1944,6 +1950,7 @@ static long bch2_dio_write_loop(struct dio_write *dio)
                op_journal_seq_set(&dio->op, &inode->ei_journal_seq);
                dio->op.write_point     = writepoint_hashed((unsigned long) current);
                dio->op.nr_replicas     = dio->op.opts.data_replicas;
+               dio->op.subvol          = inode->ei_subvol;
                dio->op.pos             = POS(inode->v.i_ino, (u64) req->ki_pos >> 9);
 
                if ((req->ki_flags & IOCB_DSYNC) &&
@@ -2438,7 +2445,7 @@ int bch2_truncate(struct mnt_idmap *idmap,
 
        truncate_setsize(&inode->v, iattr->ia_size);
 
-       ret = bch2_fpunch(c, inode->v.i_ino,
+       ret = bch2_fpunch(c, inode_inum(inode),
                        round_up(iattr->ia_size, block_bytes(c)) >> 9,
                        U64_MAX, &inode->ei_journal_seq, &i_sectors_delta);
        i_sectors_acct(c, inode, NULL, i_sectors_delta);
@@ -2498,7 +2505,7 @@ static long bchfs_fpunch(struct bch_inode_info *inode, loff_t offset, loff_t len
        if (discard_start < discard_end) {
                s64 i_sectors_delta = 0;
 
-               ret = bch2_fpunch(c, inode->v.i_ino,
+               ret = bch2_fpunch(c, inode_inum(inode),
                                  discard_start, discard_end,
                                  &inode->ei_journal_seq,
                                  &i_sectors_delta);
@@ -2577,7 +2584,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
        } else {
                s64 i_sectors_delta = 0;
 
-               ret = bch2_fpunch(c, inode->v.i_ino,
+               ret = bch2_fpunch(c, inode_inum(inode),
                                  offset >> 9, (offset + len) >> 9,
                                  &inode->ei_journal_seq,
                                  &i_sectors_delta);
@@ -2793,7 +2800,8 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                        reservation.v.nr_replicas = disk_res.nr_replicas;
                }
 
-               ret = bch2_extent_update(&trans, &iter, &reservation.k_i,
+               ret = bch2_extent_update(&trans, inode_inum(inode), &iter,
+                                        &reservation.k_i,
                                &disk_res, &inode->ei_journal_seq,
                                0, &i_sectors_delta, true);
                i_sectors_acct(c, inode, &quota_res, i_sectors_delta);
index 0f5e009..bd96c6b 100644 (file)
@@ -27,6 +27,7 @@
 #include "keylist.h"
 #include "move.h"
 #include "rebalance.h"
+#include "subvolume.h"
 #include "super.h"
 #include "super-io.h"
 #include "trace.h"
@@ -230,7 +231,8 @@ int bch2_sum_sector_overwrites(struct btree_trans *trans,
                        : 0;
 
                if (!*usage_increasing &&
-                   (new_replicas > bch2_bkey_replicas(c, old) ||
+                   (new->k.p.snapshot != old.k->p.snapshot ||
+                    new_replicas > bch2_bkey_replicas(c, old) ||
                     (!new_compressed && bch2_bkey_sectors_compressed(old))))
                        *usage_increasing = true;
 
@@ -266,6 +268,7 @@ int bch2_sum_sector_overwrites(struct btree_trans *trans,
 }
 
 int bch2_extent_update(struct btree_trans *trans,
+                      subvol_inum inum,
                       struct btree_iter *iter,
                       struct bkey_i *k,
                       struct disk_reservation *disk_res,
@@ -324,11 +327,8 @@ int bch2_extent_update(struct btree_trans *trans,
                struct btree_iter inode_iter;
                struct bch_inode_unpacked inode_u;
 
-               ret = bch2_inode_peek(trans, &inode_iter, &inode_u,
-                                     (subvol_inum) {
-                                     .subvol = BCACHEFS_ROOT_SUBVOL,
-                                     .inum = k->k.p.inode,
-                                     }, BTREE_ITER_INTENT);
+               ret = bch2_inode_peek(trans, &inode_iter, &inode_u, inum,
+                                     BTREE_ITER_INTENT);
                if (ret)
                        return ret;
 
@@ -384,22 +384,37 @@ int bch2_extent_update(struct btree_trans *trans,
        return 0;
 }
 
+/*
+ * Returns -EINTR if we had to drop locks:
+ */
 int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
-                  struct bpos end, u64 *journal_seq,
-                  s64 *i_sectors_delta)
+                  subvol_inum inum, u64 end,
+                  u64 *journal_seq, s64 *i_sectors_delta)
 {
        struct bch_fs *c        = trans->c;
        unsigned max_sectors    = KEY_SIZE_MAX & (~0 << c->block_bits);
+       struct bpos end_pos = POS(inum.inum, end);
        struct bkey_s_c k;
        int ret = 0, ret2 = 0;
+       u32 snapshot;
 
-       while ((bch2_trans_begin(trans),
-               (k = bch2_btree_iter_peek(iter)).k) &&
-              bkey_cmp(iter->pos, end) < 0) {
+       while (1) {
                struct disk_reservation disk_res =
                        bch2_disk_reservation_init(c, 0);
                struct bkey_i delete;
 
+               bch2_trans_begin(trans);
+
+               ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
+               if (ret)
+                       goto btree_err;
+
+               bch2_btree_iter_set_snapshot(iter, snapshot);
+
+               k = bch2_btree_iter_peek(iter);
+               if (bkey_cmp(iter->pos, end_pos) >= 0)
+                       break;
+
                ret = bkey_err(k);
                if (ret)
                        goto btree_err;
@@ -409,9 +424,9 @@ int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
 
                /* create the biggest key we can */
                bch2_key_resize(&delete.k, max_sectors);
-               bch2_cut_back(end, &delete);
+               bch2_cut_back(end_pos, &delete);
 
-               ret = bch2_extent_update(trans, iter, &delete,
+               ret = bch2_extent_update(trans, inum, iter, &delete,
                                &disk_res, journal_seq,
                                0, i_sectors_delta, false);
                bch2_disk_reservation_put(c, &disk_res);
@@ -424,36 +439,31 @@ btree_err:
                        break;
        }
 
-       if (bkey_cmp(iter->pos, end) > 0) {
-               bch2_btree_iter_set_pos(iter, end);
-               ret = bch2_btree_iter_traverse(iter);
-       }
+       if (bkey_cmp(iter->pos, end_pos) > 0)
+               bch2_btree_iter_set_pos(iter, end_pos);
 
        return ret ?: ret2;
 }
 
-int bch2_fpunch(struct bch_fs *c, u64 inum, u64 start, u64 end,
+int bch2_fpunch(struct bch_fs *c, subvol_inum inum, u64 start, u64 end,
                u64 *journal_seq, s64 *i_sectors_delta)
 {
        struct btree_trans trans;
        struct btree_iter iter;
-       int ret = 0;
+       int ret;
 
        bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024);
        bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
-                                  POS(inum, start),
-                                  BTREE_ITER_INTENT);
+                            POS(inum.inum, start),
+                            BTREE_ITER_INTENT);
 
-       ret = bch2_fpunch_at(&trans, &iter, POS(inum, end),
+       ret = bch2_fpunch_at(&trans, &iter, inum, end,
                             journal_seq, i_sectors_delta);
 
        bch2_trans_iter_exit(&trans, &iter);
        bch2_trans_exit(&trans);
 
-       if (ret == -EINTR)
-               ret = 0;
-
-       return ret;
+       return ret == -EINTR ? 0 : ret;
 }
 
 static int bch2_write_index_default(struct bch_write_op *op)
@@ -464,40 +474,51 @@ static int bch2_write_index_default(struct bch_write_op *op)
        struct bkey_i *k = bch2_keylist_front(keys);
        struct btree_trans trans;
        struct btree_iter iter;
+       subvol_inum inum = {
+               .subvol = op->subvol,
+               .inum   = k->k.p.inode,
+       };
        int ret;
 
+       BUG_ON(!inum.subvol);
+
        bch2_bkey_buf_init(&sk);
        bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024);
 
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
-                            bkey_start_pos(&k->k),
-                            BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
-
        do {
                bch2_trans_begin(&trans);
 
                k = bch2_keylist_front(keys);
+               bch2_bkey_buf_copy(&sk, c, k);
 
-               k->k.p.snapshot = iter.snapshot;
+               ret = bch2_subvolume_get_snapshot(&trans, inum.subvol,
+                                                 &sk.k->k.p.snapshot);
+               if (ret == -EINTR)
+                       continue;
+               if (ret)
+                       break;
 
-               bch2_bkey_buf_realloc(&sk, c, k->k.u64s);
-               bkey_copy(sk.k, k);
-               bch2_cut_front(iter.pos, sk.k);
+               bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
+                                    bkey_start_pos(&sk.k->k),
+                                    BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
 
-               ret = bch2_extent_update(&trans, &iter, sk.k,
+               ret = bch2_extent_update(&trans, inum, &iter, sk.k,
                                         &op->res, op_journal_seq(op),
                                         op->new_i_size, &op->i_sectors_delta,
                                         op->flags & BCH_WRITE_CHECK_ENOSPC);
+               bch2_trans_iter_exit(&trans, &iter);
+
                if (ret == -EINTR)
                        continue;
                if (ret)
                        break;
 
                if (bkey_cmp(iter.pos, k->k.p) >= 0)
-                       bch2_keylist_pop_front(keys);
+                       bch2_keylist_pop_front(&op->insert_keys);
+               else
+                       bch2_cut_front(iter.pos, k);
        } while (!bch2_keylist_empty(keys));
 
-       bch2_trans_iter_exit(&trans, &iter);
        bch2_trans_exit(&trans);
        bch2_bkey_buf_exit(&sk, c);
 
@@ -1645,7 +1666,7 @@ static void bch2_rbio_done(struct bch_read_bio *rbio)
 }
 
 static void bch2_read_retry_nodecode(struct bch_fs *c, struct bch_read_bio *rbio,
-                                    struct bvec_iter bvec_iter, u64 inode,
+                                    struct bvec_iter bvec_iter,
                                     struct bch_io_failures *failed,
                                     unsigned flags)
 {
@@ -1709,7 +1730,10 @@ static void bch2_rbio_retry(struct work_struct *work)
        struct bch_fs *c        = rbio->c;
        struct bvec_iter iter   = rbio->bvec_iter;
        unsigned flags          = rbio->flags;
-       u64 inode               = rbio->read_pos.inode;
+       subvol_inum inum = {
+               .subvol = rbio->subvol,
+               .inum   = rbio->read_pos.inode,
+       };
        struct bch_io_failures failed = { .nr = 0 };
 
        trace_read_retry(&rbio->bio);
@@ -1725,12 +1749,12 @@ static void bch2_rbio_retry(struct work_struct *work)
        flags &= ~BCH_READ_MAY_PROMOTE;
 
        if (flags & BCH_READ_NODECODE) {
-               bch2_read_retry_nodecode(c, rbio, iter, inode, &failed, flags);
+               bch2_read_retry_nodecode(c, rbio, iter, &failed, flags);
        } else {
                flags &= ~BCH_READ_LAST_FRAGMENT;
                flags |= BCH_READ_MUST_CLONE;
 
-               __bch2_read(c, rbio, iter, inode, &failed, flags);
+               __bch2_read(c, rbio, iter, inum, &failed, flags);
        }
 }
 
@@ -2174,6 +2198,7 @@ get_bio:
        /* XXX: only initialize this if needed */
        rbio->devs_have         = bch2_bkey_devs(k);
        rbio->pick              = pick;
+       rbio->subvol            = orig->subvol;
        rbio->read_pos          = read_pos;
        rbio->data_btree        = data_btree;
        rbio->data_pos          = data_pos;
@@ -2281,25 +2306,31 @@ out_read_done:
 }
 
 void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
-                struct bvec_iter bvec_iter, u64 inode,
+                struct bvec_iter bvec_iter, subvol_inum inum,
                 struct bch_io_failures *failed, unsigned flags)
 {
        struct btree_trans trans;
        struct btree_iter iter;
        struct bkey_buf sk;
        struct bkey_s_c k;
+       u32 snapshot;
        int ret;
 
        BUG_ON(flags & BCH_READ_NODECODE);
 
        bch2_bkey_buf_init(&sk);
        bch2_trans_init(&trans, c, 0, 0);
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
-                            POS(inode, bvec_iter.bi_sector),
-                            BTREE_ITER_SLOTS);
 retry:
        bch2_trans_begin(&trans);
+       iter = (struct btree_iter) { NULL };
+
+       ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
+       if (ret)
+               goto err;
 
+       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
+                            SPOS(inum.inum, bvec_iter.bi_sector, snapshot),
+                            BTREE_ITER_SLOTS|BTREE_ITER_FILTER_SNAPSHOTS);
        while (1) {
                unsigned bytes, sectors, offset_into_extent;
                enum btree_id data_btree = BTREE_ID_extents;
@@ -2314,7 +2345,7 @@ retry:
                }
 
                bch2_btree_iter_set_pos(&iter,
-                               POS(inode, bvec_iter.bi_sector));
+                               POS(inum.inum, bvec_iter.bi_sector));
 
                k = bch2_btree_iter_peek_slot(&iter);
                ret = bkey_err(k);
@@ -2364,16 +2395,17 @@ retry:
                swap(bvec_iter.bi_size, bytes);
                bio_advance_iter(&rbio->bio, &bvec_iter, bytes);
        }
+err:
+       bch2_trans_iter_exit(&trans, &iter);
 
        if (ret == -EINTR || ret == READ_RETRY || ret == READ_RETRY_AVOID)
                goto retry;
 
-       bch2_trans_iter_exit(&trans, &iter);
        bch2_trans_exit(&trans);
        bch2_bkey_buf_exit(&sk, c);
 
        if (ret) {
-               bch_err_inum_ratelimited(c, inode,
+               bch_err_inum_ratelimited(c, inum.inum,
                                         "read error %i from btree lookup", ret);
                rbio->bio.bi_status = BLK_STS_IOERR;
                bch2_rbio_done(rbio);
index f21ffb5..ebb0944 100644 (file)
@@ -83,12 +83,13 @@ static inline struct workqueue_struct *index_update_wq(struct bch_write_op *op)
 
 int bch2_sum_sector_overwrites(struct btree_trans *, struct btree_iter *,
                               struct bkey_i *, bool *, bool *, s64 *, s64 *);
-int bch2_extent_update(struct btree_trans *, struct btree_iter *,
-                      struct bkey_i *, struct disk_reservation *,
-                      u64 *, u64, s64 *, bool);
+int bch2_extent_update(struct btree_trans *, subvol_inum,
+                      struct btree_iter *, struct bkey_i *,
+                      struct disk_reservation *, u64 *, u64, s64 *, bool);
+
 int bch2_fpunch_at(struct btree_trans *, struct btree_iter *,
-                  struct bpos, u64 *, s64 *);
-int bch2_fpunch(struct bch_fs *c, u64, u64, u64, u64 *, s64 *);
+                  subvol_inum, u64, u64 *, s64 *);
+int bch2_fpunch(struct bch_fs *c, subvol_inum, u64, u64, u64 *, s64 *);
 
 static inline void bch2_write_op_init(struct bch_write_op *op, struct bch_fs *c,
                                      struct bch_io_opts opts)
@@ -108,6 +109,7 @@ static inline void bch2_write_op_init(struct bch_write_op *op, struct bch_fs *c,
        op->devs_have.nr        = 0;
        op->target              = 0;
        op->opts                = opts;
+       op->subvol              = 0;
        op->pos                 = POS_MAX;
        op->version             = ZERO_VERSION;
        op->write_point         = (struct write_point_specifier) { 0 };
@@ -174,10 +176,10 @@ static inline void bch2_read_extent(struct btree_trans *trans,
 }
 
 void __bch2_read(struct bch_fs *, struct bch_read_bio *, struct bvec_iter,
-                u64, struct bch_io_failures *, unsigned flags);
+                subvol_inum, struct bch_io_failures *, unsigned flags);
 
 static inline void bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
-                            u64 inode)
+                            subvol_inum inum)
 {
        struct bch_io_failures failed = { .nr = 0 };
 
@@ -185,8 +187,9 @@ static inline void bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
 
        rbio->c = c;
        rbio->start_time = local_clock();
+       rbio->subvol = inum.subvol;
 
-       __bch2_read(c, rbio, rbio->bio.bi_iter, inode, &failed,
+       __bch2_read(c, rbio, rbio->bio.bi_iter, inum, &failed,
                    BCH_READ_RETRY_IF_STALE|
                    BCH_READ_MAY_PROMOTE|
                    BCH_READ_USER_MAPPED);
index 50361f2..53270f0 100644 (file)
@@ -62,6 +62,7 @@ struct bch_read_bio {
        /*
         * pos we read from - different from data_pos for indirect extents:
         */
+       u32                     subvol;
        struct bpos             read_pos;
 
        /*
@@ -124,6 +125,7 @@ struct bch_write_op {
        u16                     nonce;
        struct bch_io_opts      opts;
 
+       u32                     subvol;
        struct bpos             pos;
        struct bversion         version;
 
index be4b47b..92ff609 100644 (file)
@@ -212,6 +212,7 @@ s64 bch2_remap_range(struct bch_fs *c,
        struct bpos dst_end = dst_start, src_end = src_start;
        struct bpos src_want;
        u64 dst_done;
+       u32 dst_snapshot, src_snapshot;
        int ret = 0, ret2 = 0;
 
        if (!percpu_ref_tryget(&c->writes))
@@ -243,15 +244,19 @@ s64 bch2_remap_range(struct bch_fs *c,
                }
 
                ret = bch2_subvolume_get_snapshot(&trans, src_inum.subvol,
-                                                 &src_iter.snapshot);
+                                                 &src_snapshot);
                if (ret)
                        continue;
 
+               bch2_btree_iter_set_snapshot(&src_iter, src_snapshot);
+
                ret = bch2_subvolume_get_snapshot(&trans, dst_inum.subvol,
-                                                 &dst_iter.snapshot);
+                                                 &dst_snapshot);
                if (ret)
                        continue;
 
+               bch2_btree_iter_set_snapshot(&dst_iter, dst_snapshot);
+
                dst_done = dst_iter.pos.offset - dst_start.offset;
                src_want = POS(src_start.inode, src_start.offset + dst_done);
                bch2_btree_iter_set_pos(&src_iter, src_want);
@@ -262,11 +267,11 @@ s64 bch2_remap_range(struct bch_fs *c,
                        continue;
 
                if (bkey_cmp(src_want, src_iter.pos) < 0) {
-                       ret = bch2_fpunch_at(&trans, &dst_iter,
-                                       bpos_min(dst_end,
-                                                POS(dst_iter.pos.inode, dst_iter.pos.offset +
-                                                    src_iter.pos.offset - src_want.offset)),
-                                                journal_seq, i_sectors_delta);
+                       ret = bch2_fpunch_at(&trans, &dst_iter, dst_inum,
+                                       min(dst_end.offset,
+                                           dst_iter.pos.offset +
+                                           src_iter.pos.offset - src_want.offset),
+                                       journal_seq, i_sectors_delta);
                        continue;
                }
 
@@ -303,8 +308,9 @@ s64 bch2_remap_range(struct bch_fs *c,
                bch2_key_resize(&new_dst.k->k,
                                min(src_k.k->p.offset - src_want.offset,
                                    dst_end.offset - dst_iter.pos.offset));
-               ret = bch2_extent_update(&trans, &dst_iter, new_dst.k,
-                                        &disk_res, journal_seq,
+
+               ret = bch2_extent_update(&trans, dst_inum, &dst_iter,
+                                        new_dst.k, &disk_res, journal_seq,
                                         new_i_size, i_sectors_delta,
                                         true);
                bch2_disk_reservation_put(c, &disk_res);