summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-10-06 22:18:21 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2020-10-21 15:33:15 -0400
commitbec65b7db1dfed3b76d8ca4dd1a42701b831435d (patch)
treeea6f4b029666a86528a67aaf0c8747cfdbe7000d
parentcd0637d7e94e4d20e626c3a3b5eec433aaa63440 (diff)
bcachefs: Fix journal_seq_copy()
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>
-rw-r--r--fs/bcachefs/fs.c25
-rw-r--r--fs/bcachefs/journal.c15
-rw-r--r--fs/bcachefs/journal.h1
3 files changed, 30 insertions, 11 deletions
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index 36d9aba5ef3f..6a9820e83db7 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -38,7 +38,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);
@@ -49,6 +50,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)
@@ -285,12 +288,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);
@@ -307,7 +310,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);
@@ -401,7 +404,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);
@@ -458,7 +461,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,
@@ -493,7 +496,7 @@ static int bch2_symlink(struct inode *vdir, struct dentry *dentry,
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))
@@ -591,22 +594,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);
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c
index 210ad1b0c469..b8b719902c63 100644
--- a/fs/bcachefs/journal.c
+++ b/fs/bcachefs/journal.c
@@ -18,6 +18,8 @@
#include <trace/events/bcachefs.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;
@@ -305,6 +307,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)
{
diff --git a/fs/bcachefs/journal.h b/fs/bcachefs/journal.h
index 56438840efd7..f60bc964ee1f 100644
--- a/fs/bcachefs/journal.h
+++ b/fs/bcachefs/journal.h
@@ -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)
{