diff --git a/.bcachefs_revision b/.bcachefs_revision index 7ea6a71d..d8ca95c6 100644 --- a/.bcachefs_revision +++ b/.bcachefs_revision @@ -1 +1 @@ -adfbb84c7c986f2f46f363d95bca33b4c470dad0 +a8faf2472b83bb675aceca3e43f20d232409b1cc diff --git a/cmd_migrate.c b/cmd_migrate.c index 7d15a08e..14532b6a 100644 --- a/cmd_migrate.c +++ b/cmd_migrate.c @@ -134,11 +134,12 @@ static void create_link(struct bch_fs *c, const char *name, u64 inum, mode_t mode) { struct qstr qstr = QSTR(name); + struct bch_inode_unpacked parent_u; struct bch_inode_unpacked inode; int ret = bch2_trans_do(c, NULL, BTREE_INSERT_ATOMIC, - bch2_link_trans(&trans, parent->bi_inum, - inum, &inode, &qstr)); + bch2_link_trans(&trans, parent->bi_inum, inum, + &parent_u, &inode, &qstr)); if (ret) die("error creating hardlink: %s", strerror(-ret)); } diff --git a/libbcachefs/fs-common.c b/libbcachefs/fs-common.c index a4497eeb..96f7bbe0 100644 --- a/libbcachefs/fs-common.c +++ b/libbcachefs/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/libbcachefs/fs-common.h b/libbcachefs/fs-common.h index c1621485..2273b796 100644 --- a/libbcachefs/fs-common.h +++ b/libbcachefs/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/libbcachefs/fs-io.c b/libbcachefs/fs-io.c index 160644cc..7f954a5d 100644 --- a/libbcachefs/fs-io.c +++ b/libbcachefs/fs-io.c @@ -2284,6 +2284,15 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr) ret = PTR_ERR_OR_ZERO(iter); bch2_trans_exit(&trans); + if (ret) + goto err; + + /* + * check this before next assertion; on filesystem error our normal + * invariants are a bit broken (truncate has to truncate the page cache + * before the inode). + */ + ret = bch2_journal_error(&c->journal); if (ret) goto err; diff --git a/libbcachefs/fs.c b/libbcachefs/fs.c index 6fc6d504..278c6d5b 100644 --- a/libbcachefs/fs.c +++ b/libbcachefs/fs.c @@ -379,7 +379,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); @@ -389,7 +389,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, @@ -397,8 +397,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/libbcachefs/fsck.c b/libbcachefs/fsck.c index 0f2308e5..3ae545b3 100644 --- a/libbcachefs/fsck.c +++ b/libbcachefs/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);