Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
ba7c37d3
Commit
ba7c37d3
authored
1 year ago
by
Kent Overstreet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bcachefs: Stripe deletion now checks what it's deleting
Signed-off-by:
Kent Overstreet
<
kent.overstreet@linux.dev
>
parent
ebe8bd75
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
56 additions
and
16 deletions
+56
-16
fs/bcachefs/ec.c
fs/bcachefs/ec.c
+56
-16
No files found.
fs/bcachefs/ec.c
View file @
ba7c37d3
...
@@ -584,12 +584,12 @@ static int ec_stripe_mem_alloc(struct btree_trans *trans,
...
@@ -584,12 +584,12 @@ static int ec_stripe_mem_alloc(struct btree_trans *trans,
bch2_trans_relock
(
trans
);
bch2_trans_relock
(
trans
);
}
}
static
ssize_t
stripe_idx_to_delete
(
struct
bch_fs
*
c
)
static
u64
stripe_idx_to_delete
(
struct
bch_fs
*
c
)
{
{
ec_stripes_heap
*
h
=
&
c
->
ec_stripes_heap
;
ec_stripes_heap
*
h
=
&
c
->
ec_stripes_heap
;
return
h
->
used
&&
h
->
data
[
0
].
blocks_nonempty
==
0
return
h
->
used
&&
h
->
data
[
0
].
blocks_nonempty
==
0
?
h
->
data
[
0
].
idx
:
-
1
;
?
h
->
data
[
0
].
idx
:
0
;
}
}
static
inline
int
ec_stripes_heap_cmp
(
ec_stripes_heap
*
h
,
static
inline
int
ec_stripes_heap_cmp
(
ec_stripes_heap
*
h
,
...
@@ -674,41 +674,81 @@ void bch2_stripes_heap_update(struct bch_fs *c,
...
@@ -674,41 +674,81 @@ void bch2_stripes_heap_update(struct bch_fs *c,
heap_verify_backpointer
(
c
,
idx
);
heap_verify_backpointer
(
c
,
idx
);
if
(
stripe_idx_to_delete
(
c
)
>=
0
)
if
(
stripe_idx_to_delete
(
c
))
bch2_do_stripe_deletes
(
c
);
bch2_do_stripe_deletes
(
c
);
}
}
/* stripe deletion */
/* stripe deletion */
static
int
ec_stripe_delete
(
struct
b
ch_fs
*
c
,
size_t
idx
)
static
int
ec_stripe_delete
(
struct
b
tree_trans
*
trans
,
u64
idx
)
{
{
return
bch2_btree_delete_range
(
c
,
BTREE_ID_stripes
,
struct
bch_fs
*
c
=
trans
->
c
;
POS
(
0
,
idx
),
struct
btree_iter
iter
;
POS
(
0
,
idx
),
struct
bkey_s_c
k
;
0
,
NULL
);
struct
bkey_s_c_stripe
s
;
int
ret
;
bch2_trans_iter_init
(
trans
,
&
iter
,
BTREE_ID_stripes
,
POS
(
0
,
idx
),
BTREE_ITER_INTENT
);
k
=
bch2_btree_iter_peek_slot
(
&
iter
);
ret
=
bkey_err
(
k
);
if
(
ret
)
goto
err
;
if
(
k
.
k
->
type
!=
KEY_TYPE_stripe
)
{
bch2_fs_inconsistent
(
c
,
"attempting to delete nonexistent stripe %llu"
,
idx
);
ret
=
-
EINVAL
;
goto
err
;
}
s
=
bkey_s_c_to_stripe
(
k
);
for
(
unsigned
i
=
0
;
i
<
s
.
v
->
nr_blocks
;
i
++
)
if
(
stripe_blockcount_get
(
s
.
v
,
i
))
{
struct
printbuf
buf
=
PRINTBUF
;
bch2_bkey_val_to_text
(
&
buf
,
c
,
k
);
bch2_fs_inconsistent
(
c
,
"attempting to delete nonempty stripe %s"
,
buf
.
buf
);
printbuf_exit
(
&
buf
);
ret
=
-
EINVAL
;
goto
err
;
}
ret
=
bch2_btree_delete_at
(
trans
,
&
iter
,
0
);
err:
bch2_trans_iter_exit
(
trans
,
&
iter
);
return
ret
;
}
}
static
void
ec_stripe_delete_work
(
struct
work_struct
*
work
)
static
void
ec_stripe_delete_work
(
struct
work_struct
*
work
)
{
{
struct
bch_fs
*
c
=
struct
bch_fs
*
c
=
container_of
(
work
,
struct
bch_fs
,
ec_stripe_delete_work
);
container_of
(
work
,
struct
bch_fs
,
ec_stripe_delete_work
);
ssize_t
idx
;
struct
btree_trans
trans
;
int
ret
;
u64
idx
;
bch2_trans_init
(
&
trans
,
c
,
0
,
0
);
while
(
1
)
{
while
(
1
)
{
mutex_lock
(
&
c
->
ec_stripes_heap_lock
);
mutex_lock
(
&
c
->
ec_stripes_heap_lock
);
idx
=
stripe_idx_to_delete
(
c
);
idx
=
stripe_idx_to_delete
(
c
);
if
(
idx
<
0
)
{
if
(
idx
)
mutex_unlock
(
&
c
->
ec_stripes_heap_lock
);
break
;
}
bch2_stripes_heap_del
(
c
,
genradix_ptr
(
&
c
->
stripes
,
idx
),
idx
);
bch2_stripes_heap_del
(
c
,
genradix_ptr
(
&
c
->
stripes
,
idx
),
idx
);
mutex_unlock
(
&
c
->
ec_stripes_heap_lock
);
mutex_unlock
(
&
c
->
ec_stripes_heap_lock
);
if
(
ec_stripe_delete
(
c
,
idx
)
)
if
(
!
idx
)
break
;
break
;
ret
=
commit_do
(
&
trans
,
NULL
,
NULL
,
BTREE_INSERT_NOFAIL
,
ec_stripe_delete
(
&
trans
,
idx
));
if
(
ret
)
{
bch_err
(
c
,
"%s: err %s"
,
__func__
,
bch2_err_str
(
ret
));
break
;
}
}
}
bch2_trans_exit
(
&
trans
);
bch2_write_ref_put
(
c
,
BCH_WRITE_REF_stripe_delete
);
bch2_write_ref_put
(
c
,
BCH_WRITE_REF_stripe_delete
);
}
}
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment