summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-07-02 14:14:36 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2020-05-06 17:14:16 -0400
commit3f78d3e2c442b54ad60d0f1c507f21144ea0a277 (patch)
tree1afb0bd03e8332bf4a68d449ce1ba446d9fd7fc1
parentea5715a73506eb929e43b66eb3b87c94e2b44ab4 (diff)
Merge with ebc9749562 bcachefs: Fix for building with old gcc
-rw-r--r--fs/bcachefs/bcachefs_format.h2
-rw-r--r--fs/bcachefs/bkey_methods.c3
-rw-r--r--fs/bcachefs/fs-ioctl.c4
-rw-r--r--fs/bcachefs/fs.c10
-rw-r--r--fs/bcachefs/fs.h34
5 files changed, 38 insertions, 15 deletions
diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h
index 362f9bc9b82c..13285936dd2d 100644
--- a/fs/bcachefs/bcachefs_format.h
+++ b/fs/bcachefs/bcachefs_format.h
@@ -848,7 +848,7 @@ static const unsigned BKEY_ALLOC_VAL_U64s_MAX =
BCH_ALLOC_FIELDS(), sizeof(u64));
#undef x
-static const unsigned BKEY_ALLOC_U64s_MAX = BKEY_U64s + BKEY_ALLOC_VAL_U64s_MAX;
+#define BKEY_ALLOC_U64s_MAX (BKEY_U64s + BKEY_ALLOC_VAL_U64s_MAX)
/* Quotas: */
diff --git a/fs/bcachefs/bkey_methods.c b/fs/bcachefs/bkey_methods.c
index 09ee958c5568..27f196ef0b18 100644
--- a/fs/bcachefs/bkey_methods.c
+++ b/fs/bcachefs/bkey_methods.c
@@ -90,6 +90,9 @@ const char *__bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
if (btree_node_type_is_extents(type)) {
if ((k.k->size == 0) != bkey_deleted(k.k))
return "bad size field";
+
+ if (k.k->size > k.k->p.offset)
+ return "size greater than offset";
} else {
if (k.k->size)
return "nonzero size field";
diff --git a/fs/bcachefs/fs-ioctl.c b/fs/bcachefs/fs-ioctl.c
index 971744ba3bf9..e80576f5a980 100644
--- a/fs/bcachefs/fs-ioctl.c
+++ b/fs/bcachefs/fs-ioctl.c
@@ -205,7 +205,7 @@ static int bch2_ioc_reinherit_attrs(struct bch_fs *c,
if (ret)
goto err2;
- bch2_lock_inodes(src, dst);
+ bch2_lock_inodes(INODE_UPDATE_LOCK, src, dst);
if (inode_attr_changing(src, dst, Inode_opt_project)) {
ret = bch2_fs_quota_transfer(c, dst,
@@ -218,7 +218,7 @@ static int bch2_ioc_reinherit_attrs(struct bch_fs *c,
ret = bch2_write_inode(c, dst, bch2_reinherit_attrs_fn, src, 0);
err3:
- bch2_unlock_inodes(src, dst);
+ bch2_unlock_inodes(INODE_UPDATE_LOCK, src, dst);
/* return true if we did work */
if (ret >= 0)
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index c70c723f8518..9ce72815d1c8 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -594,7 +594,7 @@ static int bch2_unlink(struct inode *vdir, struct dentry *dentry)
struct btree_trans trans;
int ret;
- bch2_lock_inodes(dir, inode);
+ bch2_lock_inodes(INODE_UPDATE_LOCK, dir, inode);
bch2_trans_init(&trans, c, 4, 1024);
retry:
bch2_trans_begin(&trans);
@@ -627,7 +627,7 @@ retry:
ATTR_MTIME);
err:
bch2_trans_exit(&trans);
- bch2_unlock_inodes(dir, inode);
+ bch2_unlock_inodes(INODE_UPDATE_LOCK, dir, inode);
return ret;
}
@@ -804,7 +804,8 @@ static int bch2_rename2(struct inode *src_vdir, struct dentry *src_dentry,
bch2_trans_init(&trans, c, 8, 2048);
- bch2_lock_inodes(i.src_dir,
+ bch2_lock_inodes(INODE_UPDATE_LOCK,
+ i.src_dir,
i.dst_dir,
i.src_inode,
i.dst_inode);
@@ -902,7 +903,8 @@ err:
1 << QTYP_PRJ,
KEY_TYPE_QUOTA_NOCHECK);
- bch2_unlock_inodes(i.src_dir,
+ bch2_unlock_inodes(INODE_UPDATE_LOCK,
+ i.src_dir,
i.dst_dir,
i.src_inode,
i.dst_inode);
diff --git a/fs/bcachefs/fs.h b/fs/bcachefs/fs.h
index fad8f4e5fdfc..226223b058a9 100644
--- a/fs/bcachefs/fs.h
+++ b/fs/bcachefs/fs.h
@@ -36,24 +36,42 @@ static inline int ptrcmp(void *l, void *r)
return cmp_int(l, r);
}
-#define __bch2_lock_inodes(_lock, ...) \
+enum bch_inode_lock_op {
+ INODE_LOCK = (1U << 0),
+ INODE_UPDATE_LOCK = (1U << 1),
+};
+
+#define bch2_lock_inodes(_locks, ...) \
do { \
struct bch_inode_info *a[] = { NULL, __VA_ARGS__ }; \
unsigned i; \
\
- bubble_sort(&a[1], ARRAY_SIZE(a) - 1 , ptrcmp); \
+ bubble_sort(&a[1], ARRAY_SIZE(a) - 1, ptrcmp); \
\
- for (i = ARRAY_SIZE(a) - 1; a[i]; --i) \
+ for (i = 1; i < ARRAY_SIZE(a); i++) \
if (a[i] != a[i - 1]) { \
- if (_lock) \
+ if (_locks & INODE_LOCK) \
+ down_write_nested(&a[i]->v.i_rwsem, i); \
+ if (_locks & INODE_UPDATE_LOCK) \
mutex_lock_nested(&a[i]->ei_update_lock, i);\
- else \
- mutex_unlock(&a[i]->ei_update_lock); \
} \
} while (0)
-#define bch2_lock_inodes(...) __bch2_lock_inodes(true, __VA_ARGS__)
-#define bch2_unlock_inodes(...) __bch2_lock_inodes(false, __VA_ARGS__)
+#define bch2_unlock_inodes(_locks, ...) \
+do { \
+ struct bch_inode_info *a[] = { NULL, __VA_ARGS__ }; \
+ unsigned i; \
+ \
+ bubble_sort(&a[1], ARRAY_SIZE(a) - 1, ptrcmp); \
+ \
+ for (i = 1; i < ARRAY_SIZE(a); i++) \
+ if (a[i] != a[i - 1]) { \
+ if (_locks & INODE_LOCK) \
+ up_write(&a[i]->v.i_rwsem); \
+ if (_locks & INODE_UPDATE_LOCK) \
+ mutex_unlock(&a[i]->ei_update_lock); \
+ } \
+} while (0)
static inline struct bch_inode_info *file_bch_inode(struct file *file)
{