summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/acl.c3
-rw-r--r--fs/bcachefs/fs-io.c45
-rw-r--r--fs/bcachefs/fs-ioctl.c92
-rw-r--r--fs/bcachefs/fs-ioctl.h73
-rw-r--r--fs/bcachefs/fs.c32
-rw-r--r--fs/bcachefs/fs.h7
-rw-r--r--fs/bcachefs/xattr.c2
7 files changed, 130 insertions, 124 deletions
diff --git a/fs/bcachefs/acl.c b/fs/bcachefs/acl.c
index eaf5c8e138fb..7ee2022d9501 100644
--- a/fs/bcachefs/acl.c
+++ b/fs/bcachefs/acl.c
@@ -286,10 +286,9 @@ static int inode_update_for_set_acl_fn(struct bch_inode_info *inode,
void *p)
{
struct bch_fs *c = inode->v.i_sb->s_fs_info;
- struct timespec64 now = current_time(&inode->v);
umode_t mode = (unsigned long) p;
- bi->bi_ctime = timespec_to_bch2_time(c, now);
+ bi->bi_ctime = bch2_current_time(c);
bi->bi_mode = mode;
return 0;
}
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);
}
}
diff --git a/fs/bcachefs/fs-ioctl.c b/fs/bcachefs/fs-ioctl.c
index 895ccc79e782..a89786f295cf 100644
--- a/fs/bcachefs/fs-ioctl.c
+++ b/fs/bcachefs/fs-ioctl.c
@@ -12,79 +12,6 @@
#define FS_IOC_GOINGDOWN _IOR('X', 125, __u32)
-/* Inode flags: */
-
-/* bcachefs inode flags -> vfs inode flags: */
-static const unsigned bch_flags_to_vfs[] = {
- [__BCH_INODE_SYNC] = S_SYNC,
- [__BCH_INODE_IMMUTABLE] = S_IMMUTABLE,
- [__BCH_INODE_APPEND] = S_APPEND,
- [__BCH_INODE_NOATIME] = S_NOATIME,
-};
-
-/* bcachefs inode flags -> FS_IOC_GETFLAGS: */
-static const unsigned bch_flags_to_uflags[] = {
- [__BCH_INODE_SYNC] = FS_SYNC_FL,
- [__BCH_INODE_IMMUTABLE] = FS_IMMUTABLE_FL,
- [__BCH_INODE_APPEND] = FS_APPEND_FL,
- [__BCH_INODE_NODUMP] = FS_NODUMP_FL,
- [__BCH_INODE_NOATIME] = FS_NOATIME_FL,
-};
-
-/* bcachefs inode flags -> FS_IOC_FSGETXATTR: */
-static const unsigned bch_flags_to_xflags[] = {
- [__BCH_INODE_SYNC] = FS_XFLAG_SYNC,
- [__BCH_INODE_IMMUTABLE] = FS_XFLAG_IMMUTABLE,
- [__BCH_INODE_APPEND] = FS_XFLAG_APPEND,
- [__BCH_INODE_NODUMP] = FS_XFLAG_NODUMP,
- [__BCH_INODE_NOATIME] = FS_XFLAG_NOATIME,
- //[__BCH_INODE_PROJINHERIT] = FS_XFLAG_PROJINHERIT;
-};
-
-#define set_flags(_map, _in, _out) \
-do { \
- unsigned _i; \
- \
- for (_i = 0; _i < ARRAY_SIZE(_map); _i++) \
- if ((_in) & (1 << _i)) \
- (_out) |= _map[_i]; \
- else \
- (_out) &= ~_map[_i]; \
-} while (0)
-
-#define map_flags(_map, _in) \
-({ \
- unsigned _out = 0; \
- \
- set_flags(_map, _in, _out); \
- _out; \
-})
-
-#define map_flags_rev(_map, _in) \
-({ \
- unsigned _i, _out = 0; \
- \
- for (_i = 0; _i < ARRAY_SIZE(_map); _i++) \
- if ((_in) & _map[_i]) { \
- (_out) |= 1 << _i; \
- (_in) &= ~_map[_i]; \
- } \
- (_out); \
-})
-
-#define map_defined(_map) \
-({ \
- unsigned _in = ~0; \
- \
- map_flags_rev(_map, _in); \
-})
-
-/* Set VFS inode flags from bcachefs inode: */
-void bch2_inode_flags_to_vfs(struct bch_inode_info *inode)
-{
- set_flags(bch_flags_to_vfs, inode->ei_inode.bi_flags, inode->v.i_flags);
-}
-
struct flags_set {
unsigned mask;
unsigned flags;
@@ -96,6 +23,7 @@ static int bch2_inode_flags_set(struct bch_inode_info *inode,
struct bch_inode_unpacked *bi,
void *p)
{
+ struct bch_fs *c = inode->v.i_sb->s_fs_info;
/*
* We're relying on btree locking here for exclusion with other ioctl
* calls - use the flags in the btree (@bi), not inode->i_flags:
@@ -108,14 +36,15 @@ static int bch2_inode_flags_set(struct bch_inode_info *inode,
!capable(CAP_LINUX_IMMUTABLE))
return -EPERM;
- if (!S_ISREG(inode->v.i_mode) &&
- !S_ISDIR(inode->v.i_mode) &&
+ if (!S_ISREG(bi->bi_mode) &&
+ !S_ISDIR(bi->bi_mode) &&
(newflags & (BCH_INODE_NODUMP|BCH_INODE_NOATIME)) != newflags)
return -EINVAL;
bi->bi_flags &= ~s->mask;
bi->bi_flags |= newflags;
- inode_set_ctime_current(&inode->v);
+
+ bi->bi_ctime = timespec_to_bch2_time(c, current_time(&inode->v));
return 0;
}
@@ -153,10 +82,8 @@ static int bch2_ioc_setflags(struct bch_fs *c,
}
mutex_lock(&inode->ei_update_lock);
- ret = __bch2_write_inode(c, inode, bch2_inode_flags_set, &s, 0);
-
- if (!ret)
- bch2_inode_flags_to_vfs(inode);
+ ret = bch2_write_inode(c, inode, bch2_inode_flags_set, &s,
+ ATTR_CTIME);
mutex_unlock(&inode->ei_update_lock);
setflags_out:
@@ -242,9 +169,8 @@ static int bch2_ioc_fssetxattr(struct bch_fs *c,
if (ret)
goto err_unlock;
- ret = __bch2_write_inode(c, inode, fssetxattr_inode_update_fn, &s, 0);
- if (!ret)
- bch2_inode_flags_to_vfs(inode);
+ ret = bch2_write_inode(c, inode, fssetxattr_inode_update_fn, &s,
+ ATTR_CTIME);
err_unlock:
mutex_unlock(&inode->ei_update_lock);
err:
diff --git a/fs/bcachefs/fs-ioctl.h b/fs/bcachefs/fs-ioctl.h
index 2d117ef80ab2..f201980ef2c3 100644
--- a/fs/bcachefs/fs-ioctl.h
+++ b/fs/bcachefs/fs-ioctl.h
@@ -2,7 +2,78 @@
#ifndef _BCACHEFS_FS_IOCTL_H
#define _BCACHEFS_FS_IOCTL_H
-void bch2_inode_flags_to_vfs(struct bch_inode_info *);
+/* Inode flags: */
+
+/* bcachefs inode flags -> vfs inode flags: */
+static const unsigned bch_flags_to_vfs[] = {
+ [__BCH_INODE_SYNC] = S_SYNC,
+ [__BCH_INODE_IMMUTABLE] = S_IMMUTABLE,
+ [__BCH_INODE_APPEND] = S_APPEND,
+ [__BCH_INODE_NOATIME] = S_NOATIME,
+};
+
+/* bcachefs inode flags -> FS_IOC_GETFLAGS: */
+static const unsigned bch_flags_to_uflags[] = {
+ [__BCH_INODE_SYNC] = FS_SYNC_FL,
+ [__BCH_INODE_IMMUTABLE] = FS_IMMUTABLE_FL,
+ [__BCH_INODE_APPEND] = FS_APPEND_FL,
+ [__BCH_INODE_NODUMP] = FS_NODUMP_FL,
+ [__BCH_INODE_NOATIME] = FS_NOATIME_FL,
+};
+
+/* bcachefs inode flags -> FS_IOC_FSGETXATTR: */
+static const unsigned bch_flags_to_xflags[] = {
+ [__BCH_INODE_SYNC] = FS_XFLAG_SYNC,
+ [__BCH_INODE_IMMUTABLE] = FS_XFLAG_IMMUTABLE,
+ [__BCH_INODE_APPEND] = FS_XFLAG_APPEND,
+ [__BCH_INODE_NODUMP] = FS_XFLAG_NODUMP,
+ [__BCH_INODE_NOATIME] = FS_XFLAG_NOATIME,
+ //[__BCH_INODE_PROJINHERIT] = FS_XFLAG_PROJINHERIT;
+};
+
+#define set_flags(_map, _in, _out) \
+do { \
+ unsigned _i; \
+ \
+ for (_i = 0; _i < ARRAY_SIZE(_map); _i++) \
+ if ((_in) & (1 << _i)) \
+ (_out) |= _map[_i]; \
+ else \
+ (_out) &= ~_map[_i]; \
+} while (0)
+
+#define map_flags(_map, _in) \
+({ \
+ unsigned _out = 0; \
+ \
+ set_flags(_map, _in, _out); \
+ _out; \
+})
+
+#define map_flags_rev(_map, _in) \
+({ \
+ unsigned _i, _out = 0; \
+ \
+ for (_i = 0; _i < ARRAY_SIZE(_map); _i++) \
+ if ((_in) & _map[_i]) { \
+ (_out) |= 1 << _i; \
+ (_in) &= ~_map[_i]; \
+ } \
+ (_out); \
+})
+
+#define map_defined(_map) \
+({ \
+ unsigned _in = ~0; \
+ \
+ map_flags_rev(_map, _in); \
+})
+
+/* Set VFS inode flags from bcachefs inode: */
+static inline void bch2_inode_flags_to_vfs(struct bch_inode_info *inode)
+{
+ set_flags(bch_flags_to_vfs, inode->ei_inode.bi_flags, inode->v.i_flags);
+}
long bch2_fs_file_ioctl(struct file *, unsigned, unsigned long);
long bch2_compat_fs_ioctl(struct file *, unsigned, unsigned long);
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index 53107d02cbb6..2e2a5acae0eb 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -147,6 +147,8 @@ void bch2_inode_update_after_write(struct bch_fs *c,
inode->ei_inode = *bi;
inode->ei_qid = bch_qid(bi);
+
+ bch2_inode_flags_to_vfs(inode);
}
int __must_check bch2_write_inode_trans(struct btree_trans *trans,
@@ -187,10 +189,10 @@ int __must_check bch2_write_inode_trans(struct btree_trans *trans,
return 0;
}
-int __must_check __bch2_write_inode(struct bch_fs *c,
- struct bch_inode_info *inode,
- inode_set_fn set,
- void *p, unsigned fields)
+int __must_check bch2_write_inode(struct bch_fs *c,
+ struct bch_inode_info *inode,
+ inode_set_fn set,
+ void *p, unsigned fields)
{
struct btree_trans trans;
struct bch_inode_unpacked inode_u;
@@ -271,9 +273,8 @@ static int inode_update_for_create_fn(struct bch_inode_info *inode,
{
struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct bch_inode_unpacked *new_inode = p;
- struct timespec64 now = current_time(&inode->v);
- bi->bi_mtime = bi->bi_ctime = timespec_to_bch2_time(c, now);
+ bi->bi_mtime = bi->bi_ctime = bch2_current_time(c);
if (S_ISDIR(new_inode->bi_mode))
bi->bi_nlink++;
@@ -469,9 +470,8 @@ static int inode_update_for_link_fn(struct bch_inode_info *inode,
void *p)
{
struct bch_fs *c = inode->v.i_sb->s_fs_info;
- struct timespec64 now = current_time(&inode->v);
- bi->bi_ctime = timespec_to_bch2_time(c, now);
+ bi->bi_ctime = bch2_current_time(c);
if (bi->bi_flags & BCH_INODE_UNLINKED)
bi->bi_flags &= ~BCH_INODE_UNLINKED;
@@ -543,9 +543,8 @@ static int inode_update_dir_for_unlink_fn(struct bch_inode_info *inode,
{
struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct bch_inode_info *unlink_inode = p;
- struct timespec64 now = current_time(&inode->v);
- bi->bi_mtime = bi->bi_ctime = timespec_to_bch2_time(c, now);
+ bi->bi_mtime = bi->bi_ctime = bch2_current_time(c);
bi->bi_nlink -= S_ISDIR(unlink_inode->v.i_mode);
@@ -557,9 +556,8 @@ static int inode_update_for_unlink_fn(struct bch_inode_info *inode,
void *p)
{
struct bch_fs *c = inode->v.i_sb->s_fs_info;
- struct timespec64 now = current_time(&inode->v);
- bi->bi_ctime = timespec_to_bch2_time(c, now);
+ bi->bi_ctime = bch2_current_time(c);
if (bi->bi_nlink)
bi->bi_nlink--;
else
@@ -740,8 +738,6 @@ static int bch2_rename2(struct mnt_idmap *idmap,
{
struct bch_fs *c = src_vdir->i_sb->s_fs_info;
struct rename_info i = {
- .now = timespec_to_bch2_time(c,
- current_time(src_vdir)),
.src_dir = to_bch_ei(src_vdir),
.dst_dir = to_bch_ei(dst_vdir),
.src_inode = to_bch_ei(src_dentry->d_inode),
@@ -778,7 +774,7 @@ static int bch2_rename2(struct mnt_idmap *idmap,
bch2_trans_init(&trans, c);
retry:
bch2_trans_begin(&trans);
- i.now = timespec_to_bch2_time(c, current_time(src_vdir)),
+ i.now = bch2_current_time(c);
ret = bch2_dirent_rename(&trans,
i.src_dir, &src_dentry->d_name,
@@ -1271,8 +1267,6 @@ static void bch2_vfs_inode_init(struct bch_fs *c,
inode->ei_quota_reserved = 0;
inode->ei_str_hash = bch2_hash_info_init(c, bi);
- bch2_inode_flags_to_vfs(inode);
-
inode->v.i_mapping->a_ops = &bch_address_space_operations;
switch (inode->v.i_mode & S_IFMT) {
@@ -1346,8 +1340,8 @@ static int bch2_vfs_write_inode(struct inode *vinode,
int ret;
mutex_lock(&inode->ei_update_lock);
- ret = __bch2_write_inode(c, inode, inode_update_times_fn, NULL,
- ATTR_ATIME|ATTR_MTIME|ATTR_CTIME);
+ ret = bch2_write_inode(c, inode, inode_update_times_fn, NULL,
+ ATTR_ATIME|ATTR_MTIME|ATTR_CTIME);
mutex_unlock(&inode->ei_update_lock);
if (c->opts.journal_flush_disabled)
diff --git a/fs/bcachefs/fs.h b/fs/bcachefs/fs.h
index e8dd566285fc..4fdc11762cd7 100644
--- a/fs/bcachefs/fs.h
+++ b/fs/bcachefs/fs.h
@@ -2,6 +2,7 @@
#ifndef _BCACHEFS_FS_H
#define _BCACHEFS_FS_H
+#include "inode.h"
#include "opts.h"
#include "str_hash.h"
#include "quota_types.h"
@@ -81,10 +82,8 @@ int __must_check bch2_write_inode_trans(struct btree_trans *,
struct bch_inode_info *,
struct bch_inode_unpacked *,
inode_set_fn, void *);
-int __must_check __bch2_write_inode(struct bch_fs *, struct bch_inode_info *,
- inode_set_fn, void *, unsigned);
-int __must_check bch2_write_inode(struct bch_fs *,
- struct bch_inode_info *);
+int __must_check bch2_write_inode(struct bch_fs *, struct bch_inode_info *,
+ inode_set_fn, void *, unsigned);
void bch2_vfs_exit(void);
int bch2_vfs_init(void);
diff --git a/fs/bcachefs/xattr.c b/fs/bcachefs/xattr.c
index f0440d12a031..cb84bdabb6ed 100644
--- a/fs/bcachefs/xattr.c
+++ b/fs/bcachefs/xattr.c
@@ -436,7 +436,7 @@ static int bch2_xattr_bcachefs_set(const struct xattr_handler *handler,
}
mutex_lock(&inode->ei_update_lock);
- ret = __bch2_write_inode(c, inode, inode_opt_set_fn, &s, 0);
+ ret = bch2_write_inode(c, inode, inode_opt_set_fn, &s, 0);
mutex_unlock(&inode->ei_update_lock);
if (value &&