---
fs/bcachefs/dirent.h | 5 +++++
fs/bcachefs/fs-common.c | 11 +++++++++++
fs/bcachefs/fs.c | 13 ++++++++-----
3 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/fs/bcachefs/dirent.h b/fs/bcachefs/dirent.h
index 24037e6e0a09..16b0c89970ac 100644
--- a/fs/bcachefs/dirent.h
+++ b/fs/bcachefs/dirent.h
@@ -32,6 +32,11 @@ static inline unsigned dirent_val_u64s(unsigned len)
sizeof(u64));
}
+static inline unsigned int dirent_occupied_size(const struct qstr *name)
+{
+ return (BKEY_U64s + dirent_val_u64s(name->len)) * sizeof(u64);
+}
+
int bch2_dirent_read_target(struct btree_trans *, subvol_inum,
struct bkey_s_c_dirent, subvol_inum *);
diff --git a/fs/bcachefs/fs-common.c b/fs/bcachefs/fs-common.c
index 508d029ac53d..2d5db8c530a2 100644
--- a/fs/bcachefs/fs-common.c
+++ b/fs/bcachefs/fs-common.c
@@ -153,6 +153,7 @@ int bch2_create_trans(struct btree_trans *trans,
if (is_subdir_for_nlink(new_inode))
dir_u->bi_nlink++;
dir_u->bi_mtime = dir_u->bi_ctime = now;
+ dir_u->bi_size += dirent_occupied_size(name);
ret = bch2_inode_write(trans, &dir_iter, dir_u);
if (ret)
@@ -217,6 +218,7 @@ int bch2_link_trans(struct btree_trans *trans,
}
dir_u->bi_mtime = dir_u->bi_ctime = now;
+ dir_u->bi_size += dirent_occupied_size(name);
dir_hash = bch2_hash_info_init(c, dir_u);
@@ -319,6 +321,7 @@ int bch2_unlink_trans(struct btree_trans *trans,
dir_u->bi_mtime = dir_u->bi_ctime = inode_u->bi_ctime = now;
dir_u->bi_nlink -= is_subdir_for_nlink(inode_u);
+ dir_u->bi_size -= dirent_occupied_size(name);
ret = bch2_hash_delete_at(trans, bch2_dirent_hash_desc,
&dir_hash, &dirent_iter,
@@ -457,6 +460,14 @@ int bch2_rename_trans(struct btree_trans *trans,
goto err;
}
+ if (mode == BCH_RENAME) {
+ src_dir_u->bi_size -= dirent_occupied_size(src_name);
+ dst_dir_u->bi_size += dirent_occupied_size(dst_name);
+ }
+
+ if (mode == BCH_RENAME_OVERWRITE)
+ src_dir_u->bi_size -= dirent_occupied_size(src_name);
+
if (src_inode_u->bi_parent_subvol)
src_inode_u->bi_parent_subvol = dst_dir.subvol;
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index fd01a5402c28..6c7496d40521 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -65,6 +65,9 @@ void bch2_inode_update_after_write(struct btree_trans *trans,
i_gid_write(&inode->v, bi->bi_gid);
inode->v.i_mode = bi->bi_mode;
+ if (fields & ATTR_SIZE)
+ i_size_write(&inode->v, bi->bi_size);
+
if (fields & ATTR_ATIME)
inode_set_atime_to_ts(&inode->v, bch2_time_to_timespec(c,
bi->bi_atime));
if (fields & ATTR_MTIME)
@@ -369,7 +372,7 @@ __bch2_create(struct mnt_idmap *idmap,
if (!(flags & BCH_CREATE_TMPFILE)) {
bch2_inode_update_after_write(trans, dir, &dir_u,
- ATTR_MTIME|ATTR_CTIME);
+ ATTR_MTIME|ATTR_CTIME|ATTR_SIZE);
mutex_unlock(&dir->ei_update_lock);
}
@@ -525,7 +528,7 @@ static int __bch2_link(struct bch_fs *c,
if (likely(!ret)) {
bch2_inode_update_after_write(trans, dir, &dir_u,
- ATTR_MTIME|ATTR_CTIME);
+ ATTR_MTIME|ATTR_CTIME|ATTR_SIZE);
bch2_inode_update_after_write(trans, inode, &inode_u,
ATTR_CTIME);
}
@@ -577,7 +580,7 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry,
goto err;
bch2_inode_update_after_write(trans, dir, &dir_u,
- ATTR_MTIME|ATTR_CTIME);
+ ATTR_MTIME|ATTR_CTIME|ATTR_SIZE);
bch2_inode_update_after_write(trans, inode, &inode_u,
ATTR_MTIME);
@@ -724,11 +727,11 @@ static int bch2_rename2(struct mnt_idmap *idmap,
dst_inode->v.i_ino != dst_inode_u.bi_inum);
bch2_inode_update_after_write(trans, src_dir, &src_dir_u,
- ATTR_MTIME|ATTR_CTIME);
+ ATTR_MTIME|ATTR_CTIME|ATTR_SIZE);
if (src_dir != dst_dir)
bch2_inode_update_after_write(trans, dst_dir, &dst_dir_u,
- ATTR_MTIME|ATTR_CTIME);
+ ATTR_MTIME|ATTR_CTIME|ATTR_SIZE);
bch2_inode_update_after_write(trans, src_inode, &src_inode_u,
ATTR_CTIME);
--
2.34.1