summaryrefslogtreecommitdiff
path: root/libbcachefs
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs')
-rw-r--r--libbcachefs/fs-common.c12
-rw-r--r--libbcachefs/fs-common.h1
-rw-r--r--libbcachefs/fs-io.c9
-rw-r--r--libbcachefs/fs.c12
-rw-r--r--libbcachefs/fsck.c4
5 files changed, 27 insertions, 11 deletions
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
@@ -2287,6 +2287,15 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
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;
+
BUG_ON(inode->v.i_size < inode_u.bi_size);
if (iattr->ia_size > inode->v.i_size) {
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);