mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
bcachefs: Hook up RENAME_WHITEOUT in rename.
This is needed for overlayfs, which is used by container managers. Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
d90c8acd35
commit
4645855df0
@ -529,6 +529,12 @@ void bch2_set_btree_iter_dontneed(struct btree_iter *);
|
||||
|
||||
void *__bch2_trans_kmalloc(struct btree_trans *, size_t);
|
||||
|
||||
/**
|
||||
* bch2_trans_kmalloc - allocate memory for use by the current transaction
|
||||
*
|
||||
* Must be called after bch2_trans_begin, which on second and further calls
|
||||
* frees all memory allocated in this transaction
|
||||
*/
|
||||
static inline void *bch2_trans_kmalloc(struct btree_trans *trans, size_t size)
|
||||
{
|
||||
size = roundup(size, 8);
|
||||
|
@ -42,7 +42,8 @@ int bch2_create_trans(struct btree_trans *trans,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = bch2_inode_peek(trans, &dir_iter, dir_u, dir, BTREE_ITER_intent);
|
||||
ret = bch2_inode_peek(trans, &dir_iter, dir_u, dir,
|
||||
BTREE_ITER_intent|BTREE_ITER_with_updates);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@ -163,7 +164,7 @@ int bch2_create_trans(struct btree_trans *trans,
|
||||
name,
|
||||
dir_target,
|
||||
&dir_offset,
|
||||
STR_HASH_must_create);
|
||||
STR_HASH_must_create|BTREE_ITER_with_updates);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
@ -736,15 +736,16 @@ static int bch2_rename2(struct mnt_idmap *idmap,
|
||||
struct bch_inode_info *src_inode = to_bch_ei(src_dentry->d_inode);
|
||||
struct bch_inode_info *dst_inode = to_bch_ei(dst_dentry->d_inode);
|
||||
struct bch_inode_unpacked dst_dir_u, src_dir_u;
|
||||
struct bch_inode_unpacked src_inode_u, dst_inode_u;
|
||||
struct bch_inode_unpacked src_inode_u, dst_inode_u, *whiteout_inode_u;
|
||||
struct btree_trans *trans;
|
||||
enum bch_rename_mode mode = flags & RENAME_EXCHANGE
|
||||
? BCH_RENAME_EXCHANGE
|
||||
: dst_dentry->d_inode
|
||||
? BCH_RENAME_OVERWRITE : BCH_RENAME;
|
||||
bool whiteout = !!(flags & RENAME_WHITEOUT);
|
||||
int ret;
|
||||
|
||||
if (flags & ~(RENAME_NOREPLACE|RENAME_EXCHANGE))
|
||||
if (flags & ~(RENAME_NOREPLACE|RENAME_EXCHANGE|RENAME_WHITEOUT))
|
||||
return -EINVAL;
|
||||
|
||||
if (mode == BCH_RENAME_OVERWRITE) {
|
||||
@ -785,18 +786,48 @@ static int bch2_rename2(struct mnt_idmap *idmap,
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
retry:
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
ret = commit_do(trans, NULL, NULL, 0,
|
||||
bch2_rename_trans(trans,
|
||||
inode_inum(src_dir), &src_dir_u,
|
||||
inode_inum(dst_dir), &dst_dir_u,
|
||||
&src_inode_u,
|
||||
&dst_inode_u,
|
||||
&src_dentry->d_name,
|
||||
&dst_dentry->d_name,
|
||||
mode));
|
||||
ret = bch2_rename_trans(trans,
|
||||
inode_inum(src_dir), &src_dir_u,
|
||||
inode_inum(dst_dir), &dst_dir_u,
|
||||
&src_inode_u,
|
||||
&dst_inode_u,
|
||||
&src_dentry->d_name,
|
||||
&dst_dentry->d_name,
|
||||
mode);
|
||||
if (unlikely(ret))
|
||||
goto err_tx_restart;
|
||||
|
||||
if (whiteout) {
|
||||
whiteout_inode_u = bch2_trans_kmalloc_nomemzero(trans, sizeof(*whiteout_inode_u));
|
||||
ret = PTR_ERR_OR_ZERO(whiteout_inode_u);
|
||||
if (unlikely(ret))
|
||||
goto err_tx_restart;
|
||||
bch2_inode_init_early(c, whiteout_inode_u);
|
||||
|
||||
ret = bch2_create_trans(trans,
|
||||
inode_inum(src_dir), &src_dir_u,
|
||||
whiteout_inode_u,
|
||||
&src_dentry->d_name,
|
||||
from_kuid(i_user_ns(&src_dir->v), current_fsuid()),
|
||||
from_kgid(i_user_ns(&src_dir->v), current_fsgid()),
|
||||
S_IFCHR|WHITEOUT_MODE, 0,
|
||||
NULL, NULL, (subvol_inum) { 0 }, 0) ?:
|
||||
bch2_quota_acct(c, bch_qid(whiteout_inode_u), Q_INO, 1,
|
||||
KEY_TYPE_QUOTA_PREALLOC);
|
||||
if (unlikely(ret))
|
||||
goto err_tx_restart;
|
||||
}
|
||||
|
||||
ret = bch2_trans_commit(trans, NULL, NULL, 0);
|
||||
if (unlikely(ret)) {
|
||||
err_tx_restart:
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
goto retry;
|
||||
goto err;
|
||||
}
|
||||
|
||||
BUG_ON(src_inode->v.i_ino != src_inode_u.bi_inum);
|
||||
BUG_ON(dst_inode &&
|
||||
|
@ -270,7 +270,7 @@ int bch2_hash_set_in_snapshot(struct btree_trans *trans,
|
||||
desc.hash_bkey(info, bkey_i_to_s_c(insert)),
|
||||
snapshot),
|
||||
POS(insert->k.p.inode, U64_MAX),
|
||||
BTREE_ITER_slots|BTREE_ITER_intent, k, ret) {
|
||||
BTREE_ITER_slots|BTREE_ITER_intent|flags, k, ret) {
|
||||
if (is_visible_key(desc, inum, k)) {
|
||||
if (!desc.cmp_bkey(k, bkey_i_to_s_c(insert)))
|
||||
goto found;
|
||||
|
Loading…
Reference in New Issue
Block a user