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