mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-22 00:00:03 +03:00
Update bcachefs sources to 2834633e12 bcachefs: fix ioctls that set inode flags
This commit is contained in:
parent
fe2d5ef75f
commit
7c29c458db
@ -1 +1 @@
|
||||
ae6e8a59d33008f46bb801850840dbd0a7608bbc
|
||||
2834633e12dd6e8087f5f52742a3465a228998e5
|
||||
|
@ -40,14 +40,23 @@ static const unsigned bch_flags_to_xflags[] = {
|
||||
//[__BCH_INODE_PROJINHERIT] = FS_XFLAG_PROJINHERIT;
|
||||
};
|
||||
|
||||
#define map_flags(_map, _in) \
|
||||
({ \
|
||||
unsigned _i, _out = 0; \
|
||||
#define set_flags(_map, _in, _out) \
|
||||
do { \
|
||||
unsigned _i; \
|
||||
\
|
||||
for (_i = 0; _i < ARRAY_SIZE(_map); _i++) \
|
||||
if ((_in) & (1 << _i)) \
|
||||
(_out) |= _map[_i]; \
|
||||
(_out); \
|
||||
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) \
|
||||
@ -62,16 +71,12 @@ static const unsigned bch_flags_to_xflags[] = {
|
||||
(_out); \
|
||||
})
|
||||
|
||||
#define set_flags(_map, _in, _out) \
|
||||
do { \
|
||||
unsigned _i; \
|
||||
#define map_defined(_map) \
|
||||
({ \
|
||||
unsigned _in = ~0; \
|
||||
\
|
||||
for (_i = 0; _i < ARRAY_SIZE(_map); _i++) \
|
||||
if ((_in) & (1 << _i)) \
|
||||
(_out) |= _map[_i]; \
|
||||
else \
|
||||
(_out) &= ~_map[_i]; \
|
||||
} while (0)
|
||||
map_flags_rev(_map, _in); \
|
||||
})
|
||||
|
||||
/* Set VFS inode flags from bcachefs inode: */
|
||||
void bch2_inode_flags_to_vfs(struct bch_inode_info *inode)
|
||||
@ -79,6 +84,11 @@ 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;
|
||||
};
|
||||
|
||||
static int bch2_inode_flags_set(struct bch_inode_info *inode,
|
||||
struct bch_inode_unpacked *bi,
|
||||
void *p)
|
||||
@ -87,8 +97,9 @@ static int bch2_inode_flags_set(struct bch_inode_info *inode,
|
||||
* We're relying on btree locking here for exclusion with other ioctl
|
||||
* calls - use the flags in the btree (@bi), not inode->i_flags:
|
||||
*/
|
||||
unsigned newflags = *((unsigned *) p);
|
||||
unsigned oldflags = bi->bi_flags;
|
||||
struct flags_set *s = p;
|
||||
unsigned newflags = s->flags;
|
||||
unsigned oldflags = bi->bi_flags & s->mask;
|
||||
|
||||
if (((newflags ^ oldflags) & (BCH_INODE_APPEND|BCH_INODE_IMMUTABLE)) &&
|
||||
!capable(CAP_LINUX_IMMUTABLE))
|
||||
@ -99,7 +110,8 @@ static int bch2_inode_flags_set(struct bch_inode_info *inode,
|
||||
(newflags & (BCH_INODE_NODUMP|BCH_INODE_NOATIME)) != newflags)
|
||||
return -EINVAL;
|
||||
|
||||
bi->bi_flags = newflags;
|
||||
bi->bi_flags &= ~s->mask;
|
||||
bi->bi_flags |= newflags;
|
||||
inode->v.i_ctime = current_time(&inode->v);
|
||||
return 0;
|
||||
}
|
||||
@ -116,13 +128,14 @@ static int bch2_ioc_setflags(struct bch_fs *c,
|
||||
struct bch_inode_info *inode,
|
||||
void __user *arg)
|
||||
{
|
||||
unsigned flags, uflags;
|
||||
struct flags_set s = { .mask = map_defined(bch_flags_to_uflags) };
|
||||
unsigned uflags;
|
||||
int ret;
|
||||
|
||||
if (get_user(uflags, (int __user *) arg))
|
||||
return -EFAULT;
|
||||
|
||||
flags = map_flags_rev(bch_flags_to_uflags, uflags);
|
||||
s.flags = map_flags_rev(bch_flags_to_uflags, uflags);
|
||||
if (uflags)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@ -137,7 +150,7 @@ 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, &flags);
|
||||
ret = __bch2_write_inode(c, inode, bch2_inode_flags_set, &s);
|
||||
|
||||
if (!ret)
|
||||
bch2_inode_flags_to_vfs(inode);
|
||||
@ -187,14 +200,14 @@ static int bch2_ioc_fssetxattr(struct bch_fs *c,
|
||||
struct bch_inode_info *inode,
|
||||
struct fsxattr __user *arg)
|
||||
{
|
||||
struct flags_set s = { .mask = map_defined(bch_flags_to_xflags) };
|
||||
struct fsxattr fa;
|
||||
unsigned flags;
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(&fa, arg, sizeof(fa)))
|
||||
return -EFAULT;
|
||||
|
||||
flags = map_flags_rev(bch_flags_to_xflags, fa.fsx_xflags);
|
||||
s.flags = map_flags_rev(bch_flags_to_xflags, fa.fsx_xflags);
|
||||
if (fa.fsx_xflags)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@ -213,7 +226,7 @@ static int bch2_ioc_fssetxattr(struct bch_fs *c,
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
|
||||
ret = __bch2_write_inode(c, inode, bch2_inode_flags_set, &flags);
|
||||
ret = __bch2_write_inode(c, inode, bch2_inode_flags_set, &s);
|
||||
if (!ret)
|
||||
bch2_inode_flags_to_vfs(inode);
|
||||
err_unlock:
|
||||
|
@ -204,8 +204,8 @@ static int hash_check_key(const struct bch_hash_desc desc,
|
||||
"hash table key at wrong offset: %llu, "
|
||||
"hashed to %llu chain starts at %llu\n%s",
|
||||
k.k->p.offset, hashed, h->chain.pos.offset,
|
||||
bch2_bkey_val_to_text(c, bkey_type(0, desc.btree_id),
|
||||
buf, sizeof(buf), k))) {
|
||||
(bch2_bkey_val_to_text(c, bkey_type(0, desc.btree_id),
|
||||
buf, sizeof(buf), k), buf))) {
|
||||
ret = hash_redo_key(desc, h, c, k_iter, k, hashed);
|
||||
if (ret) {
|
||||
bch_err(c, "hash_redo_key err %i", ret);
|
||||
@ -224,8 +224,8 @@ static int hash_check_key(const struct bch_hash_desc desc,
|
||||
if (fsck_err_on(k2.k->type == desc.key_type &&
|
||||
!desc.cmp_bkey(k, k2), c,
|
||||
"duplicate hash table keys:\n%s",
|
||||
bch2_bkey_val_to_text(c, bkey_type(0, desc.btree_id),
|
||||
buf, sizeof(buf), k))) {
|
||||
(bch2_bkey_val_to_text(c, bkey_type(0, desc.btree_id),
|
||||
buf, sizeof(buf), k), buf))) {
|
||||
ret = bch2_hash_delete_at(desc, &h->info, &h->iter, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -356,13 +356,13 @@ static int check_dirents(struct bch_fs *c)
|
||||
|
||||
if (fsck_err_on(!w.have_inode, c,
|
||||
"dirent in nonexisting directory:\n%s",
|
||||
bch2_bkey_val_to_text(c, BTREE_ID_DIRENTS,
|
||||
buf, sizeof(buf), k)) ||
|
||||
(bch2_bkey_val_to_text(c, BTREE_ID_DIRENTS,
|
||||
buf, sizeof(buf), k), buf)) ||
|
||||
fsck_err_on(!S_ISDIR(w.inode.bi_mode), c,
|
||||
"dirent in non directory inode type %u:\n%s",
|
||||
mode_to_type(w.inode.bi_mode),
|
||||
bch2_bkey_val_to_text(c, BTREE_ID_DIRENTS,
|
||||
buf, sizeof(buf), k))) {
|
||||
(bch2_bkey_val_to_text(c, BTREE_ID_DIRENTS,
|
||||
buf, sizeof(buf), k), buf))) {
|
||||
ret = bch2_btree_delete_at(&iter, 0);
|
||||
if (ret)
|
||||
goto err;
|
||||
@ -404,8 +404,8 @@ static int check_dirents(struct bch_fs *c)
|
||||
|
||||
if (fsck_err_on(d_inum == d.k->p.inode, c,
|
||||
"dirent points to own directory:\n%s",
|
||||
bch2_bkey_val_to_text(c, BTREE_ID_DIRENTS,
|
||||
buf, sizeof(buf), k))) {
|
||||
(bch2_bkey_val_to_text(c, BTREE_ID_DIRENTS,
|
||||
buf, sizeof(buf), k), buf))) {
|
||||
ret = remove_dirent(c, &iter, d);
|
||||
if (ret)
|
||||
goto err;
|
||||
@ -421,8 +421,8 @@ static int check_dirents(struct bch_fs *c)
|
||||
|
||||
if (fsck_err_on(!have_target, c,
|
||||
"dirent points to missing inode:\n%s",
|
||||
bch2_bkey_val_to_text(c, BTREE_ID_DIRENTS,
|
||||
buf, sizeof(buf), k))) {
|
||||
(bch2_bkey_val_to_text(c, BTREE_ID_DIRENTS,
|
||||
buf, sizeof(buf), k), buf))) {
|
||||
ret = remove_dirent(c, &iter, d);
|
||||
if (ret)
|
||||
goto err;
|
||||
@ -434,8 +434,8 @@ static int check_dirents(struct bch_fs *c)
|
||||
mode_to_type(target.bi_mode), c,
|
||||
"incorrect d_type: should be %u:\n%s",
|
||||
mode_to_type(target.bi_mode),
|
||||
bch2_bkey_val_to_text(c, BTREE_ID_DIRENTS,
|
||||
buf, sizeof(buf), k))) {
|
||||
(bch2_bkey_val_to_text(c, BTREE_ID_DIRENTS,
|
||||
buf, sizeof(buf), k), buf))) {
|
||||
struct bkey_i_dirent *n;
|
||||
|
||||
n = kmalloc(bkey_bytes(d.k), GFP_KERNEL);
|
||||
|
Loading…
Reference in New Issue
Block a user