Add a sequence number for detecting races between when we read the io
path options and when we do the btree update with the new extent.

Signed-off-by: Kent Overstreet <[email protected]>
---
 fs/bcachefs/bcachefs.h | 2 ++
 fs/bcachefs/inode.c    | 2 ++
 fs/bcachefs/opts.c     | 4 ++++
 fs/bcachefs/opts.h     | 3 +++
 fs/bcachefs/xattr.c    | 3 +++
 5 files changed, 14 insertions(+)

diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
index 16d08dfb5f19..7eb8b8f37f95 100644
--- a/fs/bcachefs/bcachefs.h
+++ b/fs/bcachefs/bcachefs.h
@@ -807,6 +807,8 @@ struct bch_fs {
        struct bch_disk_groups_cpu __rcu *disk_groups;
 
        struct bch_opts         opts;
+       atomic_t                opt_change_cookie;
+
        unsigned                loglevel;
        unsigned                prev_loglevel;
 
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
index b7fcdb76483c..c1d673374e02 100644
--- a/fs/bcachefs/inode.c
+++ b/fs/bcachefs/inode.c
@@ -1239,6 +1239,8 @@ void bch2_inode_opts_get_inode(struct bch_fs *c,
        BCH_INODE_OPTS()
 #undef x
 
+       ret->opt_change_cookie = atomic_read(&c->opt_change_cookie);
+
        bch2_io_opts_fixups(ret);
 }
 
diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c
index 10d472d3e7d1..16d210cbc849 100644
--- a/fs/bcachefs/opts.c
+++ b/fs/bcachefs/opts.c
@@ -606,6 +606,8 @@ void bch2_opt_hook_post_set(struct bch_fs *c, struct 
bch_dev *ca, u64 inum,
        default:
                break;
        }
+
+       atomic_inc(&c->opt_change_cookie);
 }
 
 int bch2_parse_one_mount_opt(struct bch_fs *c, struct bch_opts *opts,
@@ -810,6 +812,8 @@ void bch2_inode_opts_get(struct bch_fs *c, struct 
bch_inode_opts *ret)
        BCH_INODE_OPTS()
 #undef x
 
+       ret->opt_change_cookie = atomic_read(&c->opt_change_cookie);
+
        bch2_io_opts_fixups(ret);
 }
 
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
index 9e0c73b7bd3a..2425ba247201 100644
--- a/fs/bcachefs/opts.h
+++ b/fs/bcachefs/opts.h
@@ -674,9 +674,12 @@ struct bch_inode_opts {
 #define x(_name, _bits)        u##_bits _name;
        BCH_INODE_OPTS()
 #undef x
+
 #define x(_name, _bits)        u64 _name##_from_inode:1;
        BCH_INODE_OPTS()
 #undef x
+
+       u32 opt_change_cookie;
 };
 
 static inline void bch2_io_opts_fixups(struct bch_inode_opts *opts)
diff --git a/fs/bcachefs/xattr.c b/fs/bcachefs/xattr.c
index 6d7303008b19..de72a735a49d 100644
--- a/fs/bcachefs/xattr.c
+++ b/fs/bcachefs/xattr.c
@@ -590,6 +590,9 @@ static int bch2_xattr_bcachefs_set(const struct 
xattr_handler *handler,
                }
 
                ret = bch2_write_inode(c, inode, inode_opt_set_fn, &s, 0);
+
+               if (!ret)
+                       atomic_inc(&c->opt_change_cookie);
        }
 err:
        return bch2_err_class(ret);
-- 
2.50.1


Reply via email to