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
932aa837
Commit
932aa837
authored
Mar 11, 2019
by
Kent Overstreet
Committed by
Kent Overstreet
Oct 22, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bcachefs: bch2_trans_mark_update()
Signed-off-by:
Kent Overstreet
<
kent.overstreet@linux.dev
>
parent
c43a6ef9
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
702 additions
and
142 deletions
+702
-142
fs/bcachefs/alloc_background.c
fs/bcachefs/alloc_background.c
+3
-3
fs/bcachefs/alloc_background.h
fs/bcachefs/alloc_background.h
+2
-0
fs/bcachefs/bcachefs_format.h
fs/bcachefs/bcachefs_format.h
+1
-0
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_iter.c
+1
-3
fs/bcachefs/btree_types.h
fs/bcachefs/btree_types.h
+4
-0
fs/bcachefs/btree_update.h
fs/bcachefs/btree_update.h
+12
-1
fs/bcachefs/btree_update_leaf.c
fs/bcachefs/btree_update_leaf.c
+88
-31
fs/bcachefs/buckets.c
fs/bcachefs/buckets.c
+430
-56
fs/bcachefs/buckets.h
fs/bcachefs/buckets.h
+10
-1
fs/bcachefs/buckets_types.h
fs/bcachefs/buckets_types.h
+13
-0
fs/bcachefs/ec.c
fs/bcachefs/ec.c
+13
-10
fs/bcachefs/extents.c
fs/bcachefs/extents.c
+42
-3
fs/bcachefs/migrate.c
fs/bcachefs/migrate.c
+3
-0
fs/bcachefs/move.c
fs/bcachefs/move.c
+2
-0
fs/bcachefs/recovery.c
fs/bcachefs/recovery.c
+71
-29
fs/bcachefs/replicas.c
fs/bcachefs/replicas.c
+4
-4
fs/bcachefs/replicas.h
fs/bcachefs/replicas.h
+1
-0
fs/bcachefs/super-io.c
fs/bcachefs/super-io.c
+2
-1
No files found.
fs/bcachefs/alloc_background.c
View file @
932aa837
...
...
@@ -141,8 +141,8 @@ struct bkey_alloc_unpacked bch2_alloc_unpack(const struct bch_alloc *a)
return
ret
;
}
static
void
bch2_alloc_pack
(
struct
bkey_i_alloc
*
dst
,
const
struct
bkey_alloc_unpacked
src
)
void
bch2_alloc_pack
(
struct
bkey_i_alloc
*
dst
,
const
struct
bkey_alloc_unpacked
src
)
{
unsigned
idx
=
0
;
void
*
d
=
dst
->
v
.
data
;
...
...
@@ -962,7 +962,6 @@ static int bch2_invalidate_one_bucket2(struct btree_trans *trans,
invalidating_cached_data
=
m
.
cached_sectors
!=
0
;
//BUG_ON(u.dirty_sectors);
u
.
data_type
=
0
;
u
.
dirty_sectors
=
0
;
u
.
cached_sectors
=
0
;
...
...
@@ -974,6 +973,7 @@ static int bch2_invalidate_one_bucket2(struct btree_trans *trans,
* we have to trust the in memory bucket @m, not the version in the
* btree:
*/
//BUG_ON(u.dirty_sectors);
u
.
gen
=
m
.
gen
+
1
;
a
=
bkey_alloc_init
(
&
alloc_key
.
k
);
...
...
fs/bcachefs/alloc_background.h
View file @
932aa837
...
...
@@ -14,6 +14,8 @@ struct bkey_alloc_unpacked {
};
struct
bkey_alloc_unpacked
bch2_alloc_unpack
(
const
struct
bch_alloc
*
);
void
bch2_alloc_pack
(
struct
bkey_i_alloc
*
,
const
struct
bkey_alloc_unpacked
);
#define ALLOC_SCAN_BATCH(ca) max_t(size_t, 1, (ca)->mi.nbuckets >> 9)
...
...
fs/bcachefs/bcachefs_format.h
View file @
932aa837
...
...
@@ -1300,6 +1300,7 @@ enum bch_sb_features {
enum
bch_sb_compat
{
BCH_COMPAT_FEAT_ALLOC_INFO
=
0
,
BCH_COMPAT_FEAT_ALLOC_METADATA
=
1
,
};
/* options: */
...
...
fs/bcachefs/btree_iter.c
View file @
932aa837
...
...
@@ -1005,7 +1005,7 @@ static int __btree_iter_traverse_all(struct btree_trans *trans,
goto
retry_all
;
}
ret
=
btree_trans_has_multiple_iters
(
trans
)
?
-
EINTR
:
0
;
ret
=
hweight64
(
trans
->
iters_live
)
>
1
?
-
EINTR
:
0
;
out:
bch2_btree_cache_cannibalize_unlock
(
c
);
return
ret
;
...
...
@@ -1103,8 +1103,6 @@ int __must_check bch2_btree_iter_traverse(struct btree_iter *iter)
if
(
unlikely
(
ret
))
ret
=
__btree_iter_traverse_all
(
iter
->
trans
,
iter
,
ret
);
BUG_ON
(
ret
==
-
EINTR
&&
!
btree_trans_has_multiple_iters
(
iter
->
trans
));
return
ret
;
}
...
...
fs/bcachefs/btree_types.h
View file @
932aa837
...
...
@@ -6,6 +6,7 @@
#include <linux/rhashtable.h>
#include "bkey_methods.h"
#include "buckets_types.h"
#include "journal_types.h"
#include "six.h"
...
...
@@ -264,6 +265,7 @@ struct btree_insert_entry {
};
bool
deferred
;
bool
triggered
;
};
#define BTREE_ITER_MAX 64
...
...
@@ -302,6 +304,8 @@ struct btree_trans {
struct
btree_iter
iters_onstack
[
2
];
struct
btree_insert_entry
updates_onstack
[
6
];
struct
replicas_delta_list
fs_usage_deltas
;
};
#define BTREE_FLAG(flag) \
...
...
fs/bcachefs/btree_update.h
View file @
932aa837
...
...
@@ -43,8 +43,11 @@ enum {
__BTREE_INSERT_USE_ALLOC_RESERVE
,
__BTREE_INSERT_JOURNAL_REPLAY
,
__BTREE_INSERT_JOURNAL_RESERVED
,
__BTREE_INSERT_NOMARK_INSERT
,
__BTREE_INSERT_NOMARK_OVERWRITES
,
__BTREE_INSERT_NOMARK
,
__BTREE_INSERT_MARK_INMEM
,
__BTREE_INSERT_NO_CLEAR_REPLICAS
,
__BTREE_INSERT_NOWAIT
,
__BTREE_INSERT_GC_LOCK_HELD
,
__BCH_HASH_SET_MUST_CREATE
,
...
...
@@ -77,12 +80,20 @@ enum {
#define BTREE_INSERT_JOURNAL_RESERVED (1 << __BTREE_INSERT_JOURNAL_RESERVED)
/* Don't mark new key, just overwrites: */
#define BTREE_INSERT_NOMARK_INSERT (1 << __BTREE_INSERT_NOMARK_INSERT)
/* Don't mark overwrites, just new key: */
#define BTREE_INSERT_NOMARK_OVERWRITES (1 << __BTREE_INSERT_NOMARK_OVERWRITES)
/* Don't call
bch2_mark_key
: */
/* Don't call
mark new key at all
: */
#define BTREE_INSERT_NOMARK (1 << __BTREE_INSERT_NOMARK)
/* Don't mark transactionally: */
#define BTREE_INSERT_MARK_INMEM (1 << __BTREE_INSERT_MARK_INMEM)
#define BTREE_INSERT_NO_CLEAR_REPLICAS (1 << __BTREE_INSERT_NO_CLEAR_REPLICAS)
/* Don't block on allocation failure (for new btree nodes: */
#define BTREE_INSERT_NOWAIT (1 << __BTREE_INSERT_NOWAIT)
#define BTREE_INSERT_GC_LOCK_HELD (1 << __BTREE_INSERT_GC_LOCK_HELD)
...
...
fs/bcachefs/btree_update_leaf.c
View file @
932aa837
...
...
@@ -526,6 +526,22 @@ static inline void do_btree_insert_one(struct btree_trans *trans,
btree_insert_key_deferred
(
trans
,
insert
);
}
static
inline
bool
update_triggers_transactional
(
struct
btree_trans
*
trans
,
struct
btree_insert_entry
*
i
)
{
return
likely
(
!
(
trans
->
flags
&
BTREE_INSERT_MARK_INMEM
))
&&
(
i
->
iter
->
btree_id
==
BTREE_ID_EXTENTS
||
i
->
iter
->
btree_id
==
BTREE_ID_INODES
);
}
static
inline
bool
update_has_triggers
(
struct
btree_trans
*
trans
,
struct
btree_insert_entry
*
i
)
{
return
likely
(
!
(
trans
->
flags
&
BTREE_INSERT_NOMARK
))
&&
!
i
->
deferred
&&
btree_node_type_needs_gc
(
i
->
iter
->
btree_id
);
}
/*
* Get journal reservation, take write locks, and attempt to do btree update(s):
*/
...
...
@@ -538,29 +554,25 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
struct
btree_iter
*
linked
;
int
ret
;
if
(
likely
(
!
(
trans
->
flags
&
BTREE_INSERT_NO_CLEAR_REPLICAS
)))
{
memset
(
&
trans
->
fs_usage_deltas
.
fs_usage
,
0
,
sizeof
(
trans
->
fs_usage_deltas
.
fs_usage
));
trans
->
fs_usage_deltas
.
top
=
trans
->
fs_usage_deltas
.
d
;
}
trans_for_each_update_iter
(
trans
,
i
)
BUG_ON
(
i
->
iter
->
uptodate
>=
BTREE_ITER_NEED_RELOCK
);
btree_trans_lock_write
(
c
,
trans
);
if
(
likely
(
!
(
trans
->
flags
&
BTREE_INSERT_NOMARK
)))
{
trans_for_each_update_iter
(
trans
,
i
)
{
if
(
i
->
deferred
||
!
btree_node_type_needs_gc
(
i
->
iter
->
btree_id
))
continue
;
if
(
!
fs_usage
)
{
percpu_down_read
(
&
c
->
mark_lock
);
fs_usage
=
bch2_fs_usage_scratch_get
(
c
);
}
if
(
!
bch2_bkey_replicas_marked_locked
(
c
,
bkey_i_to_s_c
(
i
->
k
),
true
))
{
ret
=
BTREE_INSERT_NEED_MARK_REPLICAS
;
goto
out
;
}
trans_for_each_update_iter
(
trans
,
i
)
if
(
update_has_triggers
(
trans
,
i
)
&&
update_triggers_transactional
(
trans
,
i
))
{
ret
=
bch2_trans_mark_update
(
trans
,
i
,
&
trans
->
fs_usage_deltas
);
if
(
ret
)
return
ret
;
}
}
btree_trans_lock_write
(
c
,
trans
);
if
(
race_fault
())
{
ret
=
-
EINTR
;
...
...
@@ -578,6 +590,23 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
if
(
ret
)
goto
out
;
trans_for_each_update_iter
(
trans
,
i
)
{
if
(
i
->
deferred
||
!
btree_node_type_needs_gc
(
i
->
iter
->
btree_id
))
continue
;
if
(
!
fs_usage
)
{
percpu_down_read
(
&
c
->
mark_lock
);
fs_usage
=
bch2_fs_usage_scratch_get
(
c
);
}
if
(
!
bch2_bkey_replicas_marked_locked
(
c
,
bkey_i_to_s_c
(
i
->
k
),
true
))
{
ret
=
BTREE_INSERT_NEED_MARK_REPLICAS
;
goto
out
;
}
}
/*
* Don't get journal reservation until after we know insert will
* succeed:
...
...
@@ -606,20 +635,24 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
linked
->
flags
|=
BTREE_ITER_NOUNLOCK
;
}
if
(
likely
(
!
(
trans
->
flags
&
BTREE_INSERT_NOMARK
)))
{
trans_for_each_update_iter
(
trans
,
i
)
trans_for_each_update_iter
(
trans
,
i
)
if
(
update_has_triggers
(
trans
,
i
)
&&
!
update_triggers_transactional
(
trans
,
i
))
bch2_mark_update
(
trans
,
i
,
&
fs_usage
->
u
,
0
);
if
(
fs_usage
)
bch2_trans_fs_usage_apply
(
trans
,
fs_usage
);
if
(
unlikely
(
c
->
gc_pos
.
phase
))
{
trans_for_each_update_iter
(
trans
,
i
)
if
(
gc_visited
(
c
,
gc_pos_btree_node
(
i
->
iter
->
l
[
0
].
b
)))
bch2_mark_update
(
trans
,
i
,
NULL
,
BCH_BUCKET_MARK_GC
);
}
if
(
fs_usage
)
{
bch2_replicas_delta_list_apply
(
c
,
&
fs_usage
->
u
,
&
trans
->
fs_usage_deltas
);
bch2_trans_fs_usage_apply
(
trans
,
fs_usage
);
}
if
(
likely
(
!
(
trans
->
flags
&
BTREE_INSERT_NOMARK
))
&&
unlikely
(
c
->
gc_pos
.
phase
))
trans_for_each_update_iter
(
trans
,
i
)
if
(
gc_visited
(
c
,
gc_pos_btree_node
(
i
->
iter
->
l
[
0
].
b
)))
bch2_mark_update
(
trans
,
i
,
NULL
,
BCH_BUCKET_MARK_GC
);
trans_for_each_update
(
trans
,
i
)
do_btree_insert_one
(
trans
,
i
);
out:
...
...
@@ -646,6 +679,19 @@ int bch2_trans_commit_error(struct btree_trans *trans,
{
struct
bch_fs
*
c
=
trans
->
c
;
unsigned
flags
=
trans
->
flags
;
struct
btree_insert_entry
*
src
,
*
dst
;
src
=
dst
=
trans
->
updates
;
while
(
src
<
trans
->
updates
+
trans
->
nr_updates
)
{
if
(
!
src
->
triggered
)
{
*
dst
=
*
src
;
dst
++
;
}
src
++
;
}
trans
->
nr_updates
=
dst
-
trans
->
updates
;
/*
* BTREE_INSERT_NOUNLOCK means don't unlock _after_ successful btree
...
...
@@ -808,6 +854,7 @@ int bch2_trans_commit(struct btree_trans *trans,
{
struct
bch_fs
*
c
=
trans
->
c
;
struct
btree_insert_entry
*
i
;
unsigned
orig_mem_top
=
trans
->
mem_top
;
int
ret
=
0
;
if
(
!
trans
->
nr_updates
)
...
...
@@ -885,8 +932,16 @@ int bch2_trans_commit(struct btree_trans *trans,
return
ret
;
err:
ret
=
bch2_trans_commit_error
(
trans
,
i
,
ret
);
if
(
!
ret
)
/* can't loop if it was passed in and we changed it: */
if
(
unlikely
(
trans
->
flags
&
BTREE_INSERT_NO_CLEAR_REPLICAS
)
&&
!
ret
)
ret
=
-
EINTR
;
if
(
!
ret
)
{
/* free memory used by triggers, they'll be reexecuted: */
trans
->
mem_top
=
orig_mem_top
;
goto
retry
;
}
goto
out
;
}
...
...
@@ -969,6 +1024,7 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id,
int
ret
=
0
;
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
iter
=
bch2_trans_get_iter
(
&
trans
,
id
,
start
,
BTREE_ITER_INTENT
);
...
...
@@ -1014,5 +1070,6 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id,
}
bch2_trans_exit
(
&
trans
);
BUG_ON
(
ret
==
-
EINTR
);
return
ret
;
}
fs/bcachefs/buckets.c
View file @
932aa837
This diff is collapsed.
Click to expand it.
fs/bcachefs/buckets.h
View file @
932aa837
...
...
@@ -100,7 +100,7 @@ static inline struct bucket_mark ptr_bucket_mark(struct bch_dev *ca,
struct
bucket_mark
m
;
rcu_read_lock
();
m
=
READ_ONCE
(
bucket
(
ca
,
PTR_BUCKET_NR
(
ca
,
ptr
)
)
->
mark
);
m
=
READ_ONCE
(
PTR_BUCKET
(
ca
,
ptr
,
0
)
->
mark
);
rcu_read_unlock
();
return
m
;
...
...
@@ -266,6 +266,15 @@ int bch2_mark_overwrite(struct btree_trans *, struct btree_iter *,
struct
bch_fs_usage
*
,
unsigned
);
int
bch2_mark_update
(
struct
btree_trans
*
,
struct
btree_insert_entry
*
,
struct
bch_fs_usage
*
,
unsigned
);
void
bch2_replicas_delta_list_apply
(
struct
bch_fs
*
,
struct
bch_fs_usage
*
,
struct
replicas_delta_list
*
);
int
bch2_trans_mark_key
(
struct
btree_trans
*
,
struct
bkey_s_c
,
bool
,
s64
,
struct
replicas_delta_list
*
);
int
bch2_trans_mark_update
(
struct
btree_trans
*
,
struct
btree_insert_entry
*
,
struct
replicas_delta_list
*
);
void
bch2_trans_fs_usage_apply
(
struct
btree_trans
*
,
struct
bch_fs_usage_online
*
);
/* disk reservations: */
...
...
fs/bcachefs/buckets_types.h
View file @
932aa837
...
...
@@ -93,6 +93,19 @@ struct bch_fs_usage_short {
u64
nr_inodes
;
};
struct
replicas_delta
{
s64
delta
;
struct
bch_replicas_entry
r
;
}
__packed
;
struct
replicas_delta_list
{
struct
bch_fs_usage
fs_usage
;
struct
replicas_delta
*
top
;
struct
replicas_delta
d
[
0
];
u8
pad
[
256
];
};
/*
* A reservation for space on disk:
*/
...
...
fs/bcachefs/ec.c
View file @
932aa837
...
...
@@ -539,14 +539,17 @@ static int ec_stripe_mem_alloc(struct bch_fs *c,
struct
btree_iter
*
iter
)
{
size_t
idx
=
iter
->
pos
.
offset
;
int
ret
=
0
;
if
(
!
__ec_stripe_mem_alloc
(
c
,
idx
,
GFP_NOWAIT
|
__GFP_NOWARN
))
return
0
;
return
ret
;
bch2_btree_trans_unlock
(
iter
->
trans
);
ret
=
-
EINTR
;
if
(
!
__ec_stripe_mem_alloc
(
c
,
idx
,
GFP_KERNEL
))
return
-
EINTR
;
return
ret
;
return
-
ENOMEM
;
}
...
...
@@ -692,23 +695,22 @@ static int ec_stripe_bkey_insert(struct bch_fs *c,
if
(
!
ret
)
ret
=
-
ENOSPC
;
goto
out
;
goto
err
;
found_slot:
ret
=
ec_stripe_mem_alloc
(
c
,
iter
);
if
(
ret
==
-
EINTR
)
goto
retry
;
if
(
ret
)
return
ret
;
goto
err
;
stripe
->
k
.
p
=
iter
->
pos
;
bch2_trans_update
(
&
trans
,
BTREE_INSERT_ENTRY
(
iter
,
&
stripe
->
k_i
));
ret
=
bch2_trans_commit
(
&
trans
,
NULL
,
NULL
,
BTREE_INSERT_NOFAIL
|
BTREE_INSERT_USE_RESERVE
);
out:
BTREE_INSERT_ATOMIC
|
BTREE_INSERT_NOFAIL
);
err:
if
(
ret
==
-
EINTR
)
goto
retry
;
bch2_trans_exit
(
&
trans
);
return
ret
;
...
...
@@ -745,6 +747,7 @@ static int ec_stripe_update_ptrs(struct bch_fs *c,
int
ret
=
0
,
dev
,
idx
;
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_EXTENTS
,
bkey_start_pos
(
pos
),
...
...
fs/bcachefs/extents.c
View file @
932aa837
...
...
@@ -903,15 +903,54 @@ static void extent_bset_insert(struct bch_fs *c, struct btree_iter *iter,
bch2_btree_iter_verify
(
iter
,
l
->
b
);
}
static
unsigned
bch2_bkey_nr_alloc_ptrs
(
struct
bkey_s_c
k
)
{
struct
bkey_ptrs_c
ptrs
=
bch2_bkey_ptrs_c
(
k
);
const
union
bch_extent_entry
*
entry
;
unsigned
ret
=
0
;
bkey_extent_entry_for_each
(
ptrs
,
entry
)
{
switch
(
__extent_entry_type
(
entry
))
{
case
BCH_EXTENT_ENTRY_ptr
:
case
BCH_EXTENT_ENTRY_stripe_ptr
:
ret
++
;
}
}
return
ret
;
}
static
inline
struct
bpos
bch2_extent_atomic_end
(
struct
bkey_i
*
k
,
struct
btree_iter
*
iter
)
bch2_extent_atomic_end
(
struct
bkey_i
*
insert
,
struct
btree_iter
*
iter
)
{
struct
btree
*
b
=
iter
->
l
[
0
].
b
;
struct
btree_node_iter
node_iter
=
iter
->
l
[
0
].
iter
;
struct
bkey_packed
*
_k
;
unsigned
nr_alloc_ptrs
=
bch2_bkey_nr_alloc_ptrs
(
bkey_i_to_s_c
(
insert
));
BUG_ON
(
iter
->
uptodate
>
BTREE_ITER_NEED_PEEK
);
BUG_ON
(
bkey_cmp
(
bkey_start_pos
(
&
k
->
k
),
b
->
data
->
min_key
)
<
0
);
BUG_ON
(
bkey_cmp
(
bkey_start_pos
(
&
insert
->
k
),
b
->
data
->
min_key
)
<
0
);
while
((
_k
=
bch2_btree_node_iter_peek_filter
(
&
node_iter
,
b
,
KEY_TYPE_discard
)))
{
struct
bkey
unpacked
;
struct
bkey_s_c
k
=
bkey_disassemble
(
b
,
_k
,
&
unpacked
);
if
(
bkey_cmp
(
insert
->
k
.
p
,
bkey_start_pos
(
k
.
k
))
<=
0
)
break
;
nr_alloc_ptrs
+=
bch2_bkey_nr_alloc_ptrs
(
k
);
if
(
nr_alloc_ptrs
>
20
)
{
BUG_ON
(
bkey_cmp
(
k
.
k
->
p
,
bkey_start_pos
(
&
insert
->
k
))
<=
0
);
return
bpos_min
(
insert
->
k
.
p
,
k
.
k
->
p
);
}
bch2_btree_node_iter_advance
(
&
node_iter
,
b
);
}
return
bpos_min
(
k
->
k
.
p
,
b
->
key
.
k
.
p
);
return
bpos_min
(
insert
->
k
.
p
,
b
->
key
.
k
.
p
);
}
void
bch2_extent_trim_atomic
(
struct
bkey_i
*
k
,
struct
btree_iter
*
iter
)
...
...
fs/bcachefs/migrate.c
View file @
932aa837
...
...
@@ -43,6 +43,7 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
int
ret
=
0
;
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_EXTENTS
,
POS_MIN
,
BTREE_ITER_PREFETCH
);
...
...
@@ -96,6 +97,8 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
break
;
}
BUG_ON
(
ret
==
-
EINTR
);
bch2_trans_exit
(
&
trans
);
bch2_replicas_gc_end
(
c
,
ret
);
...
...
fs/bcachefs/move.c
View file @
932aa837
...
...
@@ -62,6 +62,7 @@ static int bch2_migrate_index_update(struct bch_write_op *op)
int
ret
=
0
;
bch2_trans_init
(
&
trans
,
c
);
bch2_trans_preload_iters
(
&
trans
);
iter
=
bch2_trans_get_iter
(
&
trans
,
BTREE_ID_EXTENTS
,
bkey_start_pos
(
&
bch2_keylist_front
(
keys
)
->
k
),
...
...
@@ -184,6 +185,7 @@ static int bch2_migrate_index_update(struct bch_write_op *op)
}
out:
bch2_trans_exit
(
&
trans
);
BUG_ON
(
ret
==
-
EINTR
);
return
ret
;
}
...
...
fs/bcachefs/recovery.c
View file @
932aa837
...
...
@@ -212,11 +212,6 @@ static int bch2_extent_replay_key(struct bch_fs *c, struct bkey_i *k)
bch2_disk_reservation_init
(
c
,
0
);
struct
bkey_i
*
split
;
bool
split_compressed
=
false
;
unsigned
flags
=
BTREE_INSERT_ATOMIC
|
BTREE_INSERT_NOFAIL
|
BTREE_INSERT_LAZY_RW
|
BTREE_INSERT_JOURNAL_REPLAY
|
BTREE_INSERT_NOMARK
;
int
ret
;
bch2_trans_init
(
&
trans
,
c
);
...
...
@@ -252,9 +247,6 @@ static int bch2_extent_replay_key(struct bch_fs *c, struct bkey_i *k)
BCH_DISK_RESERVATION_NOFAIL
);
BUG_ON
(
ret
);
flags
&=
~
BTREE_INSERT_JOURNAL_REPLAY
;
flags
&=
~
BTREE_INSERT_NOMARK
;
flags
|=
BTREE_INSERT_NOMARK_OVERWRITES
;
split_compressed
=
true
;
}
...
...
@@ -266,24 +258,31 @@ static int bch2_extent_replay_key(struct bch_fs *c, struct bkey_i *k)
bch2_btree_iter_set_pos
(
iter
,
split
->
k
.
p
);
}
while
(
bkey_cmp
(
iter
->
pos
,
k
->
k
.
p
)
<
0
);
ret
=
bch2_trans_commit
(
&
trans
,
&
disk_res
,
NULL
,
flags
);
if
(
ret
)
goto
err
;
if
(
split_compressed
)
{
/*
* This isn't strictly correct - we should only be relying on
* the btree node lock for synchronization with gc when we've
* got a write lock held.
*
* but - there are other correctness issues if btree gc were to
* run before journal replay finishes
*/
BUG_ON
(
c
->
gc_pos
.
phase
);
bch2_mark_key
(
c
,
bkey_i_to_s_c
(
k
),
false
,
-
((
s64
)
k
->
k
.
size
),
NULL
,
0
,
0
);
memset
(
&
trans
.
fs_usage_deltas
.
fs_usage
,
0
,
sizeof
(
trans
.
fs_usage_deltas
.
fs_usage
));
trans
.
fs_usage_deltas
.
top
=
trans
.
fs_usage_deltas
.
d
;
ret
=
bch2_trans_mark_key
(
&
trans
,
bkey_i_to_s_c
(
k
),
false
,
-
((
s64
)
k
->
k
.
size
),
&
trans
.
fs_usage_deltas
)
?:
bch2_trans_commit
(
&
trans
,
&
disk_res
,
NULL
,
BTREE_INSERT_ATOMIC
|
BTREE_INSERT_NOFAIL
|
BTREE_INSERT_LAZY_RW
|
BTREE_INSERT_NOMARK_OVERWRITES
|
BTREE_INSERT_NO_CLEAR_REPLICAS
);
}
else
{
ret
=
bch2_trans_commit
(
&
trans
,
&
disk_res
,
NULL
,
BTREE_INSERT_ATOMIC
|
BTREE_INSERT_NOFAIL
|
BTREE_INSERT_LAZY_RW
|
BTREE_INSERT_JOURNAL_REPLAY
|
BTREE_INSERT_NOMARK
);
}
if
(
ret
)
goto
err
;
err:
if
(
ret
==
-
EINTR
)
goto
retry
;
...
...
@@ -527,7 +526,7 @@ static int verify_superblock_clean(struct bch_fs *c,
struct
bch_sb_field_clean
*
clean
=
*
cleanp
;
int
ret
=
0
;
if
(
!
clean
||
!
j
)
if
(
!
c
->
sb
.
c
lean
||
!
j
)
return
0
;
if
(
mustfix_fsck_err_on
(
j
->
seq
!=
clean
->
journal_seq
,
c
,
...
...
@@ -653,6 +652,7 @@ int bch2_fs_recovery(struct bch_fs *c)
u64
journal_seq
;
LIST_HEAD
(
journal_entries
);
struct
journal_keys
journal_keys
=
{
NULL
};
bool
wrote
=
false
,
write_sb
=
false
;
int
ret
;
if
(
c
->
sb
.
clean
)
...
...
@@ -677,8 +677,12 @@ int bch2_fs_recovery(struct bch_fs *c)
if
(
ret
)
goto
err
;
fsck_err_on
(
c
->
sb
.
clean
&&
!
journal_empty
(
&
journal_entries
),
c
,
"filesystem marked clean but journal not empty"
);
if
(
mustfix_fsck_err_on
(
c
->
sb
.
clean
&&
!
journal_empty
(
&
journal_entries
),
c
,
"filesystem marked clean but journal not empty"
))
{
c
->
sb
.
compat
&=
~
(
1ULL
<<
BCH_COMPAT_FEAT_ALLOC_INFO
);
SET_BCH_SB_CLEAN
(
c
->
disk_sb
.
sb
,
false
);
c
->
sb
.
clean
=
false
;
}
if
(
!
c
->
sb
.
clean
&&
list_empty
(
&
journal_entries
))
{
bch_err
(
c
,
"no journal entries found"
);
...
...
@@ -736,12 +740,15 @@ int bch2_fs_recovery(struct bch_fs *c)
if
(
ret
)
goto
err
;
bch_verbose
(
c
,
"starting alloc read"
);
err
=
"error reading allocation information"
;
ret
=
bch2_alloc_read
(
c
,
&
journal_keys
);
if
(
ret
)
goto
err
;
bch_verbose
(
c
,
"alloc read done"
);
bch_verbose
(
c
,
"starting stripes_read"
);
err
=
"error reading stripes"
;
ret
=
bch2_stripes_read
(
c
,
&
journal_keys
);
if
(
ret
)
goto
err
;
...
...
@@ -749,11 +756,26 @@ int bch2_fs_recovery(struct bch_fs *c)
set_bit
(
BCH_FS_ALLOC_READ_DONE
,
&
c
->
flags
);
if
((
c
->
sb
.
compat
&
(
1ULL
<<
BCH_COMPAT_FEAT_ALLOC_INFO
))
&&
!
(
c
->
sb
.
compat
&
(
1ULL
<<
BCH_COMPAT_FEAT_ALLOC_METADATA
)))
{
/*
* interior btree node updates aren't consistent with the
* journal; after an unclean shutdown we have to walk all
* pointers to metadata:
*/
bch_verbose
(
c
,
"starting metadata mark and sweep:"
);
err
=
"error in mark and sweep"
;
ret
=
bch2_gc
(
c
,
NULL
,
true
,
true
);
if
(
ret
)
goto
err
;
bch_verbose
(
c
,
"mark and sweep done"
);
}
if
(
c
->
opts
.
fsck
||
!
(
c
->
sb
.
compat
&
(
1ULL
<<
BCH_COMPAT_FEAT_ALLOC_INFO
))
||
test_bit
(
BCH_FS_REBUILD_REPLICAS
,
&
c
->
flags
))
{
bch_verbose
(
c
,
"starting mark and sweep:"
);
err
=
"error in
recovery
"
;
err
=
"error in
mark and sweep
"
;
ret
=
bch2_gc
(
c
,
&
journal_keys
,
true
,
false
);
if
(
ret
)
goto
err
;
...
...
@@ -780,6 +802,16 @@ int bch2_fs_recovery(struct bch_fs *c)
goto
err
;
bch_verbose
(
c
,
"journal replay done"
);
bch_verbose
(
c
,
"writing allocation info:"
);
err
=
"error writing out alloc info"
;
ret
=
bch2_stripes_write
(
c
,
BTREE_INSERT_LAZY_RW
,
&
wrote
)
?:
bch2_alloc_write
(
c
,
BTREE_INSERT_LAZY_RW
,
&
wrote
);
if
(
ret
)
{
bch_err
(
c
,
"error writing alloc info"
);
goto
err
;
}
bch_verbose
(
c
,
"alloc write done"
);
if
(
c
->
opts
.
norecovery
)
goto
out
;
...
...
@@ -802,13 +834,23 @@ int bch2_fs_recovery(struct bch_fs *c)
c
->
disk_sb
.
sb
->
version_min
=
le16_to_cpu
(
bcachefs_metadata_version_min
);
c
->
disk_sb
.
sb
->
version
=
le16_to_cpu
(
bcachefs_metadata_version_current
);
write_sb
=
true
;
}
if
(
!
test_bit
(
BCH_FS_ERROR
,
&
c
->
flags
))
{
c
->
disk_sb
.
sb
->
compat
[
0
]
|=
1ULL
<<
BCH_COMPAT_FEAT_ALLOC_INFO
;
write_sb
=
true
;
}
if
(
c
->
opts
.
fsck
&&
!
test_bit
(
BCH_FS_ERROR
,
&
c
->
flags
))
{
c
->
disk_sb
.
sb
->
features
[
0
]
|=
1ULL
<<
BCH_FEATURE_ATOMIC_NLINK
;
SET_BCH_SB_HAS_ERRORS
(
c
->
disk_sb
.
sb
,
0
);
write_sb
=
true
;
}
if
(
write_sb
)
bch2_write_super
(
c
);
mutex_unlock
(
&
c
->
sb_lock
);
if
(
c
->
journal_seq_blacklist_table
&&
...
...
@@ -821,7 +863,7 @@ int bch2_fs_recovery(struct bch_fs *c)
return
ret
;
err:
fsck_err:
pr_err
(
"Error in recovery: %s (%i)"
,
err
,
ret
);
bch_err
(
c
,
"Error in recovery: %s (%i)"
,
err
,
ret
);
goto
out
;
}
...
...
fs/bcachefs/replicas.c
View file @
932aa837
...
...
@@ -102,8 +102,8 @@ static void stripe_to_replicas(struct bkey_s_c k,
r
->
devs
[
r
->
nr_devs
++
]
=
ptr
->
dev
;
}
static
void
bkey_to_replicas
(
struct
bch_replicas_entry
*
e
,
struct
bkey_s_c
k
)
void
bch2_
bkey_to_replicas
(
struct
bch_replicas_entry
*
e
,
struct
bkey_s_c
k
)
{
e
->
nr_devs
=
0
;
...
...
@@ -439,7 +439,7 @@ bool bch2_bkey_replicas_marked_locked(struct bch_fs *c,
return
false
;
}
bkey_to_replicas
(
&
search
.
e
,
k
);
b
ch2_b
key_to_replicas
(
&
search
.
e
,
k
);
return
bch2_replicas_marked_locked
(
c
,
&
search
.
e
,
check_gc_replicas
);
}
...
...
@@ -472,7 +472,7 @@ int bch2_mark_bkey_replicas(struct bch_fs *c, struct bkey_s_c k)
return
ret
;
}
bkey_to_replicas
(
&
search
.
e
,
k
);
b
ch2_b
key_to_replicas
(
&
search
.
e
,
k
);
return
bch2_mark_replicas
(
c
,
&
search
.
e
);
}
...
...
fs/bcachefs/replicas.h
View file @
932aa837
...
...
@@ -28,6 +28,7 @@ int bch2_mark_replicas(struct bch_fs *,
bool
bch2_bkey_replicas_marked_locked
(
struct
bch_fs
*
,
struct
bkey_s_c
,
bool
);
void
bch2_bkey_to_replicas
(
struct
bch_replicas_entry
*
,
struct
bkey_s_c
);
bool
bch2_bkey_replicas_marked
(
struct
bch_fs
*
,
struct
bkey_s_c
,
bool
);
int
bch2_mark_bkey_replicas
(
struct
bch_fs
*
,
struct
bkey_s_c
);
...
...
fs/bcachefs/super-io.c
View file @
932aa837
...
...
@@ -946,7 +946,7 @@ int bch2_fs_mark_dirty(struct bch_fs *c)
mutex_lock
(
&
c
->
sb_lock
);
SET_BCH_SB_CLEAN
(
c
->
disk_sb
.
sb
,
false
);
c
->
disk_sb
.
sb
->
compat
[
0
]
&=
~
(
1ULL
<<
BCH_COMPAT_FEAT_ALLOC_
INFO
);
c
->
disk_sb
.
sb
->
compat
[
0
]
&=
~
(
1ULL
<<
BCH_COMPAT_FEAT_ALLOC_
METADATA
);
ret
=
bch2_write_super
(
c
);
mutex_unlock
(
&
c
->
sb_lock
);
...
...
@@ -1063,6 +1063,7 @@ void bch2_fs_mark_clean(struct bch_fs *c)
SET_BCH_SB_CLEAN
(
c
->
disk_sb
.
sb
,
true
);
c
->
disk_sb
.
sb
->
compat
[
0
]
|=
1ULL
<<
BCH_COMPAT_FEAT_ALLOC_INFO
;
c
->
disk_sb
.
sb
->
compat
[
0
]
|=
1ULL
<<
BCH_COMPAT_FEAT_ALLOC_METADATA
;
u64s
=
sizeof
(
*
sb_clean
)
/
sizeof
(
u64
)
+
c
->
journal
.
entry_u64s_reserved
;
...
...
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