Commit 61ce38b8 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

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: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent d5e4dcc2
...@@ -40,7 +40,8 @@ static void bch2_vfs_inode_init(struct bch_fs *, ...@@ -40,7 +40,8 @@ static void bch2_vfs_inode_init(struct bch_fs *,
struct bch_inode_info *, struct bch_inode_info *,
struct bch_inode_unpacked *); 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 journal_seq)
{ {
u64 old, v = READ_ONCE(dst->ei_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, ...@@ -51,6 +52,8 @@ static void journal_seq_copy(struct bch_inode_info *dst,
if (old >= journal_seq) if (old >= journal_seq)
break; break;
} while ((v = cmpxchg(&dst->ei_journal_seq, old, journal_seq)) != old); } 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) static void __pagecache_lock_put(struct pagecache_lock *lock, long i)
...@@ -294,12 +297,12 @@ __bch2_create(struct mnt_idmap *idmap, ...@@ -294,12 +297,12 @@ __bch2_create(struct mnt_idmap *idmap,
if (!tmpfile) { if (!tmpfile) {
bch2_inode_update_after_write(c, dir, &dir_u, bch2_inode_update_after_write(c, dir, &dir_u,
ATTR_MTIME|ATTR_CTIME); ATTR_MTIME|ATTR_CTIME);
journal_seq_copy(dir, journal_seq); journal_seq_copy(c, dir, journal_seq);
mutex_unlock(&dir->ei_update_lock); mutex_unlock(&dir->ei_update_lock);
} }
bch2_vfs_inode_init(c, inode, &inode_u); 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_ACCESS, acl);
set_cached_acl(&inode->v, ACL_TYPE_DEFAULT, default_acl); set_cached_acl(&inode->v, ACL_TYPE_DEFAULT, default_acl);
...@@ -320,7 +323,7 @@ __bch2_create(struct mnt_idmap *idmap, ...@@ -320,7 +323,7 @@ __bch2_create(struct mnt_idmap *idmap,
* We raced, another process pulled the new inode into cache * We raced, another process pulled the new inode into cache
* before us: * before us:
*/ */
journal_seq_copy(old, journal_seq); journal_seq_copy(c, old, journal_seq);
make_bad_inode(&inode->v); make_bad_inode(&inode->v);
iput(&inode->v); iput(&inode->v);
...@@ -416,7 +419,7 @@ static int __bch2_link(struct bch_fs *c, ...@@ -416,7 +419,7 @@ static int __bch2_link(struct bch_fs *c,
if (likely(!ret)) { if (likely(!ret)) {
BUG_ON(inode_u.bi_inum != inode->v.i_ino); 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, bch2_inode_update_after_write(c, dir, &dir_u,
ATTR_MTIME|ATTR_CTIME); ATTR_MTIME|ATTR_CTIME);
bch2_inode_update_after_write(c, inode, &inode_u, 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) ...@@ -473,7 +476,7 @@ static int bch2_unlink(struct inode *vdir, struct dentry *dentry)
if (likely(!ret)) { if (likely(!ret)) {
BUG_ON(inode_u.bi_inum != inode->v.i_ino); 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, bch2_inode_update_after_write(c, dir, &dir_u,
ATTR_MTIME|ATTR_CTIME); ATTR_MTIME|ATTR_CTIME);
bch2_inode_update_after_write(c, inode, &inode_u, bch2_inode_update_after_write(c, inode, &inode_u,
...@@ -509,7 +512,7 @@ static int bch2_symlink(struct mnt_idmap *idmap, ...@@ -509,7 +512,7 @@ static int bch2_symlink(struct mnt_idmap *idmap,
if (unlikely(ret)) if (unlikely(ret))
goto err; 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); ret = __bch2_link(c, inode, dir, dentry);
if (unlikely(ret)) if (unlikely(ret))
...@@ -609,22 +612,22 @@ static int bch2_rename2(struct mnt_idmap *idmap, ...@@ -609,22 +612,22 @@ static int bch2_rename2(struct mnt_idmap *idmap,
bch2_inode_update_after_write(c, src_dir, &src_dir_u, bch2_inode_update_after_write(c, src_dir, &src_dir_u,
ATTR_MTIME|ATTR_CTIME); ATTR_MTIME|ATTR_CTIME);
journal_seq_copy(src_dir, journal_seq); journal_seq_copy(c, src_dir, journal_seq);
if (src_dir != dst_dir) { if (src_dir != dst_dir) {
bch2_inode_update_after_write(c, dst_dir, &dst_dir_u, bch2_inode_update_after_write(c, dst_dir, &dst_dir_u,
ATTR_MTIME|ATTR_CTIME); 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, bch2_inode_update_after_write(c, src_inode, &src_inode_u,
ATTR_CTIME); ATTR_CTIME);
journal_seq_copy(src_inode, journal_seq); journal_seq_copy(c, src_inode, journal_seq);
if (dst_inode) { if (dst_inode) {
bch2_inode_update_after_write(c, dst_inode, &dst_inode_u, bch2_inode_update_after_write(c, dst_inode, &dst_inode_u,
ATTR_CTIME); ATTR_CTIME);
journal_seq_copy(dst_inode, journal_seq); journal_seq_copy(c, dst_inode, journal_seq);
} }
err: err:
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "super-io.h" #include "super-io.h"
#include "trace.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) static bool __journal_entry_is_open(union journal_res_state state)
{ {
return state.cur_entry_offset < JOURNAL_ENTRY_CLOSED_VAL; return state.cur_entry_offset < JOURNAL_ENTRY_CLOSED_VAL;
...@@ -304,6 +306,19 @@ u64 bch2_inode_journal_seq(struct journal *j, u64 inode) ...@@ -304,6 +306,19 @@ u64 bch2_inode_journal_seq(struct journal *j, u64 inode)
return seq; 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, static int __journal_res_get(struct journal *j, struct journal_res *res,
unsigned flags) unsigned flags)
{ {
......
...@@ -147,6 +147,7 @@ static inline u64 journal_cur_seq(struct journal *j) ...@@ -147,6 +147,7 @@ static inline u64 journal_cur_seq(struct journal *j)
} }
u64 bch2_inode_journal_seq(struct journal *, u64); 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) static inline int journal_state_count(union journal_res_state s, int idx)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment