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
nexedi
linux
Commits
49b25e05
Commit
49b25e05
authored
Mar 01, 2012
by
Jeff Mahoney
Committed by
David Sterba
Mar 22, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
btrfs: enhance transaction abort infrastructure
Signed-off-by:
Jeff Mahoney
<
jeffm@suse.com
>
parent
4da35113
Changes
8
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
300 additions
and
56 deletions
+300
-56
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+12
-1
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+46
-4
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+4
-0
fs/btrfs/relocation.c
fs/btrfs/relocation.c
+8
-6
fs/btrfs/scrub.c
fs/btrfs/scrub.c
+6
-2
fs/btrfs/super.c
fs/btrfs/super.c
+66
-8
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+155
-35
fs/btrfs/transaction.h
fs/btrfs/transaction.h
+3
-0
No files found.
fs/btrfs/ctree.h
View file @
49b25e05
...
...
@@ -2968,6 +2968,16 @@ void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...);
void
__btrfs_std_error
(
struct
btrfs_fs_info
*
fs_info
,
const
char
*
function
,
unsigned
int
line
,
int
errno
,
const
char
*
fmt
,
...);
void
__btrfs_abort_transaction
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
const
char
*
function
,
unsigned
int
line
,
int
errno
);
#define btrfs_abort_transaction(trans, root, errno) \
do { \
__btrfs_abort_transaction(trans, root, __func__, \
__LINE__, errno); \
} while (0)
#define btrfs_std_error(fs_info, errno) \
do { \
if ((errno)) \
...
...
@@ -3024,7 +3034,7 @@ void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
void
btrfs_reloc_pre_snapshot
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_pending_snapshot
*
pending
,
u64
*
bytes_to_reserve
);
void
btrfs_reloc_post_snapshot
(
struct
btrfs_trans_handle
*
trans
,
int
btrfs_reloc_post_snapshot
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_pending_snapshot
*
pending
);
/* scrub.c */
...
...
@@ -3034,6 +3044,7 @@ void btrfs_scrub_pause(struct btrfs_root *root);
void
btrfs_scrub_pause_super
(
struct
btrfs_root
*
root
);
void
btrfs_scrub_continue
(
struct
btrfs_root
*
root
);
void
btrfs_scrub_continue_super
(
struct
btrfs_root
*
root
);
int
__btrfs_scrub_cancel
(
struct
btrfs_fs_info
*
info
);
int
btrfs_scrub_cancel
(
struct
btrfs_root
*
root
);
int
btrfs_scrub_cancel_dev
(
struct
btrfs_root
*
root
,
struct
btrfs_device
*
dev
);
int
btrfs_scrub_cancel_devid
(
struct
btrfs_root
*
root
,
u64
devid
);
...
...
fs/btrfs/disk-io.c
View file @
49b25e05
...
...
@@ -61,7 +61,6 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root,
int
mark
);
static
int
btrfs_destroy_pinned_extent
(
struct
btrfs_root
*
root
,
struct
extent_io_tree
*
pinned_extents
);
static
int
btrfs_cleanup_transaction
(
struct
btrfs_root
*
root
);
/*
* end_io_wq structs are used to do processing in task context when an IO is
...
...
@@ -2896,6 +2895,19 @@ int write_ctree_super(struct btrfs_trans_handle *trans,
return
ret
;
}
/* Kill all outstanding I/O */
void
btrfs_abort_devices
(
struct
btrfs_root
*
root
)
{
struct
list_head
*
head
;
struct
btrfs_device
*
dev
;
mutex_lock
(
&
root
->
fs_info
->
fs_devices
->
device_list_mutex
);
head
=
&
root
->
fs_info
->
fs_devices
->
devices
;
list_for_each_entry_rcu
(
dev
,
head
,
dev_list
)
{
blk_abort_queue
(
dev
->
bdev
->
bd_disk
->
queue
);
}
mutex_unlock
(
&
root
->
fs_info
->
fs_devices
->
device_list_mutex
);
}
void
btrfs_free_fs_root
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_root
*
root
)
{
spin_lock
(
&
fs_info
->
fs_roots_radix_lock
);
...
...
@@ -3536,13 +3548,43 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root,
return
0
;
}
static
int
btrfs_cleanup_transaction
(
struct
btrfs_root
*
root
)
void
btrfs_cleanup_one_transaction
(
struct
btrfs_transaction
*
cur_trans
,
struct
btrfs_root
*
root
)
{
btrfs_destroy_delayed_refs
(
cur_trans
,
root
);
btrfs_block_rsv_release
(
root
,
&
root
->
fs_info
->
trans_block_rsv
,
cur_trans
->
dirty_pages
.
dirty_bytes
);
/* FIXME: cleanup wait for commit */
cur_trans
->
in_commit
=
1
;
cur_trans
->
blocked
=
1
;
if
(
waitqueue_active
(
&
root
->
fs_info
->
transaction_blocked_wait
))
wake_up
(
&
root
->
fs_info
->
transaction_blocked_wait
);
cur_trans
->
blocked
=
0
;
if
(
waitqueue_active
(
&
root
->
fs_info
->
transaction_wait
))
wake_up
(
&
root
->
fs_info
->
transaction_wait
);
cur_trans
->
commit_done
=
1
;
if
(
waitqueue_active
(
&
cur_trans
->
commit_wait
))
wake_up
(
&
cur_trans
->
commit_wait
);
btrfs_destroy_pending_snapshots
(
cur_trans
);
btrfs_destroy_marked_extents
(
root
,
&
cur_trans
->
dirty_pages
,
EXTENT_DIRTY
);
/*
memset(cur_trans, 0, sizeof(*cur_trans));
kmem_cache_free(btrfs_transaction_cachep, cur_trans);
*/
}
int
btrfs_cleanup_transaction
(
struct
btrfs_root
*
root
)
{
struct
btrfs_transaction
*
t
;
LIST_HEAD
(
list
);
WARN_ON
(
1
);
mutex_lock
(
&
root
->
fs_info
->
transaction_kthread_mutex
);
spin_lock
(
&
root
->
fs_info
->
trans_lock
);
...
...
fs/btrfs/disk-io.h
View file @
49b25e05
...
...
@@ -85,6 +85,10 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
struct
btrfs_fs_info
*
fs_info
);
int
btrfs_add_log_tree
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
);
int
btrfs_cleanup_transaction
(
struct
btrfs_root
*
root
);
void
btrfs_cleanup_one_transaction
(
struct
btrfs_transaction
*
trans
,
struct
btrfs_root
*
root
);
void
btrfs_abort_devices
(
struct
btrfs_root
*
root
);
#ifdef CONFIG_DEBUG_LOCK_ALLOC
void
btrfs_init_lockdep
(
void
);
...
...
fs/btrfs/relocation.c
View file @
49b25e05
...
...
@@ -4410,7 +4410,7 @@ void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans,
* called after snapshot is created. migrate block reservation
* and create reloc root for the newly created snapshot
*/
void
btrfs_reloc_post_snapshot
(
struct
btrfs_trans_handle
*
trans
,
int
btrfs_reloc_post_snapshot
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_pending_snapshot
*
pending
)
{
struct
btrfs_root
*
root
=
pending
->
root
;
...
...
@@ -4420,7 +4420,7 @@ void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
int
ret
;
if
(
!
root
->
reloc_root
)
return
;
return
0
;
rc
=
root
->
fs_info
->
reloc_ctl
;
rc
->
merging_rsv_size
+=
rc
->
nodes_relocated
;
...
...
@@ -4429,19 +4429,21 @@ void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
ret
=
btrfs_block_rsv_migrate
(
&
pending
->
block_rsv
,
rc
->
block_rsv
,
rc
->
nodes_relocated
);
BUG_ON
(
ret
);
if
(
ret
)
return
ret
;
}
new_root
=
pending
->
snap
;
reloc_root
=
create_reloc_root
(
trans
,
root
->
reloc_root
,
new_root
->
root_key
.
objectid
);
if
(
IS_ERR
(
reloc_root
))
return
PTR_ERR
(
reloc_root
);
ret
=
__add_reloc_root
(
reloc_root
);
BUG_ON
(
ret
<
0
);
new_root
->
reloc_root
=
reloc_root
;
if
(
rc
->
create_reloc_tree
)
{
if
(
rc
->
create_reloc_tree
)
ret
=
clone_backref_node
(
trans
,
rc
,
root
,
reloc_root
);
BUG_ON
(
ret
);
}
return
ret
;
}
fs/btrfs/scrub.c
View file @
49b25e05
...
...
@@ -1680,9 +1680,8 @@ void btrfs_scrub_continue_super(struct btrfs_root *root)
up_write
(
&
root
->
fs_info
->
scrub_super_lock
);
}
int
btrfs_scrub_cancel
(
struct
btrfs_root
*
root
)
int
__btrfs_scrub_cancel
(
struct
btrfs_fs_info
*
fs_info
)
{
struct
btrfs_fs_info
*
fs_info
=
root
->
fs_info
;
mutex_lock
(
&
fs_info
->
scrub_lock
);
if
(
!
atomic_read
(
&
fs_info
->
scrubs_running
))
{
...
...
@@ -1703,6 +1702,11 @@ int btrfs_scrub_cancel(struct btrfs_root *root)
return
0
;
}
int
btrfs_scrub_cancel
(
struct
btrfs_root
*
root
)
{
return
__btrfs_scrub_cancel
(
root
->
fs_info
);
}
int
btrfs_scrub_cancel_dev
(
struct
btrfs_root
*
root
,
struct
btrfs_device
*
dev
)
{
struct
btrfs_fs_info
*
fs_info
=
root
->
fs_info
;
...
...
fs/btrfs/super.c
View file @
49b25e05
...
...
@@ -119,6 +119,8 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info)
if
(
fs_info
->
fs_state
&
BTRFS_SUPER_FLAG_ERROR
)
{
sb
->
s_flags
|=
MS_RDONLY
;
printk
(
KERN_INFO
"btrfs is forced readonly
\n
"
);
__btrfs_scrub_cancel
(
fs_info
);
// WARN_ON(1);
}
}
...
...
@@ -197,6 +199,34 @@ void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...)
printk
(
"%sBTRFS %s (device %s): %pV"
,
lvl
,
type
,
sb
->
s_id
,
&
vaf
);
}
/*
* We only mark the transaction aborted and then set the file system read-only.
* This will prevent new transactions from starting or trying to join this
* one.
*
* This means that error recovery at the call site is limited to freeing
* any local memory allocations and passing the error code up without
* further cleanup. The transaction should complete as it normally would
* in the call path but will return -EIO.
*
* We'll complete the cleanup in btrfs_end_transaction and
* btrfs_commit_transaction.
*/
void
__btrfs_abort_transaction
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
const
char
*
function
,
unsigned
int
line
,
int
errno
)
{
WARN_ON_ONCE
(
1
);
trans
->
aborted
=
errno
;
/* Nothing used. The other threads that have joined this
* transaction may be able to continue. */
if
(
!
trans
->
blocks_used
)
{
btrfs_printk
(
root
->
fs_info
,
"Aborting unused transaction.
\n
"
);
return
;
}
trans
->
transaction
->
aborted
=
errno
;
__btrfs_std_error
(
root
->
fs_info
,
function
,
line
,
errno
,
NULL
);
}
/*
* __btrfs_panic decodes unexpected, fatal errors from the caller,
* issues an alert, and either panics or BUGs, depending on mount options.
...
...
@@ -295,6 +325,7 @@ static match_table_t tokens = {
/*
* Regular mount options parser. Everything that is needed only when
* reading in a new superblock is parsed here.
* XXX JDM: This needs to be cleaned up for remount.
*/
int
btrfs_parse_options
(
struct
btrfs_root
*
root
,
char
*
options
)
{
...
...
@@ -1096,11 +1127,20 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
{
struct
btrfs_fs_info
*
fs_info
=
btrfs_sb
(
sb
);
struct
btrfs_root
*
root
=
fs_info
->
tree_root
;
unsigned
old_flags
=
sb
->
s_flags
;
unsigned
long
old_opts
=
fs_info
->
mount_opt
;
unsigned
long
old_compress_type
=
fs_info
->
compress_type
;
u64
old_max_inline
=
fs_info
->
max_inline
;
u64
old_alloc_start
=
fs_info
->
alloc_start
;
int
old_thread_pool_size
=
fs_info
->
thread_pool_size
;
unsigned
int
old_metadata_ratio
=
fs_info
->
metadata_ratio
;
int
ret
;
ret
=
btrfs_parse_options
(
root
,
data
);
if
(
ret
)
return
-
EINVAL
;
if
(
ret
)
{
ret
=
-
EINVAL
;
goto
restore
;
}
if
((
*
flags
&
MS_RDONLY
)
==
(
sb
->
s_flags
&
MS_RDONLY
))
return
0
;
...
...
@@ -1109,25 +1149,43 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
sb
->
s_flags
|=
MS_RDONLY
;
ret
=
btrfs_commit_super
(
root
);
WARN_ON
(
ret
);
if
(
ret
)
goto
restore
;
}
else
{
if
(
fs_info
->
fs_devices
->
rw_devices
==
0
)
return
-
EACCES
;
ret
=
-
EACCES
;
goto
restore
;
if
(
btrfs_super_log_root
(
fs_info
->
super_copy
)
!=
0
)
return
-
EINVAL
;
ret
=
-
EINVAL
;
goto
restore
;
ret
=
btrfs_cleanup_fs_roots
(
fs_info
);
WARN_ON
(
ret
);
if
(
ret
)
goto
restore
;
/* recover relocation */
ret
=
btrfs_recover_relocation
(
root
);
WARN_ON
(
ret
);
if
(
ret
)
goto
restore
;
sb
->
s_flags
&=
~
MS_RDONLY
;
}
return
0
;
restore:
/* We've hit an error - don't reset MS_RDONLY */
if
(
sb
->
s_flags
&
MS_RDONLY
)
old_flags
|=
MS_RDONLY
;
sb
->
s_flags
=
old_flags
;
fs_info
->
mount_opt
=
old_opts
;
fs_info
->
compress_type
=
old_compress_type
;
fs_info
->
max_inline
=
old_max_inline
;
fs_info
->
alloc_start
=
old_alloc_start
;
fs_info
->
thread_pool_size
=
old_thread_pool_size
;
fs_info
->
metadata_ratio
=
old_metadata_ratio
;
return
ret
;
}
/* Used to sort the devices by max_avail(descending sort) */
...
...
fs/btrfs/transaction.c
View file @
49b25e05
This diff is collapsed.
Click to expand it.
fs/btrfs/transaction.h
View file @
49b25e05
...
...
@@ -43,6 +43,7 @@ struct btrfs_transaction {
wait_queue_head_t
commit_wait
;
struct
list_head
pending_snapshots
;
struct
btrfs_delayed_ref_root
delayed_refs
;
int
aborted
;
};
struct
btrfs_trans_handle
{
...
...
@@ -55,6 +56,7 @@ struct btrfs_trans_handle {
struct
btrfs_transaction
*
transaction
;
struct
btrfs_block_rsv
*
block_rsv
;
struct
btrfs_block_rsv
*
orig_rsv
;
int
aborted
;
};
struct
btrfs_pending_snapshot
{
...
...
@@ -114,4 +116,5 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
struct
extent_io_tree
*
dirty_pages
,
int
mark
);
int
btrfs_transaction_blocked
(
struct
btrfs_fs_info
*
info
);
int
btrfs_transaction_in_commit
(
struct
btrfs_fs_info
*
info
);
void
put_transaction
(
struct
btrfs_transaction
*
transaction
);
#endif
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