summaryrefslogtreecommitdiff
path: root/fs/bcachefs/fs-io.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-07-17 14:12:42 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:07 -0400
commit2ea9004864b918be34e742e38fb08d868600d020 (patch)
treeecfc0db344695321f68b80b96ca3b6465753d6b0 /fs/bcachefs/fs-io.c
parent4e1ec2cc0d82f1d4344e7b5a53229c9ccde8437d (diff)
downloadlwn-2ea9004864b918be34e742e38fb08d868600d020.tar.gz
lwn-2ea9004864b918be34e742e38fb08d868600d020.zip
bcachefs: Fix mtime/ctime updates
Also make inode flags consistent with how the rest of the inode is updated Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/fs-io.c')
-rw-r--r--fs/bcachefs/fs-io.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index 29d289b0dfa5..33c379ecf5a1 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -177,23 +177,40 @@ static int bch2_quota_reservation_add(struct bch_fs *c,
/* i_size updates: */
+struct inode_new_size {
+ loff_t new_size;
+ u64 now;
+ unsigned fields;
+};
+
static int inode_set_size(struct bch_inode_info *inode,
struct bch_inode_unpacked *bi,
void *p)
{
- loff_t *new_i_size = p;
+ struct inode_new_size *s = p;
- lockdep_assert_held(&inode->ei_update_lock);
+ bi->bi_size = s->new_size;
+ if (s->fields & ATTR_ATIME)
+ bi->bi_atime = s->now;
+ if (s->fields & ATTR_MTIME)
+ bi->bi_mtime = s->now;
+ if (s->fields & ATTR_CTIME)
+ bi->bi_ctime = s->now;
- bi->bi_size = *new_i_size;
return 0;
}
static int __must_check bch2_write_inode_size(struct bch_fs *c,
struct bch_inode_info *inode,
- loff_t new_size)
+ loff_t new_size, unsigned fields)
{
- return __bch2_write_inode(c, inode, inode_set_size, &new_size, 0);
+ struct inode_new_size s = {
+ .new_size = new_size,
+ .now = bch2_current_time(c),
+ .fields = fields,
+ };
+
+ return bch2_write_inode(c, inode, inode_set_size, &s, fields);
}
static void i_sectors_acct(struct bch_fs *c, struct bch_inode_info *inode,
@@ -241,6 +258,7 @@ static int i_sectors_dirty_finish_fn(struct bch_inode_info *inode,
struct bch_inode_unpacked *bi,
void *p)
{
+ struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct i_sectors_hook *h = p;
if (h->new_i_size != U64_MAX &&
@@ -249,6 +267,7 @@ static int i_sectors_dirty_finish_fn(struct bch_inode_info *inode,
bi->bi_size = h->new_i_size;
bi->bi_sectors += h->sectors;
bi->bi_flags &= ~h->flags;
+ bi->bi_mtime = bi->bi_ctime = bch2_current_time(c);
return 0;
}
@@ -259,7 +278,7 @@ static int i_sectors_dirty_finish(struct bch_fs *c, struct i_sectors_hook *h)
mutex_lock(&h->inode->ei_update_lock);
i_sectors_acct(c, h->inode, &h->quota_res, h->sectors);
- ret = __bch2_write_inode(c, h->inode, i_sectors_dirty_finish_fn, h, 0);
+ ret = bch2_write_inode(c, h->inode, i_sectors_dirty_finish_fn, h, 0);
if (!ret && h->new_i_size != U64_MAX)
i_size_write(&h->inode->v, h->new_i_size);
@@ -289,7 +308,7 @@ static int i_sectors_dirty_start(struct bch_fs *c, struct i_sectors_hook *h)
int ret;
mutex_lock(&h->inode->ei_update_lock);
- ret = __bch2_write_inode(c, h->inode, i_sectors_dirty_start_fn, h, 0);
+ ret = bch2_write_inode(c, h->inode, i_sectors_dirty_start_fn, h, 0);
mutex_unlock(&h->inode->ei_update_lock);
return ret;
@@ -2223,9 +2242,8 @@ static int bch2_extend(struct bch_inode_info *inode, struct iattr *iattr)
setattr_copy(NULL, &inode->v, iattr);
mutex_lock(&inode->ei_update_lock);
- inode_set_ctime_current(&inode->v);
- inode->v.i_mtime = inode_get_ctime(&inode->v);
- ret = bch2_write_inode_size(c, inode, inode->v.i_size);
+ ret = bch2_write_inode_size(c, inode, inode->v.i_size,
+ ATTR_MTIME|ATTR_CTIME);
mutex_unlock(&inode->ei_update_lock);
return ret;
@@ -2284,8 +2302,6 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
/* ATTR_MODE will never be set here, ns argument isn't needed: */
setattr_copy(NULL, &inode->v, iattr);
- inode_set_ctime_current(&inode->v);
- inode->v.i_mtime = inode_get_ctime(&inode->v);
out:
ret = i_sectors_dirty_finish(c, &i_sectors_hook) ?: ret;
err_put_pagecache:
@@ -2617,7 +2633,7 @@ btree_iter_err:
i_size_write(&inode->v, end);
mutex_lock(&inode->ei_update_lock);
- ret = bch2_write_inode_size(c, inode, inode->v.i_size);
+ ret = bch2_write_inode_size(c, inode, inode->v.i_size, 0);
mutex_unlock(&inode->ei_update_lock);
}
@@ -2633,7 +2649,8 @@ btree_iter_err:
if (inode->ei_inode.bi_size != inode->v.i_size) {
mutex_lock(&inode->ei_update_lock);
- ret = bch2_write_inode_size(c, inode, inode->v.i_size);
+ ret = bch2_write_inode_size(c, inode,
+ inode->v.i_size, 0);
mutex_unlock(&inode->ei_update_lock);
}
}