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
abbfc4db
Commit
abbfc4db
authored
Jul 16, 2024
by
Kent Overstreet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bcachefs: Add check for btree_path ref overflow
Signed-off-by:
Kent Overstreet
<
kent.overstreet@linux.dev
>
parent
094c6a9f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
31 additions
and
21 deletions
+31
-21
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_iter.c
+12
-12
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_iter.h
+18
-8
fs/bcachefs/btree_update.c
fs/bcachefs/btree_update.c
+1
-1
No files found.
fs/bcachefs/btree_iter.c
View file @
abbfc4db
...
@@ -1010,9 +1010,9 @@ static int bch2_btree_path_traverse_all(struct btree_trans *trans)
...
@@ -1010,9 +1010,9 @@ static int bch2_btree_path_traverse_all(struct btree_trans *trans)
* the same position:
* the same position:
*/
*/
if
(
trans
->
paths
[
idx
].
uptodate
)
{
if
(
trans
->
paths
[
idx
].
uptodate
)
{
__btree_path_get
(
&
trans
->
paths
[
idx
],
false
);
__btree_path_get
(
trans
,
&
trans
->
paths
[
idx
],
false
);
ret
=
bch2_btree_path_traverse_one
(
trans
,
idx
,
0
,
_THIS_IP_
);
ret
=
bch2_btree_path_traverse_one
(
trans
,
idx
,
0
,
_THIS_IP_
);
__btree_path_put
(
&
trans
->
paths
[
idx
],
false
);
__btree_path_put
(
trans
,
&
trans
->
paths
[
idx
],
false
);
if
(
bch2_err_matches
(
ret
,
BCH_ERR_transaction_restart
)
||
if
(
bch2_err_matches
(
ret
,
BCH_ERR_transaction_restart
)
||
bch2_err_matches
(
ret
,
ENOMEM
))
bch2_err_matches
(
ret
,
ENOMEM
))
...
@@ -1225,7 +1225,7 @@ static btree_path_idx_t btree_path_clone(struct btree_trans *trans, btree_path_i
...
@@ -1225,7 +1225,7 @@ static btree_path_idx_t btree_path_clone(struct btree_trans *trans, btree_path_i
{
{
btree_path_idx_t
new
=
btree_path_alloc
(
trans
,
src
);
btree_path_idx_t
new
=
btree_path_alloc
(
trans
,
src
);
btree_path_copy
(
trans
,
trans
->
paths
+
new
,
trans
->
paths
+
src
);
btree_path_copy
(
trans
,
trans
->
paths
+
new
,
trans
->
paths
+
src
);
__btree_path_get
(
trans
->
paths
+
new
,
intent
);
__btree_path_get
(
trans
,
trans
->
paths
+
new
,
intent
);
#ifdef TRACK_PATH_ALLOCATED
#ifdef TRACK_PATH_ALLOCATED
trans
->
paths
[
new
].
ip_allocated
=
ip
;
trans
->
paths
[
new
].
ip_allocated
=
ip
;
#endif
#endif
...
@@ -1236,7 +1236,7 @@ __flatten
...
@@ -1236,7 +1236,7 @@ __flatten
btree_path_idx_t
__bch2_btree_path_make_mut
(
struct
btree_trans
*
trans
,
btree_path_idx_t
__bch2_btree_path_make_mut
(
struct
btree_trans
*
trans
,
btree_path_idx_t
path
,
bool
intent
,
unsigned
long
ip
)
btree_path_idx_t
path
,
bool
intent
,
unsigned
long
ip
)
{
{
__btree_path_put
(
trans
->
paths
+
path
,
intent
);
__btree_path_put
(
trans
,
trans
->
paths
+
path
,
intent
);
path
=
btree_path_clone
(
trans
,
path
,
intent
,
ip
);
path
=
btree_path_clone
(
trans
,
path
,
intent
,
ip
);
trans
->
paths
[
path
].
preserve
=
false
;
trans
->
paths
[
path
].
preserve
=
false
;
return
path
;
return
path
;
...
@@ -1361,7 +1361,7 @@ void bch2_path_put(struct btree_trans *trans, btree_path_idx_t path_idx, bool in
...
@@ -1361,7 +1361,7 @@ void bch2_path_put(struct btree_trans *trans, btree_path_idx_t path_idx, bool in
{
{
struct
btree_path
*
path
=
trans
->
paths
+
path_idx
,
*
dup
;
struct
btree_path
*
path
=
trans
->
paths
+
path_idx
,
*
dup
;
if
(
!
__btree_path_put
(
path
,
intent
))
if
(
!
__btree_path_put
(
trans
,
path
,
intent
))
return
;
return
;
dup
=
path
->
preserve
dup
=
path
->
preserve
...
@@ -1392,7 +1392,7 @@ void bch2_path_put(struct btree_trans *trans, btree_path_idx_t path_idx, bool in
...
@@ -1392,7 +1392,7 @@ void bch2_path_put(struct btree_trans *trans, btree_path_idx_t path_idx, bool in
static
void
bch2_path_put_nokeep
(
struct
btree_trans
*
trans
,
btree_path_idx_t
path
,
static
void
bch2_path_put_nokeep
(
struct
btree_trans
*
trans
,
btree_path_idx_t
path
,
bool
intent
)
bool
intent
)
{
{
if
(
!
__btree_path_put
(
trans
->
paths
+
path
,
intent
))
if
(
!
__btree_path_put
(
trans
,
trans
->
paths
+
path
,
intent
))
return
;
return
;
__bch2_path_free
(
trans
,
path
);
__bch2_path_free
(
trans
,
path
);
...
@@ -1716,14 +1716,14 @@ btree_path_idx_t bch2_path_get(struct btree_trans *trans,
...
@@ -1716,14 +1716,14 @@ btree_path_idx_t bch2_path_get(struct btree_trans *trans,
trans
->
paths
[
path_pos
].
cached
==
cached
&&
trans
->
paths
[
path_pos
].
cached
==
cached
&&
trans
->
paths
[
path_pos
].
btree_id
==
btree_id
&&
trans
->
paths
[
path_pos
].
btree_id
==
btree_id
&&
trans
->
paths
[
path_pos
].
level
==
level
)
{
trans
->
paths
[
path_pos
].
level
==
level
)
{
__btree_path_get
(
trans
->
paths
+
path_pos
,
intent
);
__btree_path_get
(
trans
,
trans
->
paths
+
path_pos
,
intent
);
path_idx
=
bch2_btree_path_set_pos
(
trans
,
path_pos
,
pos
,
intent
,
ip
);
path_idx
=
bch2_btree_path_set_pos
(
trans
,
path_pos
,
pos
,
intent
,
ip
);
path
=
trans
->
paths
+
path_idx
;
path
=
trans
->
paths
+
path_idx
;
}
else
{
}
else
{
path_idx
=
btree_path_alloc
(
trans
,
path_pos
);
path_idx
=
btree_path_alloc
(
trans
,
path_pos
);
path
=
trans
->
paths
+
path_idx
;
path
=
trans
->
paths
+
path_idx
;
__btree_path_get
(
path
,
intent
);
__btree_path_get
(
trans
,
path
,
intent
);
path
->
pos
=
pos
;
path
->
pos
=
pos
;
path
->
btree_id
=
btree_id
;
path
->
btree_id
=
btree_id
;
path
->
cached
=
cached
;
path
->
cached
=
cached
;
...
@@ -2326,7 +2326,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
...
@@ -2326,7 +2326,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
* advance, same as on exit for iter->path, but only up
* advance, same as on exit for iter->path, but only up
* to snapshot
* to snapshot
*/
*/
__btree_path_get
(
trans
->
paths
+
iter
->
path
,
iter
->
flags
&
BTREE_ITER_intent
);
__btree_path_get
(
trans
,
trans
->
paths
+
iter
->
path
,
iter
->
flags
&
BTREE_ITER_intent
);
iter
->
update_path
=
iter
->
path
;
iter
->
update_path
=
iter
->
path
;
iter
->
update_path
=
bch2_btree_path_set_pos
(
trans
,
iter
->
update_path
=
bch2_btree_path_set_pos
(
trans
,
...
@@ -2911,9 +2911,9 @@ void bch2_trans_copy_iter(struct btree_iter *dst, struct btree_iter *src)
...
@@ -2911,9 +2911,9 @@ void bch2_trans_copy_iter(struct btree_iter *dst, struct btree_iter *src)
dst
->
ip_allocated
=
_RET_IP_
;
dst
->
ip_allocated
=
_RET_IP_
;
#endif
#endif
if
(
src
->
path
)
if
(
src
->
path
)
__btree_path_get
(
trans
->
paths
+
src
->
path
,
src
->
flags
&
BTREE_ITER_intent
);
__btree_path_get
(
trans
,
trans
->
paths
+
src
->
path
,
src
->
flags
&
BTREE_ITER_intent
);
if
(
src
->
update_path
)
if
(
src
->
update_path
)
__btree_path_get
(
trans
->
paths
+
src
->
update_path
,
src
->
flags
&
BTREE_ITER_intent
);
__btree_path_get
(
trans
,
trans
->
paths
+
src
->
update_path
,
src
->
flags
&
BTREE_ITER_intent
);
dst
->
key_cache_path
=
0
;
dst
->
key_cache_path
=
0
;
}
}
...
@@ -3237,7 +3237,7 @@ void bch2_trans_put(struct btree_trans *trans)
...
@@ -3237,7 +3237,7 @@ void bch2_trans_put(struct btree_trans *trans)
bch2_trans_unlock
(
trans
);
bch2_trans_unlock
(
trans
);
trans_for_each_update
(
trans
,
i
)
trans_for_each_update
(
trans
,
i
)
__btree_path_put
(
trans
->
paths
+
i
->
path
,
true
);
__btree_path_put
(
trans
,
trans
->
paths
+
i
->
path
,
true
);
trans
->
nr_updates
=
0
;
trans
->
nr_updates
=
0
;
check_btree_paths_leaked
(
trans
);
check_btree_paths_leaked
(
trans
);
...
...
fs/bcachefs/btree_iter.h
View file @
abbfc4db
...
@@ -6,6 +6,12 @@
...
@@ -6,6 +6,12 @@
#include "btree_types.h"
#include "btree_types.h"
#include "trace.h"
#include "trace.h"
void
bch2_trans_updates_to_text
(
struct
printbuf
*
,
struct
btree_trans
*
);
void
bch2_btree_path_to_text
(
struct
printbuf
*
,
struct
btree_trans
*
,
btree_path_idx_t
);
void
bch2_trans_paths_to_text
(
struct
printbuf
*
,
struct
btree_trans
*
);
void
bch2_dump_trans_updates
(
struct
btree_trans
*
);
void
bch2_dump_trans_paths_updates
(
struct
btree_trans
*
);
static
inline
int
__bkey_err
(
const
struct
bkey
*
k
)
static
inline
int
__bkey_err
(
const
struct
bkey
*
k
)
{
{
return
PTR_ERR_OR_ZERO
(
k
);
return
PTR_ERR_OR_ZERO
(
k
);
...
@@ -13,16 +19,26 @@ static inline int __bkey_err(const struct bkey *k)
...
@@ -13,16 +19,26 @@ static inline int __bkey_err(const struct bkey *k)
#define bkey_err(_k) __bkey_err((_k).k)
#define bkey_err(_k) __bkey_err((_k).k)
static
inline
void
__btree_path_get
(
struct
btree_path
*
path
,
bool
intent
)
static
inline
void
__btree_path_get
(
struct
btree_
trans
*
trans
,
struct
btree_
path
*
path
,
bool
intent
)
{
{
unsigned
idx
=
path
-
trans
->
paths
;
EBUG_ON
(
!
test_bit
(
idx
,
trans
->
paths_allocated
));
if
(
unlikely
(
path
->
ref
==
U8_MAX
))
{
bch2_dump_trans_paths_updates
(
trans
);
panic
(
"path %u refcount overflow
\n
"
,
idx
);
}
path
->
ref
++
;
path
->
ref
++
;
path
->
intent_ref
+=
intent
;
path
->
intent_ref
+=
intent
;
}
}
static
inline
bool
__btree_path_put
(
struct
btree_path
*
path
,
bool
intent
)
static
inline
bool
__btree_path_put
(
struct
btree_
trans
*
trans
,
struct
btree_
path
*
path
,
bool
intent
)
{
{
EBUG_ON
(
!
test_bit
(
path
-
trans
->
paths
,
trans
->
paths_allocated
));
EBUG_ON
(
!
path
->
ref
);
EBUG_ON
(
!
path
->
ref
);
EBUG_ON
(
!
path
->
intent_ref
&&
intent
);
EBUG_ON
(
!
path
->
intent_ref
&&
intent
);
path
->
intent_ref
-=
intent
;
path
->
intent_ref
-=
intent
;
return
--
path
->
ref
==
0
;
return
--
path
->
ref
==
0
;
}
}
...
@@ -894,12 +910,6 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans,
...
@@ -894,12 +910,6 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans,
_ret; \
_ret; \
})
})
void
bch2_trans_updates_to_text
(
struct
printbuf
*
,
struct
btree_trans
*
);
void
bch2_btree_path_to_text
(
struct
printbuf
*
,
struct
btree_trans
*
,
btree_path_idx_t
);
void
bch2_trans_paths_to_text
(
struct
printbuf
*
,
struct
btree_trans
*
);
void
bch2_dump_trans_updates
(
struct
btree_trans
*
);
void
bch2_dump_trans_paths_updates
(
struct
btree_trans
*
);
struct
btree_trans
*
__bch2_trans_get
(
struct
bch_fs
*
,
unsigned
);
struct
btree_trans
*
__bch2_trans_get
(
struct
bch_fs
*
,
unsigned
);
void
bch2_trans_put
(
struct
btree_trans
*
);
void
bch2_trans_put
(
struct
btree_trans
*
);
...
...
fs/bcachefs/btree_update.c
View file @
abbfc4db
...
@@ -449,7 +449,7 @@ bch2_trans_update_by_path(struct btree_trans *trans, btree_path_idx_t path_idx,
...
@@ -449,7 +449,7 @@ bch2_trans_update_by_path(struct btree_trans *trans, btree_path_idx_t path_idx,
}
}
}
}
__btree_path_get
(
trans
->
paths
+
i
->
path
,
true
);
__btree_path_get
(
trans
,
trans
->
paths
+
i
->
path
,
true
);
/*
/*
* If a key is present in the key cache, it must also exist in the
* If a key is present in the key cache, it must also exist in the
...
...
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