Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
58176a96
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
58176a96
编写于
8月 29, 2007
作者:
J
Josef Bacik
提交者:
David Woodhouse
8月 29, 2007
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Add per-root block accounting and sysfs entries
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
b888db2b
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
393 addition
and
11 deletion
+393
-11
fs/btrfs/Makefile
fs/btrfs/Makefile
+1
-1
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+54
-0
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+29
-2
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+2
-1
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+15
-2
fs/btrfs/inode.c
fs/btrfs/inode.c
+9
-4
fs/btrfs/super.c
fs/btrfs/super.c
+14
-0
fs/btrfs/sysfs.c
fs/btrfs/sysfs.c
+236
-0
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+33
-1
未找到文件。
fs/btrfs/Makefile
浏览文件 @
58176a96
...
...
@@ -5,7 +5,7 @@ obj-m := btrfs.o
btrfs-y
:=
super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o
\
hash.o file-item.o inode-item.o inode-map.o disk-io.o
\
transaction.o bit-radix.o inode.o file.o tree-defrag.o
\
extent_map.o
extent_map.o
sysfs.o
#btrfs-y := ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
# root-tree.o dir-item.o hash.o file-item.o inode-item.o \
...
...
fs/btrfs/ctree.h
浏览文件 @
58176a96
...
...
@@ -22,6 +22,7 @@
#include <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/workqueue.h>
#include <linux/completion.h>
#include "bit-radix.h"
struct
btrfs_trans_handle
;
...
...
@@ -313,6 +314,8 @@ struct btrfs_fs_info {
struct
list_head
trans_list
;
struct
list_head
dead_roots
;
struct
delayed_work
trans_work
;
struct
kobject
super_kobj
;
struct
completion
kobj_unregister
;
int
do_barriers
;
int
closing
;
};
...
...
@@ -328,6 +331,8 @@ struct btrfs_root {
struct
btrfs_key
root_key
;
struct
btrfs_fs_info
*
fs_info
;
struct
inode
*
inode
;
struct
kobject
root_kobj
;
struct
completion
kobj_unregister
;
u64
objectid
;
u64
last_trans
;
u32
blocksize
;
...
...
@@ -338,6 +343,7 @@ struct btrfs_root {
struct
btrfs_key
defrag_progress
;
int
defrag_running
;
int
defrag_level
;
char
*
name
;
};
/* the lower bits in the key flags defines the item type */
...
...
@@ -814,6 +820,28 @@ static inline void btrfs_set_root_flags(struct btrfs_root_item *item, u32 val)
item
->
flags
=
cpu_to_le32
(
val
);
}
static
inline
void
btrfs_set_root_blocks_used
(
struct
btrfs_root_item
*
item
,
u64
val
)
{
item
->
blocks_used
=
cpu_to_le64
(
val
);
}
static
inline
u64
btrfs_root_blocks_used
(
struct
btrfs_root_item
*
item
)
{
return
le64_to_cpu
(
item
->
blocks_used
);
}
static
inline
void
btrfs_set_root_block_limit
(
struct
btrfs_root_item
*
item
,
u64
val
)
{
item
->
block_limit
=
cpu_to_le64
(
val
);
}
static
inline
u64
btrfs_root_block_limit
(
struct
btrfs_root_item
*
item
)
{
return
le64_to_cpu
(
item
->
block_limit
);
}
static
inline
u64
btrfs_super_blocknr
(
struct
btrfs_super_block
*
s
)
{
return
le64_to_cpu
(
s
->
blocknr
);
...
...
@@ -1014,6 +1042,23 @@ static inline void btrfs_memmove(struct btrfs_root *root,
memmove
(
dst
,
src
,
nr
);
}
static
inline
int
btrfs_set_root_name
(
struct
btrfs_root
*
root
,
const
char
*
name
,
int
len
)
{
/* if we already have a name just free it */
if
(
root
->
name
)
kfree
(
root
->
name
);
root
->
name
=
kmalloc
(
len
+
1
,
GFP_KERNEL
);
if
(
!
root
->
name
)
return
-
ENOMEM
;
memcpy
(
root
->
name
,
name
,
len
);
root
->
name
[
len
]
=
'\0'
;
return
0
;
}
/* helper function to cast into the data area of the leaf. */
#define btrfs_item_ptr(leaf, slot, type) \
((type *)(btrfs_leaf_data(leaf) + \
...
...
@@ -1191,4 +1236,13 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
/* tree-defrag.c */
int
btrfs_defrag_leaves
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
int
cache_only
);
/* sysfs.c */
int
btrfs_init_sysfs
(
void
);
void
btrfs_exit_sysfs
(
void
);
int
btrfs_sysfs_add_super
(
struct
btrfs_fs_info
*
fs
);
int
btrfs_sysfs_add_root
(
struct
btrfs_root
*
root
);
void
btrfs_sysfs_del_root
(
struct
btrfs_root
*
root
);
void
btrfs_sysfs_del_super
(
struct
btrfs_fs_info
*
root
);
#endif
fs/btrfs/disk-io.c
浏览文件 @
58176a96
...
...
@@ -294,9 +294,12 @@ static int __setup_root(int blocksize,
root
->
last_trans
=
0
;
root
->
highest_inode
=
0
;
root
->
last_inode_alloc
=
0
;
root
->
name
=
NULL
;
memset
(
&
root
->
root_key
,
0
,
sizeof
(
root
->
root_key
));
memset
(
&
root
->
root_item
,
0
,
sizeof
(
root
->
root_item
));
memset
(
&
root
->
defrag_progress
,
0
,
sizeof
(
root
->
defrag_progress
));
memset
(
&
root
->
root_kobj
,
0
,
sizeof
(
root
->
root_kobj
));
init_completion
(
&
root
->
kobj_unregister
);
root
->
defrag_running
=
0
;
root
->
defrag_level
=
0
;
root
->
root_key
.
objectid
=
objectid
;
...
...
@@ -384,7 +387,8 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
}
struct
btrfs_root
*
btrfs_read_fs_root
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_key
*
location
)
struct
btrfs_key
*
location
,
const
char
*
name
,
int
namelen
)
{
struct
btrfs_root
*
root
;
int
ret
;
...
...
@@ -405,6 +409,22 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
kfree
(
root
);
return
ERR_PTR
(
ret
);
}
ret
=
btrfs_set_root_name
(
root
,
name
,
namelen
);
if
(
ret
)
{
brelse
(
root
->
node
);
kfree
(
root
);
return
ERR_PTR
(
ret
);
}
ret
=
btrfs_sysfs_add_root
(
root
);
if
(
ret
)
{
brelse
(
root
->
node
);
kfree
(
root
->
name
);
kfree
(
root
);
return
ERR_PTR
(
ret
);
}
return
root
;
}
...
...
@@ -433,6 +453,8 @@ struct btrfs_root *open_ctree(struct super_block *sb)
INIT_RADIX_TREE
(
&
fs_info
->
block_group_data_radix
,
GFP_KERNEL
);
INIT_LIST_HEAD
(
&
fs_info
->
trans_list
);
INIT_LIST_HEAD
(
&
fs_info
->
dead_roots
);
memset
(
&
fs_info
->
super_kobj
,
0
,
sizeof
(
fs_info
->
super_kobj
));
init_completion
(
&
fs_info
->
kobj_unregister
);
sb_set_blocksize
(
sb
,
4096
);
fs_info
->
running_transaction
=
NULL
;
fs_info
->
last_trans_committed
=
0
;
...
...
@@ -500,8 +522,10 @@ struct btrfs_root *open_ctree(struct super_block *sb)
fs_info
->
generation
=
btrfs_super_generation
(
disk_super
)
+
1
;
ret
=
btrfs_find_dead_roots
(
tree_root
);
if
(
ret
)
if
(
ret
)
{
mutex_unlock
(
&
fs_info
->
fs_mutex
);
goto
fail_tree_root
;
}
mutex_unlock
(
&
fs_info
->
fs_mutex
);
return
tree_root
;
...
...
@@ -553,12 +577,15 @@ int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
{
radix_tree_delete
(
&
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
root
->
root_key
.
objectid
);
btrfs_sysfs_del_root
(
root
);
if
(
root
->
inode
)
iput
(
root
->
inode
);
if
(
root
->
node
)
brelse
(
root
->
node
);
if
(
root
->
commit_root
)
brelse
(
root
->
commit_root
);
if
(
root
->
name
)
kfree
(
root
->
name
);
kfree
(
root
);
return
0
;
}
...
...
fs/btrfs/disk-io.h
浏览文件 @
58176a96
...
...
@@ -66,7 +66,8 @@ struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr);
int
btrfs_csum_data
(
struct
btrfs_root
*
root
,
char
*
data
,
size_t
len
,
char
*
result
);
struct
btrfs_root
*
btrfs_read_fs_root
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_key
*
location
);
struct
btrfs_key
*
location
,
const
char
*
name
,
int
namelen
);
struct
btrfs_root
*
btrfs_read_fs_root_no_radix
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_key
*
location
);
u64
bh_blocknr
(
struct
buffer_head
*
bh
);
...
...
fs/btrfs/extent-tree.c
浏览文件 @
58176a96
...
...
@@ -858,16 +858,23 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_extent_refs
(
ei
,
refs
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
if
(
refs
==
0
)
{
u64
super_blocks_used
;
u64
super_blocks_used
,
root_blocks_used
;
if
(
pin
)
{
ret
=
pin_down_block
(
root
,
blocknr
,
0
);
BUG_ON
(
ret
);
}
/* block accounting for super block */
super_blocks_used
=
btrfs_super_blocks_used
(
&
info
->
super_copy
);
btrfs_set_super_blocks_used
(
&
info
->
super_copy
,
super_blocks_used
-
num_blocks
);
/* block accounting for root item */
root_blocks_used
=
btrfs_root_blocks_used
(
&
root
->
root_item
);
btrfs_set_root_blocks_used
(
&
root
->
root_item
,
root_blocks_used
-
num_blocks
);
ret
=
btrfs_del_item
(
trans
,
extent_root
,
path
);
if
(
ret
)
{
return
ret
;
...
...
@@ -1175,7 +1182,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
{
int
ret
;
int
pending_ret
;
u64
super_blocks_used
;
u64
super_blocks_used
,
root_blocks_used
;
u64
search_start
=
0
;
struct
btrfs_fs_info
*
info
=
root
->
fs_info
;
struct
btrfs_root
*
extent_root
=
info
->
extent_root
;
...
...
@@ -1193,10 +1200,16 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
if
(
ret
)
return
ret
;
/* block accounting for super block */
super_blocks_used
=
btrfs_super_blocks_used
(
&
info
->
super_copy
);
btrfs_set_super_blocks_used
(
&
info
->
super_copy
,
super_blocks_used
+
num_blocks
);
/* block accounting for root item */
root_blocks_used
=
btrfs_root_blocks_used
(
&
root
->
root_item
);
btrfs_set_root_blocks_used
(
&
root
->
root_item
,
root_blocks_used
+
num_blocks
);
if
(
root
==
extent_root
)
{
BUG_ON
(
num_blocks
!=
1
);
set_radix_bit
(
&
root
->
fs_info
->
extent_ins_radix
,
ins
->
objectid
);
...
...
fs/btrfs/inode.c
浏览文件 @
58176a96
...
...
@@ -733,7 +733,8 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
*/
static
int
fixup_tree_root_location
(
struct
btrfs_root
*
root
,
struct
btrfs_key
*
location
,
struct
btrfs_root
**
sub_root
)
struct
btrfs_root
**
sub_root
,
struct
dentry
*
dentry
)
{
struct
btrfs_path
*
path
;
struct
btrfs_root_item
*
ri
;
...
...
@@ -747,7 +748,9 @@ static int fixup_tree_root_location(struct btrfs_root *root,
BUG_ON
(
!
path
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
*
sub_root
=
btrfs_read_fs_root
(
root
->
fs_info
,
location
);
*
sub_root
=
btrfs_read_fs_root
(
root
->
fs_info
,
location
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
);
if
(
IS_ERR
(
*
sub_root
))
return
PTR_ERR
(
*
sub_root
);
...
...
@@ -812,7 +815,8 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
return
ERR_PTR
(
ret
);
inode
=
NULL
;
if
(
location
.
objectid
)
{
ret
=
fixup_tree_root_location
(
root
,
&
location
,
&
sub_root
);
ret
=
fixup_tree_root_location
(
root
,
&
location
,
&
sub_root
,
dentry
);
if
(
ret
<
0
)
return
ERR_PTR
(
ret
);
if
(
ret
>
0
)
...
...
@@ -1829,6 +1833,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
btrfs_set_root_blocknr
(
&
root_item
,
bh_blocknr
(
subvol
));
btrfs_set_root_refs
(
&
root_item
,
1
);
btrfs_set_root_blocks_used
(
&
root_item
,
0
);
memset
(
&
root_item
.
drop_progress
,
0
,
sizeof
(
root_item
.
drop_progress
));
root_item
.
drop_level
=
0
;
brelse
(
subvol
);
...
...
@@ -1865,7 +1870,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
if
(
ret
)
goto
fail_commit
;
new_root
=
btrfs_read_fs_root
(
root
->
fs_info
,
&
key
);
new_root
=
btrfs_read_fs_root
(
root
->
fs_info
,
&
key
,
name
,
namelen
);
BUG_ON
(
!
new_root
);
trans
=
btrfs_start_transaction
(
new_root
,
1
);
...
...
fs/btrfs/super.c
浏览文件 @
58176a96
...
...
@@ -45,12 +45,14 @@ static struct super_operations btrfs_super_ops;
static
void
btrfs_put_super
(
struct
super_block
*
sb
)
{
struct
btrfs_root
*
root
=
btrfs_sb
(
sb
);
struct
btrfs_fs_info
*
fs
=
root
->
fs_info
;
int
ret
;
ret
=
close_ctree
(
root
);
if
(
ret
)
{
printk
(
"close ctree returns %d
\n
"
,
ret
);
}
btrfs_sysfs_del_super
(
fs
);
sb
->
s_fs_info
=
NULL
;
}
...
...
@@ -101,6 +103,12 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
err
=
-
ENOMEM
;
goto
fail_close
;
}
/* this does the super kobj at the same time */
err
=
btrfs_sysfs_add_super
(
tree_root
->
fs_info
);
if
(
err
)
goto
fail_close
;
sb
->
s_root
=
root_dentry
;
btrfs_transaction_queue_work
(
tree_root
,
HZ
*
30
);
return
0
;
...
...
@@ -182,6 +190,11 @@ static struct super_operations btrfs_super_ops = {
static
int
__init
init_btrfs_fs
(
void
)
{
int
err
;
err
=
btrfs_init_sysfs
();
if
(
err
)
return
err
;
btrfs_init_transaction_sys
();
err
=
btrfs_init_cachep
();
if
(
err
)
...
...
@@ -196,6 +209,7 @@ static void __exit exit_btrfs_fs(void)
btrfs_destroy_cachep
();
extent_map_exit
();
unregister_filesystem
(
&
btrfs_fs_type
);
btrfs_exit_sysfs
();
}
module_init
(
init_btrfs_fs
)
...
...
fs/btrfs/sysfs.c
浏览文件 @
58176a96
...
...
@@ -16,6 +16,242 @@
* Boston, MA 021110-1307, USA.
*/
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
static
ssize_t
root_blocks_used_show
(
struct
btrfs_root
*
root
,
char
*
buf
)
{
return
snprintf
(
buf
,
PAGE_SIZE
,
"%llu
\n
"
,
(
unsigned
long
long
)
btrfs_root_blocks_used
(
&
root
->
root_item
));
}
static
ssize_t
root_block_limit_show
(
struct
btrfs_root
*
root
,
char
*
buf
)
{
return
snprintf
(
buf
,
PAGE_SIZE
,
"%llu
\n
"
,
(
unsigned
long
long
)
btrfs_root_block_limit
(
&
root
->
root_item
));
}
static
ssize_t
super_blocks_used_show
(
struct
btrfs_fs_info
*
fs
,
char
*
buf
)
{
return
snprintf
(
buf
,
PAGE_SIZE
,
"%llu
\n
"
,
(
unsigned
long
long
)
btrfs_super_blocks_used
(
fs
->
disk_super
));
}
static
ssize_t
super_total_blocks_show
(
struct
btrfs_fs_info
*
fs
,
char
*
buf
)
{
return
snprintf
(
buf
,
PAGE_SIZE
,
"%llu
\n
"
,
(
unsigned
long
long
)
btrfs_super_total_blocks
(
fs
->
disk_super
));
}
static
ssize_t
super_blocksize_show
(
struct
btrfs_fs_info
*
fs
,
char
*
buf
)
{
return
snprintf
(
buf
,
PAGE_SIZE
,
"%llu
\n
"
,
(
unsigned
long
long
)
btrfs_super_blocksize
(
fs
->
disk_super
));
}
/* this is for root attrs (subvols/snapshots) */
struct
btrfs_root_attr
{
struct
attribute
attr
;
ssize_t
(
*
show
)(
struct
btrfs_root
*
,
char
*
);
ssize_t
(
*
store
)(
struct
btrfs_root
*
,
const
char
*
,
size_t
);
};
#define ROOT_ATTR(name, mode, show, store) \
static struct btrfs_root_attr btrfs_root_attr_##name = __ATTR(name, mode, show, store)
ROOT_ATTR
(
blocks_used
,
0444
,
root_blocks_used_show
,
NULL
);
ROOT_ATTR
(
block_limit
,
0644
,
root_block_limit_show
,
NULL
);
static
struct
attribute
*
btrfs_root_attrs
[]
=
{
&
btrfs_root_attr_blocks_used
.
attr
,
&
btrfs_root_attr_block_limit
.
attr
,
NULL
,
};
/* this is for super attrs (actual full fs) */
struct
btrfs_super_attr
{
struct
attribute
attr
;
ssize_t
(
*
show
)(
struct
btrfs_fs_info
*
,
char
*
);
ssize_t
(
*
store
)(
struct
btrfs_fs_info
*
,
const
char
*
,
size_t
);
};
#define SUPER_ATTR(name, mode, show, store) \
static struct btrfs_super_attr btrfs_super_attr_##name = __ATTR(name, mode, show, store)
SUPER_ATTR
(
blocks_used
,
0444
,
super_blocks_used_show
,
NULL
);
SUPER_ATTR
(
total_blocks
,
0444
,
super_total_blocks_show
,
NULL
);
SUPER_ATTR
(
blocksize
,
0444
,
super_blocksize_show
,
NULL
);
static
struct
attribute
*
btrfs_super_attrs
[]
=
{
&
btrfs_super_attr_blocks_used
.
attr
,
&
btrfs_super_attr_total_blocks
.
attr
,
&
btrfs_super_attr_blocksize
.
attr
,
NULL
,
};
static
ssize_t
btrfs_super_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
)
{
struct
btrfs_fs_info
*
fs
=
container_of
(
kobj
,
struct
btrfs_fs_info
,
super_kobj
);
struct
btrfs_super_attr
*
a
=
container_of
(
attr
,
struct
btrfs_super_attr
,
attr
);
return
a
->
show
?
a
->
show
(
fs
,
buf
)
:
0
;
}
static
ssize_t
btrfs_super_attr_store
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
const
char
*
buf
,
size_t
len
)
{
struct
btrfs_fs_info
*
fs
=
container_of
(
kobj
,
struct
btrfs_fs_info
,
super_kobj
);
struct
btrfs_super_attr
*
a
=
container_of
(
attr
,
struct
btrfs_super_attr
,
attr
);
return
a
->
store
?
a
->
store
(
fs
,
buf
,
len
)
:
0
;
}
static
ssize_t
btrfs_root_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
buf
)
{
struct
btrfs_root
*
root
=
container_of
(
kobj
,
struct
btrfs_root
,
root_kobj
);
struct
btrfs_root_attr
*
a
=
container_of
(
attr
,
struct
btrfs_root_attr
,
attr
);
return
a
->
show
?
a
->
show
(
root
,
buf
)
:
0
;
}
static
ssize_t
btrfs_root_attr_store
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
const
char
*
buf
,
size_t
len
)
{
struct
btrfs_root
*
root
=
container_of
(
kobj
,
struct
btrfs_root
,
root_kobj
);
struct
btrfs_root_attr
*
a
=
container_of
(
attr
,
struct
btrfs_root_attr
,
attr
);
return
a
->
store
?
a
->
store
(
root
,
buf
,
len
)
:
0
;
}
static
void
btrfs_super_release
(
struct
kobject
*
kobj
)
{
struct
btrfs_fs_info
*
fs
=
container_of
(
kobj
,
struct
btrfs_fs_info
,
super_kobj
);
complete
(
&
fs
->
kobj_unregister
);
}
static
void
btrfs_root_release
(
struct
kobject
*
kobj
)
{
struct
btrfs_root
*
root
=
container_of
(
kobj
,
struct
btrfs_root
,
root_kobj
);
complete
(
&
root
->
kobj_unregister
);
}
static
struct
sysfs_ops
btrfs_super_attr_ops
=
{
.
show
=
btrfs_super_attr_show
,
.
store
=
btrfs_super_attr_store
,
};
static
struct
sysfs_ops
btrfs_root_attr_ops
=
{
.
show
=
btrfs_root_attr_show
,
.
store
=
btrfs_root_attr_store
,
};
static
struct
kobj_type
btrfs_root_ktype
=
{
.
default_attrs
=
btrfs_root_attrs
,
.
sysfs_ops
=
&
btrfs_root_attr_ops
,
.
release
=
btrfs_root_release
,
};
static
struct
kobj_type
btrfs_super_ktype
=
{
.
default_attrs
=
btrfs_super_attrs
,
.
sysfs_ops
=
&
btrfs_super_attr_ops
,
.
release
=
btrfs_super_release
,
};
static
struct
kset
btrfs_kset
=
{
.
kobj
=
{.
name
=
"btrfs"
},
};
int
btrfs_sysfs_add_super
(
struct
btrfs_fs_info
*
fs
)
{
int
error
;
fs
->
super_kobj
.
kset
=
&
btrfs_kset
;
fs
->
super_kobj
.
ktype
=
&
btrfs_super_ktype
;
error
=
kobject_set_name
(
&
fs
->
super_kobj
,
"%s"
,
fs
->
sb
->
s_id
);
if
(
error
)
goto
fail
;
error
=
kobject_register
(
&
fs
->
super_kobj
);
if
(
error
)
goto
fail
;
return
0
;
fail:
printk
(
KERN_ERR
"btrfs: sysfs creation for super failed
\n
"
);
return
error
;
}
int
btrfs_sysfs_add_root
(
struct
btrfs_root
*
root
)
{
int
error
;
root
->
root_kobj
.
ktype
=
&
btrfs_root_ktype
;
root
->
root_kobj
.
parent
=
&
root
->
fs_info
->
super_kobj
;
error
=
kobject_set_name
(
&
root
->
root_kobj
,
"%s"
,
root
->
name
);
if
(
error
)
{
goto
fail
;
}
error
=
kobject_register
(
&
root
->
root_kobj
);
if
(
error
)
goto
fail
;
return
0
;
fail:
printk
(
KERN_ERR
"btrfs: sysfs creation for root failed
\n
"
);
return
error
;
}
void
btrfs_sysfs_del_root
(
struct
btrfs_root
*
root
)
{
kobject_unregister
(
&
root
->
root_kobj
);
wait_for_completion
(
&
root
->
kobj_unregister
);
}
void
btrfs_sysfs_del_super
(
struct
btrfs_fs_info
*
fs
)
{
kobject_unregister
(
&
fs
->
super_kobj
);
wait_for_completion
(
&
fs
->
kobj_unregister
);
}
int
btrfs_init_sysfs
()
{
kobj_set_kset_s
(
&
btrfs_kset
,
fs_subsys
);
return
kset_register
(
&
btrfs_kset
);
}
void
btrfs_exit_sysfs
()
{
kset_unregister
(
&
btrfs_kset
);
}
fs/btrfs/transaction.c
浏览文件 @
58176a96
...
...
@@ -236,6 +236,7 @@ static int wait_for_commit(struct btrfs_root *root,
struct
dirty_root
{
struct
list_head
list
;
struct
btrfs_root
*
root
;
struct
btrfs_root
*
latest_root
;
};
int
btrfs_add_dead_root
(
struct
btrfs_root
*
root
,
struct
list_head
*
dead_list
)
...
...
@@ -278,6 +279,15 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
btrfs_root_blocknr
(
&
root
->
root_item
));
brelse
(
root
->
commit_root
);
root
->
commit_root
=
NULL
;
/* make sure to update the root on disk
* so we get any updates to the block used
* counts
*/
err
=
btrfs_update_root
(
trans
,
root
->
fs_info
->
tree_root
,
&
root
->
root_key
,
&
root
->
root_item
);
continue
;
}
dirty
=
kmalloc
(
sizeof
(
*
dirty
),
GFP_NOFS
);
...
...
@@ -291,6 +301,7 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
memcpy
(
dirty
->
root
,
root
,
sizeof
(
*
root
));
dirty
->
root
->
node
=
root
->
commit_root
;
dirty
->
latest_root
=
root
;
root
->
commit_root
=
NULL
;
root
->
root_key
.
offset
=
root
->
fs_info
->
generation
;
...
...
@@ -384,20 +395,29 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
{
struct
dirty_root
*
dirty
;
struct
btrfs_trans_handle
*
trans
;
u64
num_blocks
;
u64
blocks_used
;
int
ret
=
0
;
int
err
;
while
(
!
list_empty
(
list
))
{
struct
btrfs_root
*
root
;
mutex_lock
(
&
tree_root
->
fs_info
->
fs_mutex
);
dirty
=
list_entry
(
list
->
next
,
struct
dirty_root
,
list
);
list_del_init
(
&
dirty
->
list
);
num_blocks
=
btrfs_root_blocks_used
(
&
dirty
->
root
->
root_item
);
root
=
dirty
->
latest_root
;
while
(
1
)
{
trans
=
btrfs_start_transaction
(
tree_root
,
1
);
ret
=
btrfs_drop_snapshot
(
trans
,
dirty
->
root
);
if
(
ret
!=
-
EAGAIN
)
{
break
;
}
err
=
btrfs_update_root
(
trans
,
tree_root
,
&
dirty
->
root
->
root_key
,
...
...
@@ -414,9 +434,19 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
mutex_lock
(
&
tree_root
->
fs_info
->
fs_mutex
);
}
BUG_ON
(
ret
);
num_blocks
-=
btrfs_root_blocks_used
(
&
dirty
->
root
->
root_item
);
blocks_used
=
btrfs_root_blocks_used
(
&
root
->
root_item
);
if
(
num_blocks
)
{
record_root_in_trans
(
root
);
btrfs_set_root_blocks_used
(
&
root
->
root_item
,
blocks_used
-
num_blocks
);
}
ret
=
btrfs_del_root
(
trans
,
tree_root
,
&
dirty
->
root
->
root_key
);
if
(
ret
)
if
(
ret
)
{
BUG
();
break
;
}
ret
=
btrfs_end_transaction
(
trans
,
tree_root
);
BUG_ON
(
ret
);
...
...
@@ -534,10 +564,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
wake_up
(
&
cur_trans
->
commit_wait
);
put_transaction
(
cur_trans
);
put_transaction
(
cur_trans
);
if
(
root
->
fs_info
->
closing
)
list_splice_init
(
&
root
->
fs_info
->
dead_roots
,
&
dirty_fs_roots
);
else
list_splice_init
(
&
dirty_fs_roots
,
&
root
->
fs_info
->
dead_roots
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
kmem_cache_free
(
btrfs_trans_handle_cachep
,
trans
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录