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
6bd13057
Commit
6bd13057
authored
Mar 31, 2019
by
Kent Overstreet
Committed by
Kent Overstreet
Oct 22, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bcachefs: Fsck locking improvements
Signed-off-by:
Kent Overstreet
<
kent.overstreet@linux.dev
>
parent
36e916e1
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
83 additions
and
57 deletions
+83
-57
fs/bcachefs/dirent.c
fs/bcachefs/dirent.c
+13
-6
fs/bcachefs/dirent.h
fs/bcachefs/dirent.h
+1
-0
fs/bcachefs/fsck.c
fs/bcachefs/fsck.c
+48
-32
fs/bcachefs/inode.c
fs/bcachefs/inode.c
+18
-17
fs/bcachefs/inode.h
fs/bcachefs/inode.h
+3
-2
No files found.
fs/bcachefs/dirent.c
View file @
6bd13057
...
...
@@ -329,17 +329,18 @@ u64 bch2_dirent_lookup(struct bch_fs *c, u64 dir_inum,
return
inum
;
}
int
bch2_empty_dir
(
struct
bch_fs
*
c
,
u64
dir_inum
)
int
bch2_empty_dir
_trans
(
struct
btree_trans
*
trans
,
u64
dir_inum
)
{
struct
btree_trans
trans
;
struct
btree_iter
*
iter
;
struct
bkey_s_c
k
;
int
ret
=
0
;
bch2_trans_init
(
&
trans
,
c
);
iter
=
bch2_trans_get_iter
(
trans
,
BTREE_ID_DIRENTS
,
POS
(
dir_inum
,
0
),
0
);
if
(
IS_ERR
(
iter
))
return
PTR_ERR
(
iter
);
for_each_btree_key
(
&
trans
,
iter
,
BTREE_ID_DIRENTS
,
POS
(
dir_inum
,
0
),
0
,
k
)
{
for_each_btree_key_continue
(
iter
,
0
,
k
)
{
if
(
k
.
k
->
p
.
inode
>
dir_inum
)
break
;
...
...
@@ -348,11 +349,17 @@ int bch2_empty_dir(struct bch_fs *c, u64 dir_inum)
break
;
}
}
bch2_trans_
exit
(
&
trans
);
bch2_trans_
iter_put
(
trans
,
iter
);
return
ret
;
}
int
bch2_empty_dir
(
struct
bch_fs
*
c
,
u64
dir_inum
)
{
return
bch2_trans_do
(
c
,
NULL
,
0
,
bch2_empty_dir_trans
(
&
trans
,
dir_inum
));
}
int
bch2_readdir
(
struct
bch_fs
*
c
,
struct
file
*
file
,
struct
dir_context
*
ctx
)
{
...
...
fs/bcachefs/dirent.h
View file @
6bd13057
...
...
@@ -55,6 +55,7 @@ int bch2_dirent_rename(struct btree_trans *,
u64
bch2_dirent_lookup
(
struct
bch_fs
*
,
u64
,
const
struct
bch_hash_info
*
,
const
struct
qstr
*
);
int
bch2_empty_dir_trans
(
struct
btree_trans
*
,
u64
);
int
bch2_empty_dir
(
struct
bch_fs
*
,
u64
);
int
bch2_readdir
(
struct
bch_fs
*
,
struct
file
*
,
struct
dir_context
*
);
...
...
fs/bcachefs/fsck.c
View file @
6bd13057
...
...
@@ -128,18 +128,21 @@ static struct inode_walker inode_walker_init(void)
};
}
static
int
walk_inode
(
struct
bch_fs
*
c
,
struct
inode_walker
*
w
,
u64
inum
)
static
int
walk_inode
(
struct
btree_trans
*
trans
,
struct
inode_walker
*
w
,
u64
inum
)
{
w
->
first_this_inode
=
inum
!=
w
->
cur_inum
;
w
->
cur_inum
=
inum
;
if
(
w
->
first_this_inode
)
{
int
ret
=
bch2_inode_find_by_inum
(
c
,
inum
,
&
w
->
inode
);
if
(
inum
!=
w
->
cur_inum
)
{
int
ret
=
bch2_inode_find_by_inum_trans
(
trans
,
inum
,
&
w
->
inode
);
if
(
ret
&&
ret
!=
-
ENOENT
)
return
ret
;
w
->
have_inode
=
!
ret
;
w
->
have_inode
=
!
ret
;
w
->
cur_inum
=
inum
;
w
->
first_this_inode
=
true
;
}
else
{
w
->
first_this_inode
=
false
;
}
return
0
;
...
...
@@ -445,12 +448,15 @@ static int check_extents(struct bch_fs *c)
int
ret
=
0
;
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
bch_verbose
(
c
,
"checking extents"
);
for_each_btree_key
(
&
trans
,
iter
,
BTREE_ID_EXTENTS
,
POS
(
BCACHEFS_ROOT_INO
,
0
),
0
,
k
)
{
ret
=
walk_inode
(
c
,
&
w
,
k
.
k
->
p
.
inode
);
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_EXTENTS
,
POS
(
BCACHEFS_ROOT_INO
,
0
),
0
);
retry:
for_each_btree_key_continue
(
iter
,
0
,
k
)
{
ret
=
walk_inode
(
&
trans
,
&
w
,
k
.
k
->
p
.
inode
);
if
(
ret
)
break
;
...
...
@@ -515,6 +521,8 @@ static int check_extents(struct bch_fs *c)
}
err:
fsck_err:
if
(
ret
==
-
EINTR
)
goto
retry
;
return
bch2_trans_exit
(
&
trans
)
?:
ret
;
}
...
...
@@ -537,21 +545,20 @@ static int check_dirents(struct bch_fs *c)
bch_verbose
(
c
,
"checking dirents"
);
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_DIRENTS
,
POS
(
BCACHEFS_ROOT_INO
,
0
),
0
);
hash_check_init
(
&
h
);
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_DIRENTS
,
POS
(
BCACHEFS_ROOT_INO
,
0
),
0
);
retry:
for_each_btree_key_continue
(
iter
,
0
,
k
)
{
struct
bkey_s_c_dirent
d
;
struct
bch_inode_unpacked
target
;
bool
have_target
;
u64
d_inum
;
ret
=
walk_inode
(
c
,
&
w
,
k
.
k
->
p
.
inode
);
ret
=
walk_inode
(
&
trans
,
&
w
,
k
.
k
->
p
.
inode
);
if
(
ret
)
break
;
...
...
@@ -620,7 +627,7 @@ static int check_dirents(struct bch_fs *c)
continue
;
}
ret
=
bch2_inode_find_by_inum
(
c
,
d_inum
,
&
target
);
ret
=
bch2_inode_find_by_inum
_trans
(
&
trans
,
d_inum
,
&
target
);
if
(
ret
&&
ret
!=
-
ENOENT
)
break
;
...
...
@@ -671,6 +678,9 @@ static int check_dirents(struct bch_fs *c)
hash_stop_chain
(
&
trans
,
&
h
);
err:
fsck_err:
if
(
ret
==
-
EINTR
)
goto
retry
;
return
bch2_trans_exit
(
&
trans
)
?:
ret
;
}
...
...
@@ -689,17 +699,16 @@ static int check_xattrs(struct bch_fs *c)
bch_verbose
(
c
,
"checking xattrs"
);
bch2_trans_init
(
&
trans
,
c
);
hash_check_init
(
&
h
);
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_XATTRS
,
POS
(
BCACHEFS_ROOT_INO
,
0
),
0
);
hash_check_init
(
&
h
);
retry:
for_each_btree_key_continue
(
iter
,
0
,
k
)
{
ret
=
walk_inode
(
c
,
&
w
,
k
.
k
->
p
.
inode
);
ret
=
walk_inode
(
&
trans
,
&
w
,
k
.
k
->
p
.
inode
);
if
(
ret
)
break
;
...
...
@@ -722,6 +731,8 @@ static int check_xattrs(struct bch_fs *c)
}
err:
fsck_err:
if
(
ret
==
-
EINTR
)
goto
retry
;
return
bch2_trans_exit
(
&
trans
)
?:
ret
;
}
...
...
@@ -905,6 +916,7 @@ static int check_directory_structure(struct bch_fs *c,
int
ret
=
0
;
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
bch_verbose
(
c
,
"checking directory structure"
);
...
...
@@ -919,9 +931,8 @@ static int check_directory_structure(struct bch_fs *c,
}
ret
=
path_down
(
&
path
,
BCACHEFS_ROOT_INO
);
if
(
ret
)
{
return
ret
;
}
if
(
ret
)
goto
err
;
while
(
path
.
nr
)
{
next:
...
...
@@ -983,14 +994,19 @@ static int check_directory_structure(struct bch_fs *c,
path
.
nr
--
;
}
for_each_btree_key
(
&
trans
,
iter
,
BTREE_ID_INODES
,
POS_MIN
,
0
,
k
)
{
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_INODES
,
POS_MIN
,
0
);
retry:
for_each_btree_key_continue
(
iter
,
0
,
k
)
{
if
(
k
.
k
->
type
!=
KEY_TYPE_inode
)
continue
;
if
(
!
S_ISDIR
(
le16_to_cpu
(
bkey_s_c_to_inode
(
k
).
v
->
bi_mode
)))
continue
;
if
(
!
bch2_empty_dir
(
c
,
k
.
k
->
p
.
inode
))
ret
=
bch2_empty_dir_trans
(
&
trans
,
k
.
k
->
p
.
inode
);
if
(
ret
==
-
EINTR
)
goto
retry
;
if
(
!
ret
)
continue
;
if
(
fsck_err_on
(
!
inode_bitmap_test
(
&
dirs_done
,
k
.
k
->
p
.
inode
),
c
,
...
...
@@ -1018,15 +1034,12 @@ static int check_directory_structure(struct bch_fs *c,
memset
(
&
path
,
0
,
sizeof
(
path
));
goto
restart_dfs
;
}
out:
kfree
(
dirs_done
.
bits
);
kfree
(
path
.
entries
);
return
ret
;
err:
fsck_err:
ret
=
bch2_trans_exit
(
&
trans
)
?:
ret
;
goto
out
;
kfree
(
dirs_done
.
bits
);
kfree
(
path
.
entries
);
return
ret
;
}
struct
nlink
{
...
...
@@ -1070,6 +1083,7 @@ static int bch2_gc_walk_dirents(struct bch_fs *c, nlink_table *links,
int
ret
;
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
inc_link
(
c
,
links
,
range_start
,
range_end
,
BCACHEFS_ROOT_INO
,
false
);
...
...
@@ -1327,6 +1341,7 @@ static int bch2_gc_walk_inodes(struct bch_fs *c,
u64
nlinks_pos
;
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_INODES
,
POS
(
range_start
,
0
),
0
);
...
...
@@ -1426,6 +1441,7 @@ static int check_inodes_fast(struct bch_fs *c)
int
ret
=
0
,
ret2
;
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_INODES
,
POS_MIN
,
0
);
...
...
fs/bcachefs/inode.c
View file @
6bd13057
...
...
@@ -444,31 +444,32 @@ int bch2_inode_rm(struct bch_fs *c, u64 inode_nr)
return
ret
;
}
int
bch2_inode_find_by_inum
(
struct
bch_fs
*
c
,
u64
inode_nr
,
struct
bch_inode_unpacked
*
inode
)
int
bch2_inode_find_by_inum
_trans
(
struct
btree_trans
*
trans
,
u64
inode_nr
,
struct
bch_inode_unpacked
*
inode
)
{
struct
btree_trans
trans
;
struct
btree_iter
*
iter
;
struct
bkey_s_c
k
;
int
ret
=
-
ENOENT
;
bch2_trans_init
(
&
trans
,
c
);
iter
=
bch2_trans_get_iter
(
trans
,
BTREE_ID_INODES
,
POS
(
inode_nr
,
0
),
BTREE_ITER_SLOTS
);
if
(
IS_ERR
(
iter
))
return
PTR_ERR
(
iter
);
for_each_btree_key
(
&
trans
,
iter
,
BTREE_ID_INODES
,
POS
(
inode_nr
,
0
),
BTREE_ITER_SLOTS
,
k
)
{
switch
(
k
.
k
->
type
)
{
case
KEY_TYPE_inode
:
ret
=
bch2_inode_unpack
(
bkey_s_c_to_inode
(
k
),
inode
);
break
;
default:
/* hole, not found */
break
;
}
k
=
bch2_btree_iter_peek_slot
(
iter
);
if
(
k
.
k
->
type
==
KEY_TYPE_inode
)
ret
=
bch2_inode_unpack
(
bkey_s_c_to_inode
(
k
),
inode
);
break
;
}
bch2_trans_iter_put
(
trans
,
iter
);
return
bch2_trans_exit
(
&
trans
)
?:
ret
;
return
ret
;
}
int
bch2_inode_find_by_inum
(
struct
bch_fs
*
c
,
u64
inode_nr
,
struct
bch_inode_unpacked
*
inode
)
{
return
bch2_trans_do
(
c
,
NULL
,
0
,
bch2_inode_find_by_inum_trans
(
&
trans
,
inode_nr
,
inode
));
}
#ifdef CONFIG_BCACHEFS_DEBUG
...
...
fs/bcachefs/inode.h
View file @
6bd13057
...
...
@@ -60,8 +60,9 @@ int bch2_inode_create(struct bch_fs *, struct bch_inode_unpacked *,
int
bch2_inode_rm
(
struct
bch_fs
*
,
u64
);
int
bch2_inode_find_by_inum
(
struct
bch_fs
*
,
u64
,
struct
bch_inode_unpacked
*
);
int
bch2_inode_find_by_inum_trans
(
struct
btree_trans
*
,
u64
,
struct
bch_inode_unpacked
*
);
int
bch2_inode_find_by_inum
(
struct
bch_fs
*
,
u64
,
struct
bch_inode_unpacked
*
);
static
inline
struct
bch_io_opts
bch2_inode_opts_get
(
struct
bch_inode_unpacked
*
inode
)
{
...
...
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