bcachefs: Convert bch2_fpunch to bch2_extent_update()
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 10 Oct 2019 16:47:22 +0000 (12:47 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:29 +0000 (17:08 -0400)
As before - we're moving non Linux specific code out of fs-io.c.

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

index 92cab285698c463c9ddf62543a236c431d962d7d..19793745edf9fb757e0882121b7c44250fb3aaed 100644 (file)
@@ -2145,78 +2145,6 @@ out:
 
 /* truncate: */
 
-int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
-                  struct bpos end, struct bch_inode_info *inode)
-{
-       struct bch_fs *c        = trans->c;
-       unsigned max_sectors    = KEY_SIZE_MAX & (~0 << c->block_bits);
-       struct bkey_s_c k;
-       int ret = 0, ret2 = 0;
-
-       while ((k = bch2_btree_iter_peek(iter)).k &&
-              bkey_cmp(iter->pos, end) < 0) {
-               struct disk_reservation disk_res =
-                       bch2_disk_reservation_init(c, 0);
-               struct bkey_i delete;
-
-               ret = bkey_err(k);
-               if (ret)
-                       goto btree_err;
-
-               bkey_init(&delete.k);
-               delete.k.p = iter->pos;
-
-               /* create the biggest key we can */
-               bch2_key_resize(&delete.k, max_sectors);
-               bch2_cut_back(end, &delete.k);
-
-               bch2_trans_begin_updates(trans);
-
-               ret = bchfs_extent_update(trans, inode,
-                               &disk_res, NULL, iter, &delete,
-                               0, false, true, NULL);
-               bch2_disk_reservation_put(c, &disk_res);
-btree_err:
-               if (ret == -EINTR) {
-                       ret2 = ret;
-                       ret = 0;
-               }
-               if (ret)
-                       break;
-       }
-
-       if (bkey_cmp(iter->pos, end) > 0) {
-               bch2_btree_iter_set_pos(iter, end);
-               ret = bch2_btree_iter_traverse(iter);
-       }
-
-       return ret ?: ret2;
-}
-
-static int __bch2_fpunch(struct bch_fs *c, struct bch_inode_info *inode,
-                        u64 start_offset, u64 end_offset)
-{
-       struct btree_trans trans;
-       struct btree_iter *iter;
-       int ret = 0;
-
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024);
-
-       iter = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS,
-                                  POS(inode->v.i_ino, start_offset),
-                                  BTREE_ITER_INTENT);
-
-       ret = bch2_fpunch_at(&trans, iter,
-                       POS(inode->v.i_ino, end_offset), inode);
-
-       bch2_trans_exit(&trans);
-
-       if (ret == -EINTR)
-               ret = 0;
-
-       return ret;
-}
-
 static inline int range_has_data(struct bch_fs *c,
                                  struct bpos start,
                                  struct bpos end)
@@ -2388,6 +2316,7 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
        struct btree_trans trans;
        struct btree_iter *iter;
        u64 new_i_size = iattr->ia_size;
+       s64 i_sectors_delta = 0;
        int ret = 0;
 
        inode_dio_wait(&inode->v);
@@ -2447,9 +2376,11 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
 
        truncate_setsize(&inode->v, iattr->ia_size);
 
-       ret = __bch2_fpunch(c, inode,
+       ret = bch2_fpunch(c, inode->v.i_ino,
                        round_up(iattr->ia_size, block_bytes(c)) >> 9,
-                       U64_MAX);
+                       U64_MAX, &inode->ei_journal_seq, &i_sectors_delta);
+       i_sectors_acct(c, inode, NULL, i_sectors_delta);
+
        if (unlikely(ret))
                goto err;
 
@@ -2467,7 +2398,7 @@ err:
 
 /* fallocate: */
 
