bcachefs: Fix journal_seq_copy()
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 7 Oct 2020 02:18:21 +0000 (22:18 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:44 +0000 (17:08 -0400)
We also need to update the journal's bloom filter of inode numbers that
each journal write has upudates for - in case the inode gets evicted
before it gets fsynced.

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

index 3239c4717cc6c12c55da4aeb2366f80ef13b609b..a488dcebc11a7c99cbf0f6ee6b521f462d3ba02d 100644 (file)
@@ -40,7 +40,8 @@ static void bch2_vfs_inode_init(struct bch_fs *,
                                struct bch_inode_info *,
                                struct bch_inode_unpacked *);
 
-static void journal_seq_copy(struct bch_inode_info *dst,
+static void journal_seq_copy(struct bch_fs *c,
+                            struct bch_inode_info *dst,
                             u64 journal_seq)
 {
        u64 old, v = READ_ONCE(dst->ei_journal_seq);
@@ -51,6 +52,8 @@ static void journal_seq_copy(struct bch_inode_info *dst,
                if (old >= journal_seq)
                        break;
        } while ((v = cmpxchg(&dst->ei_journal_seq, old, journal_seq)) != old);
+
+       bch2_journal_set_has_inum(&c->journal, dst->v.i_ino, journal_seq);
 }
 
 static void __pagecache_lock_put(struct pagecache_lock *lock, long i)
@@ -294,12 +297,12 @@ err_before_quota:
        if (!tmpfile) {
                bch2_inode_update_after_write(c, dir, &dir_u,
                                              ATTR_MTIME|ATTR_CTIME);
-               journal_seq_copy(dir, journal_seq);
+               journal_seq_copy(c, dir, journal_seq);
                mutex_unlock(&dir->ei_update_lock);
        }
 
        bch2_vfs_inode_init(c, inode, &inode_u);
-       journal_seq_copy(inode, journal_seq);
+       journal_seq_copy(c, inode, journal_seq);
 
        set_cached_acl(&inode->v, ACL_TYPE_ACCESS, acl);
        set_cached_acl(&inode->v, ACL_TYPE_DEFAULT, default_acl);
@@ -320,7 +323,7 @@ err_before_quota:
                 * We raced, another process pulled the new inode into cache
                 * before us:
                 */
-               journal_seq_copy(old, journal_seq);
+               journal_seq_copy(c, old, journal_seq);
                make_bad_inode(&inode->v);
                iput(&inode->v);
 
@@ -416,7 +419,7 @@ static int __bch2_link(struct bch_fs *c,
        if (likely(!ret)) {
                BUG_ON(inode_u.bi_inum != inode->v.i_ino);
 
-               journal_seq_copy(inode, dir->ei_journal_seq);
+               journal_seq_copy(c, inode, dir->ei_journal_seq);
                bch2_inode_update_after_write(c, dir, &dir_u,
                                              ATTR_MTIME|ATTR_CTIME);
                bch2_inode_update_after_write(c, inode, &inode_u, ATTR_CTIME);
@@ -473,7 +476,7 @@ static int bch2_unlink(struct inode *vdir, struct dentry *dentry)
        if (likely(!ret)) {
                BUG_ON(inode_u.bi_inum != inode->v.i_ino);
 
-               journal_seq_copy(inode, dir->ei_journal_seq);
+               journal_seq_copy(c, inode, dir->ei_journal_seq);
                bch2_inode_update_after_write(c, dir, &dir_u,
                                              ATTR_MTIME|ATTR_CTIME);
                bch2_inode_update_after_write(c, inode, &inode_u,
@@ -509,7 +512,7 @@ static int bch2_symlink(struct mnt_idmap *idmap,
        if (unlikely(ret))
                goto err;
 
-       journal_seq_copy(dir, inode->ei_journal_seq);
+       journal_seq_copy(c, dir, inode->ei_journal_seq);
 
        ret = __bch2_link(c, inode, dir, dentry);
        if (unlikely(ret))
@@ -609,22 +612,22 @@ retry:
 
        bch2_inode_update_after_write(c, src_dir, &src_dir_u,
                                      ATTR_MTIME|ATTR_CTIME);
-       journal_seq_copy(src_dir, journal_seq);
+       journal_seq_copy(c, src_dir, journal_seq);
 
        if (src_dir != dst_dir) {
                bch2_inode_update_after_write(c, dst_dir, &dst_dir_u,
                                              ATTR_MTIME|ATTR_CTIME);
-               journal_seq_copy(dst_dir, journal_seq);
+               journal_seq_copy(c, dst_dir, journal_seq);
        }
 
        bch2_inode_update_after_write(c, src_inode, &src_inode_u,
                                      ATTR_CTIME);
-       journal_seq_copy(src_inode, journal_seq);
+       journal_seq_copy(c, src_inode, journal_seq);
 
        if (dst_inode) {
                bch2_inode_update_after_write(c, dst_inode, &dst_inode_u,
                                              ATTR_CTIME);
-               journal_seq_copy(dst_inode, journal_seq);
+               journal_seq_copy(c, dst_inode, journal_seq);
        }
 err:
        bch2_trans_exit(&trans);
index 8b0746e092deafdc8095a2062f1d9be66a6e580e..d1e4a8162ddda8a5e991bb01ea3bc7599c4ef209 100644 (file)
@@ -17,6 +17,8 @@
 #include "super-io.h"
 #include "trace.h"
 
+static inline struct journal_buf *journal_seq_to_buf(struct journal *, u64);
+
 static bool __journal_entry_is_open(union journal_res_state state)
 {
        return state.cur_entry_offset < JOURNAL_ENTRY_CLOSED_VAL;
@@ -304,6 +306,19 @@ u64 bch2_inode_journal_seq(struct journal *j, u64 inode)
        return seq;
 }
 
+void bch2_journal_set_has_inum(struct journal *j, u64 inode, u64 seq)
+{
+       size_t h = hash_64(inode, ilog2(sizeof(j->buf[0].has_inode) * 8));
+       struct journal_buf *buf;
+
+       spin_lock(&j->lock);
+
+       if ((buf = journal_seq_to_buf(j, seq)))
+               set_bit(h, buf->has_inode);
+
+       spin_unlock(&j->lock);
+}
+
 static int __journal_res_get(struct journal *j, struct journal_res *res,
                             unsigned flags)
 {
index 26654b9cf0eabd7dce23d63a8c227f66f8fe38be..b8e74c483a239f39bd760c2acb3e3a9b693430fe 100644 (file)
@@ -147,6 +147,7 @@ static inline u64 journal_cur_seq(struct journal *j)
 }
 
 u64 bch2_inode_journal_seq(struct journal *, u64);
+void bch2_journal_set_has_inum(struct journal *, u64, u64);
 
 static inline int journal_state_count(union journal_res_state s, int idx)
 {