From 184b1dc1a6bf4bc53a1c71bf14120498aad67ff5 Mon Sep 17 00:00:00 2001 From: Justin Husted Date: Mon, 11 Nov 2019 20:14:30 -0800 Subject: [PATCH] bcachefs: Update directory timestamps during link Timestamp updates on the directory during a link operation were cached. This is inconsistent with other metadata operations such as rename, as well as being less efficient. Signed-off-by: Justin Husted Signed-off-by: Kent Overstreet --- fs/bcachefs/fs-common.c | 12 ++++++------ fs/bcachefs/fs-common.h | 1 + fs/bcachefs/fs.c | 12 +++++++++--- fs/bcachefs/fsck.c | 4 ++-- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/fs/bcachefs/fs-common.c b/fs/bcachefs/fs-common.c index a4497eeb1f1b..96f7bbe0a3ed 100644 --- a/fs/bcachefs/fs-common.c +++ b/fs/bcachefs/fs-common.c @@ -76,11 +76,10 @@ int bch2_create_trans(struct btree_trans *trans, u64 dir_inum, } int bch2_link_trans(struct btree_trans *trans, u64 dir_inum, - u64 inum, struct bch_inode_unpacked *inode_u, - const struct qstr *name) + u64 inum, struct bch_inode_unpacked *dir_u, + struct bch_inode_unpacked *inode_u, const struct qstr *name) { struct btree_iter *dir_iter, *inode_iter; - struct bch_inode_unpacked dir_u; struct bch_hash_info dir_hash; u64 now = bch2_current_time(trans->c); @@ -91,18 +90,19 @@ int bch2_link_trans(struct btree_trans *trans, u64 dir_inum, inode_u->bi_ctime = now; bch2_inode_nlink_inc(inode_u); - dir_iter = bch2_inode_peek(trans, &dir_u, dir_inum, 0); + dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, 0); if (IS_ERR(dir_iter)) return PTR_ERR(dir_iter); - /* XXX: shouldn't we be updating mtime/ctime on the directory? */ + dir_u->bi_mtime = dir_u->bi_ctime = now; - dir_hash = bch2_hash_info_init(trans->c, &dir_u); + dir_hash = bch2_hash_info_init(trans->c, dir_u); bch2_trans_iter_put(trans, dir_iter); return bch2_dirent_create(trans, dir_inum, &dir_hash, mode_to_type(inode_u->bi_mode), name, inum, BCH_HASH_SET_MUST_CREATE) ?: + bch2_inode_write(trans, dir_iter, dir_u) ?: bch2_inode_write(trans, inode_iter, inode_u); } diff --git a/fs/bcachefs/fs-common.h b/fs/bcachefs/fs-common.h index c1621485a526..2273b7961c9b 100644 --- a/fs/bcachefs/fs-common.h +++ b/fs/bcachefs/fs-common.h @@ -14,6 +14,7 @@ int bch2_create_trans(struct btree_trans *, u64, int bch2_link_trans(struct btree_trans *, u64, u64, struct bch_inode_unpacked *, + struct bch_inode_unpacked *, const struct qstr *); int bch2_unlink_trans(struct btree_trans *, diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c index e8cdae3c114b..c20eaa7418c2 100644 --- a/fs/bcachefs/fs.c +++ b/fs/bcachefs/fs.c @@ -395,7 +395,7 @@ static int __bch2_link(struct bch_fs *c, struct dentry *dentry) { struct btree_trans trans; - struct bch_inode_unpacked inode_u; + struct bch_inode_unpacked dir_u, inode_u; int ret; mutex_lock(&inode->ei_update_lock); @@ -405,7 +405,7 @@ static int __bch2_link(struct bch_fs *c, bch2_trans_begin(&trans); ret = bch2_link_trans(&trans, dir->v.i_ino, - inode->v.i_ino, &inode_u, + inode->v.i_ino, &dir_u, &inode_u, &dentry->d_name) ?: bch2_trans_commit(&trans, NULL, &inode->ei_journal_seq, @@ -413,8 +413,14 @@ static int __bch2_link(struct bch_fs *c, BTREE_INSERT_NOUNLOCK); } while (ret == -EINTR); - if (likely(!ret)) + if (likely(!ret)) { + BUG_ON(inode_u.bi_inum != inode->v.i_ino); + + journal_seq_copy(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); + } bch2_trans_exit(&trans); mutex_unlock(&inode->ei_update_lock); diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 0f2308e53d65..3ae545b31c7a 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -80,7 +80,7 @@ static int reattach_inode(struct bch_fs *c, struct bch_inode_unpacked *lostfound_inode, u64 inum) { - struct bch_inode_unpacked inode_u; + struct bch_inode_unpacked dir_u, inode_u; char name_buf[20]; struct qstr name; int ret; @@ -92,7 +92,7 @@ static int reattach_inode(struct bch_fs *c, BTREE_INSERT_ATOMIC| BTREE_INSERT_LAZY_RW, bch2_link_trans(&trans, lostfound_inode->bi_inum, - inum, &inode_u, &name)); + inum, &dir_u, &inode_u, &name)); if (ret) bch_err(c, "error %i reattaching inode %llu", ret, inum);