-static long bch2_fpunch(struct bch_inode_info *inode, loff_t offset, loff_t len)
+static long bchfs_fpunch(struct bch_inode_info *inode, loff_t offset, loff_t len)
 {
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        u64 discard_start = round_up(offset, block_bytes(c)) >> 9;
@@ -2495,8 +2426,15 @@ static long bch2_fpunch(struct bch_inode_info *inode, loff_t offset, loff_t len)
 
        truncate_pagecache_range(&inode->v, offset, offset + len - 1);
 
-       if (discard_start < discard_end)
-               ret = __bch2_fpunch(c, inode, discard_start, discard_end);
+       if (discard_start < discard_end) {
+               s64 i_sectors_delta = 0;
+
+               ret = bch2_fpunch(c, inode->v.i_ino,
+                                 discard_start, discard_end,
+                                 &inode->ei_journal_seq,
+                                 &i_sectors_delta);
+               i_sectors_acct(c, inode, NULL, i_sectors_delta);
+       }
 err:
        bch2_pagecache_block_put(&inode->ei_pagecache_lock);
        inode_unlock(&inode->v);
@@ -2504,7 +2442,7 @@ err:
        return ret;
 }
 
-static long bch2_fcollapse_finsert(struct bch_inode_info *inode,
+static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
                                   loff_t offset, loff_t len,
                                   bool insert)
 {
@@ -2564,8 +2502,14 @@ static long bch2_fcollapse_finsert(struct bch_inode_info *inode,
                                            ATTR_MTIME|ATTR_CTIME);
                mutex_unlock(&inode->ei_update_lock);
        } else {
-               ret = __bch2_fpunch(c, inode, offset >> 9,
-                                   (offset + len) >> 9);
+               s64 i_sectors_delta = 0;
+
+               ret = bch2_fpunch(c, inode->v.i_ino,
+                                 offset >> 9, (offset + len) >> 9,
+                                 &inode->ei_journal_seq,
+                                 &i_sectors_delta);
+               i_sectors_acct(c, inode, NULL, i_sectors_delta);
+
                if (ret)
                        goto err;
        }
@@ -2715,8 +2659,8 @@ err:
        return ret;
 }
 
