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
5 years ago
by
Kent Overstreet
Committed by
Kent Overstreet
1 year ago
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
)
{
...
...
This diff is collapsed.
Click to expand it.
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
*
);
...
...
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
)
{
...
...
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