-static long bch2_fallocate(struct bch_inode_info *inode, int mode,
-                          loff_t offset, loff_t len)
+static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
+                           loff_t offset, loff_t len)
 {
        struct address_space *mapping = inode->v.i_mapping;
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
@@ -2765,6 +2709,7 @@ static long bch2_fallocate(struct bch_inode_info *inode, int mode,
        end_pos = POS(inode->v.i_ino, block_end >> 9);
 
        while (bkey_cmp(iter->pos, end_pos) < 0) {
+               s64 i_sectors_delta = 0;
                struct disk_reservation disk_res = { 0 };
                struct quota_res quota_res = { 0 };
                struct bkey_i_reservation reservation;
@@ -2818,10 +2763,10 @@ static long bch2_fallocate(struct bch_inode_info *inode, int mode,
 
                bch2_trans_begin_updates(&trans);
 
-               ret = bchfs_extent_update(&trans, inode,
-                               &disk_res, &quota_res,
-                               iter, &reservation.k_i,
-                               0, true, true, NULL);
+               ret = bch2_extent_update(&trans, iter, &reservation.k_i,
+                               &disk_res, &inode->ei_journal_seq,
+                               0, &i_sectors_delta);
+               i_sectors_acct(c, inode, &quota_res, i_sectors_delta);
 bkey_err:
                bch2_quota_reservation_put(c, inode, &quota_res);
                bch2_disk_reservation_put(c, &disk_res);
@@ -2887,16 +2832,16 @@ long bch2_fallocate_dispatch(struct file *file, int mode,
        struct bch_inode_info *inode = file_bch_inode(file);
 
        if (!(mode & ~(FALLOC_FL_KEEP_SIZE|FALLOC_FL_ZERO_RANGE)))
-               return bch2_fallocate(inode, mode, offset, len);
+               return bchfs_fallocate(inode, mode, offset, len);
 
        if (mode == (FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE))
-               return bch2_fpunch(inode, offset, len);
+               return bchfs_fpunch(inode, offset, len);
 
        if (mode == FALLOC_FL_INSERT_RANGE)
-               return bch2_fcollapse_finsert(inode, offset, len, true);
+               return bchfs_fcollapse_finsert(inode, offset, len, true);
 
        if (mode == FALLOC_FL_COLLAPSE_RANGE)
-               return bch2_fcollapse_finsert(inode, offset, len, false);
+               return bchfs_fcollapse_finsert(inode, offset, len, false);
 
        return -EOPNOTSUPP;
 }
@@ -2941,6 +2886,7 @@ loff_t bch2_remap_file_range(struct file *file_src, loff_t pos_src,
        struct bch_inode_info *src = file_bch_inode(file_src);
        struct bch_inode_info *dst = file_bch_inode(file_dst);
        struct bch_fs *c = src->v.i_sb->s_fs_info;
+       s64 i_sectors_delta = 0;
        loff_t ret = 0;
        loff_t aligned_len;
 
@@ -2960,6 +2906,8 @@ loff_t bch2_remap_file_range(struct file *file_src, loff_t pos_src,
 
        bch2_lock_inodes(INODE_LOCK|INODE_PAGECACHE_BLOCK, src, dst);
 
+       file_update_time(file_dst);
+
        inode_dio_wait(&src->v);
        inode_dio_wait(&dst->v);
 
@@ -2967,26 +2915,40 @@ loff_t bch2_remap_file_range(struct file *file_src, loff_t pos_src,
                                            file_dst, pos_dst,
                                            &len, remap_flags);
        if (ret < 0 || len == 0)
-               goto out_unlock;
+               goto err;
 
        aligned_len = round_up(len, block_bytes(c));
 
        ret = write_invalidate_inode_pages_range(dst->v.i_mapping,
                                pos_dst, pos_dst + aligned_len);
        if (ret)
-               goto out_unlock;
+               goto err;
 
        mark_range_unallocated(src, pos_src, pos_src + aligned_len);
 
-       ret = bch2_remap_range(c, dst,
+       ret = bch2_remap_range(c,
                               POS(dst->v.i_ino, pos_dst >> 9),
                               POS(src->v.i_ino, pos_src >> 9),
                               aligned_len >> 9,
-                              pos_dst + len);
-       if (ret > 0)
-               ret = min(ret << 9, len);
+                              &dst->ei_journal_seq,
+                              pos_dst + len, &i_sectors_delta);
+       if (ret < 0)
+               goto err;
 
-out_unlock:
+       ret <<= 9;
+       /*
+        * due to alignment, we might have remapped slightly more than requsted
+        */
+       ret = min(ret, len);
+
+       /* XXX get a quota reservation */
+       i_sectors_acct(c, dst, NULL, i_sectors_delta);
+
+       spin_lock(&dst->v.i_lock);
+       if (pos_dst + len > dst->v.i_size)
+               i_size_write(&dst->v, pos_dst + len);
+       spin_unlock(&dst->v.i_lock);
+err:
        bch2_unlock_inodes(INODE_LOCK|INODE_PAGECACHE_BLOCK, src, dst);
 
        return ret;
index 090d1c86de37f925f3a9b54d24b48beb36401a16..f823810d4971d0d5a15e50dd7b28ffaa114b7568 100644 (file)
@@ -18,8 +18,6 @@ int bchfs_extent_update(struct btree_trans *,
                        struct btree_iter *,
                        struct bkey_i *,
                        u64, bool, bool, s64 *);
-int bch2_fpunch_at(struct btree_trans *, struct btree_iter *,
-                  struct bpos, struct bch_inode_info *);
 
 int __must_check bch2_write_inode_size(struct bch_fs *,
                                       struct bch_inode_info *,
index a9b1c21dd9a703d1449041accb37d95143283053..c60e52fbf4fed4d6a8186ccd9f74d3618ccf54cf 100644 (file)
@@ -319,6 +319,77 @@ int bch2_extent_update(struct btree_trans *trans,
        return ret;
 }
 
+int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
+                  struct bpos 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 bkey_s_c k;
+       int ret = 0, ret2 = 0;
+
+       while ((k = bch2_btree_iter_peek(iter)).k &&
+              bkey_cmp(iter->pos, end) < 0) {
+               struct disk_reservation disk_res =
+                       bch2_disk_reservation_init(c, 0);
+               struct bkey_i delete;
+
+               ret = bkey_err(k);
+               if (ret)
+                       goto btree_err;
+
+               bkey_init(&delete.k);
+               delete.k.p = iter->pos;
+
+               /* create the biggest key we can */
+               bch2_key_resize(&delete.k, max_sectors);
+               bch2_cut_back(end, &delete.k);
+
+               bch2_trans_begin_updates(trans);
+
+               ret = bch2_extent_update(trans, iter, &delete,
+                               &disk_res, journal_seq,
+                               0, i_sectors_delta);
+               bch2_disk_reservation_put(c, &disk_res);
+btree_err:
+               if (ret == -EINTR) {
+                       ret2 = ret;
+                       ret = 0;
+               }
+               if (ret)
+                       break;
+       }
+
+       if (bkey_cmp(iter->pos, end) > 0) {
+               bch2_btree_iter_set_pos(iter, end);
+               ret = bch2_btree_iter_traverse(iter);
+       }
+
+       return ret ?: ret2;
+}
+
+int bch2_fpunch(struct bch_fs *c, u64 inum, u64 start, u64 end,
+               u64 *journal_seq, s64 *i_sectors_delta)
+{
+       struct btree_trans trans;
+       struct btree_iter *iter;
+       int ret = 0;
+
+       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024);
+       iter = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS,
+                                  POS(inum, start),
+                                  BTREE_ITER_INTENT);
+
+       ret = bch2_fpunch_at(&trans, iter, POS(inum, end),
+                            journal_seq, i_sectors_delta);
+       bch2_trans_exit(&trans);
+
+       if (ret == -EINTR)
+               ret = 0;
+
+       return ret;
+}
+
 /* Writes */
 
 void bch2_submit_wbio_replicas(struct bch_write_bio *wbio, struct bch_fs *c,
index e53f9ecc082dc5ba043c19f33175164e2c2a254e..97cc661420c60ccef4c28eb70b250ade5c9454fe 100644 (file)
@@ -61,6 +61,10 @@ static inline struct workqueue_struct *index_update_wq(struct bch_write_op *op)
 int bch2_extent_update(struct btree_trans *, struct btree_iter *,
                       struct bkey_i *, struct disk_reservation *,
                       u64 *, u64, s64 *);
+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 *);
+
 int bch2_write_index_default(struct bch_write_op *);
 
 static inline void bch2_write_op_init(struct bch_write_op *op, struct bch_fs *c,
index c9ff467cc0d944c0e076119f7f541eeaf0db9acb..4a4b17f93a2ef3db040e7ad5e6e95529b710eb12 100644 (file)
@@ -2,8 +2,8 @@
 #include "bcachefs.h"
 #include "btree_update.h"
 #include "extents.h"
-#include "fs.h"
-#include "fs-io.h"
+#include "inode.h"
+#include "io.h"
 #include "reflink.h"
 
 #include <linux/sched/signal.h>
@@ -70,12 +70,6 @@ void bch2_reflink_v_to_text(struct printbuf *out, struct bch_fs *c,
        bch2_bkey_ptrs_to_text(out, c, k);
 }
 
-/*
- * bch2_remap_range() depends on bch2_extent_update(), which depends on various
- * things tied to the linux vfs for inode updates, for now:
- */
-#ifndef NO_BCACHEFS_FS
-
 static int bch2_make_extent_indirect(struct btree_trans *trans,
                                     struct btree_iter *extent_iter,
                                     struct bkey_i_extent *e)
@@ -159,9 +153,9 @@ static struct bkey_s_c get_next_src(struct btree_iter *iter, struct bpos end)
 }
 
 s64 bch2_remap_range(struct bch_fs *c,
-                    struct bch_inode_info *dst_inode,
                     struct bpos dst_start, struct bpos src_start,
-                    u64 remap_sectors, u64 new_i_size)
+                    u64 remap_sectors, u64 *journal_seq,
+                    u64 new_i_size, s64 *i_sectors_delta)
 {
        struct btree_trans trans;
        struct btree_iter *dst_iter, *src_iter;
@@ -170,7 +164,7 @@ s64 bch2_remap_range(struct bch_fs *c,
        struct bpos dst_end = dst_start, src_end = src_start;
        struct bpos dst_want, src_want;
        u64 src_done, dst_done;
-       int ret = 0;
+       int ret = 0, ret2 = 0;
 
        if (!(c->sb.features & (1ULL << BCH_FEATURE_REFLINK))) {
                mutex_lock(&c->sb_lock);
@@ -213,7 +207,7 @@ s64 bch2_remap_range(struct bch_fs *c,
 
                if (bkey_cmp(dst_iter->pos, dst_want) < 0) {
                        ret = bch2_fpunch_at(&trans, dst_iter, dst_want,
-                                            dst_inode);
+                                            journal_seq, i_sectors_delta);
                        if (ret)
                                goto btree_err;
                        continue;
@@ -259,9 +253,9 @@ s64 bch2_remap_range(struct bch_fs *c,
                                min(src_k.k->p.offset - src_iter->pos.offset,
                                    dst_end.offset - dst_iter->pos.offset));
 
-               ret = bchfs_extent_update(&trans, dst_inode, NULL, NULL,
-                                         dst_iter, &new_dst.k,
-                                         new_i_size, false, true, NULL);
+               ret = bch2_extent_update(&trans, dst_iter, &new_dst.k,
+                                        NULL, journal_seq,
+                                        new_i_size, i_sectors_delta);
                if (ret)
                        goto btree_err;
 
@@ -282,17 +276,24 @@ err:
        dst_done = dst_iter->pos.offset - dst_start.offset;
        new_i_size = min(dst_iter->pos.offset << 9, new_i_size);
 
-       ret = bch2_trans_exit(&trans) ?: ret;
+       bch2_trans_begin(&trans);
 
-       mutex_lock(&dst_inode->ei_update_lock);
-       if (dst_inode->v.i_size < new_i_size) {
-               i_size_write(&dst_inode->v, new_i_size);
-               ret = bch2_write_inode_size(c, dst_inode, new_i_size,
-                                           ATTR_MTIME|ATTR_CTIME);
-       }
-       mutex_unlock(&dst_inode->ei_update_lock);
+       do {
+               struct bch_inode_unpacked inode_u;
+               struct btree_iter *inode_iter;
 
-       return dst_done ?: ret;
-}
+               inode_iter = bch2_inode_peek(&trans, &inode_u,
+                               dst_start.inode, BTREE_ITER_INTENT);
+               ret2 = PTR_ERR_OR_ZERO(inode_iter);
 
-#endif /* NO_BCACHEFS_FS */
+               if (!ret2 &&
+                   inode_u.bi_size < new_i_size)
+                       ret2  = bch2_inode_write(&trans, inode_iter, &inode_u) ?:
+                               bch2_trans_commit(&trans, NULL, journal_seq,
+                                                 BTREE_INSERT_ATOMIC);
+       } while (ret2 == -EINTR);
+
+       ret = bch2_trans_exit(&trans) ?: ret;
+
+       return dst_done ?: ret ?: ret2;
+}
index 327618c36d33efdf576aa4caccc4c0e4febcda00..ac23b855858cc75e45e1422c0b2933e1f0dd520f 100644 (file)
@@ -24,9 +24,7 @@ void bch2_reflink_v_to_text(struct printbuf *, struct bch_fs *,
        .val_to_text    = bch2_reflink_v_to_text,               \
 }
 
-#ifndef NO_BCACHEFS_FS
-s64 bch2_remap_range(struct bch_fs *, struct bch_inode_info *,
-                    struct bpos, struct bpos, u64, u64);
-#endif /* NO_BCACHEFS_FS */
+s64 bch2_remap_range(struct bch_fs *, struct bpos, struct bpos,
+                    u64, u64 *, u64, s64 *);
 
 #endif /* _BCACHEFS_REFLINK_H */