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
58176a96
Commit
58176a96
authored
Aug 29, 2007
by
Josef Bacik
Committed by
David Woodhouse
Aug 29, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: Add per-root block accounting and sysfs entries
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
b888db2b
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
393 additions
and
11 deletions
+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
No files found.
fs/btrfs/Makefile
View file @
58176a96
...
@@ -5,7 +5,7 @@ obj-m := btrfs.o
...
@@ -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
\
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
\
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
\
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 \
#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 \
# root-tree.o dir-item.o hash.o file-item.o inode-item.o \
...
...
fs/btrfs/ctree.h
View file @
58176a96
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/buffer_head.h>
#include <linux/workqueue.h>
#include <linux/workqueue.h>
#include <linux/completion.h>
#include "bit-radix.h"
#include "bit-radix.h"
struct
btrfs_trans_handle
;
struct
btrfs_trans_handle
;
...
@@ -313,6 +314,8 @@ struct btrfs_fs_info {
...
@@ -313,6 +314,8 @@ struct btrfs_fs_info {
struct
list_head
trans_list
;
struct
list_head
trans_list
;
struct
list_head
dead_roots
;
struct
list_head
dead_roots
;
struct
delayed_work
trans_work
;
struct
delayed_work
trans_work
;
struct
kobject
super_kobj
;
struct
completion
kobj_unregister
;
int
do_barriers
;
int
do_barriers
;
int
closing
;
int
closing
;
};
};
...
@@ -328,6 +331,8 @@ struct btrfs_root {
...
@@ -328,6 +331,8 @@ struct btrfs_root {
struct
btrfs_key
root_key
;
struct
btrfs_key
root_key
;
struct
btrfs_fs_info
*
fs_info
;
struct
btrfs_fs_info
*
fs_info
;
struct
inode
*
inode
;
struct
inode
*
inode
;
struct
kobject
root_kobj
;
struct
completion
kobj_unregister
;
u64
objectid
;
u64
objectid
;
u64
last_trans
;
u64
last_trans
;
u32
blocksize
;
u32
blocksize
;
...
@@ -338,6 +343,7 @@ struct btrfs_root {
...
@@ -338,6 +343,7 @@ struct btrfs_root {
struct
btrfs_key
defrag_progress
;
struct
btrfs_key
defrag_progress
;
int
defrag_running
;
int
defrag_running
;
int
defrag_level
;
int
defrag_level
;
char
*
name
;
};
};
/* the lower bits in the key flags defines the item type */
/* 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)
...
@@ -814,6 +820,28 @@ static inline void btrfs_set_root_flags(struct btrfs_root_item *item, u32 val)
item
->
flags
=
cpu_to_le32
(
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
)
static
inline
u64
btrfs_super_blocknr
(
struct
btrfs_super_block
*
s
)
{
{
return
le64_to_cpu
(
s
->
blocknr
);
return
le64_to_cpu
(
s
->
blocknr
);
...
@@ -1014,6 +1042,23 @@ static inline void btrfs_memmove(struct btrfs_root *root,
...
@@ -1014,6 +1042,23 @@ static inline void btrfs_memmove(struct btrfs_root *root,
memmove
(
dst
,
src
,
nr
);
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. */
/* helper function to cast into the data area of the leaf. */
#define btrfs_item_ptr(leaf, slot, type) \
#define btrfs_item_ptr(leaf, slot, type) \
((type *)(btrfs_leaf_data(leaf) + \
((type *)(btrfs_leaf_data(leaf) + \
...
@@ -1191,4 +1236,13 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
...
@@ -1191,4 +1236,13 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
/* tree-defrag.c */
/* tree-defrag.c */
int
btrfs_defrag_leaves
(
struct
btrfs_trans_handle
*
trans
,
int
btrfs_defrag_leaves
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
int
cache_only
);
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
#endif
fs/btrfs/disk-io.c
View file @
58176a96
...
@@ -294,9 +294,12 @@ static int __setup_root(int blocksize,
...
@@ -294,9 +294,12 @@ static int __setup_root(int blocksize,
root
->
last_trans
=
0
;
root
->
last_trans
=
0
;
root
->
highest_inode
=
0
;
root
->
highest_inode
=
0
;
root
->
last_inode_alloc
=
0
;
root
->
last_inode_alloc
=
0
;
root
->
name
=
NULL
;
memset
(
&
root
->
root_key
,
0
,
sizeof
(
root
->
root_key
));
memset
(
&
root
->
root_key
,
0
,
sizeof
(
root
->
root_key
));
memset
(
&
root
->
root_item
,
0
,
sizeof
(
root
->
root_item
));
memset
(
&
root
->
root_item
,
0
,
sizeof
(
root
->
root_item
));
memset
(
&
root
->
defrag_progress
,
0
,
sizeof
(
root
->
defrag_progress
));
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_running
=
0
;
root
->
defrag_level
=
0
;
root
->
defrag_level
=
0
;
root
->
root_key
.
objectid
=
objectid
;
root
->
root_key
.
objectid
=
objectid
;
...
@@ -384,7 +387,8 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
...
@@ -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_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
;
struct
btrfs_root
*
root
;
int
ret
;
int
ret
;
...
@@ -405,6 +409,22 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
...
@@ -405,6 +409,22 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
kfree
(
root
);
kfree
(
root
);
return
ERR_PTR
(
ret
);
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
;
return
root
;
}
}
...
@@ -433,6 +453,8 @@ struct btrfs_root *open_ctree(struct super_block *sb)
...
@@ -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_RADIX_TREE
(
&
fs_info
->
block_group_data_radix
,
GFP_KERNEL
);
INIT_LIST_HEAD
(
&
fs_info
->
trans_list
);
INIT_LIST_HEAD
(
&
fs_info
->
trans_list
);
INIT_LIST_HEAD
(
&
fs_info
->
dead_roots
);
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
);
sb_set_blocksize
(
sb
,
4096
);
fs_info
->
running_transaction
=
NULL
;
fs_info
->
running_transaction
=
NULL
;
fs_info
->
last_trans_committed
=
0
;
fs_info
->
last_trans_committed
=
0
;
...
@@ -500,8 +522,10 @@ struct btrfs_root *open_ctree(struct super_block *sb)
...
@@ -500,8 +522,10 @@ struct btrfs_root *open_ctree(struct super_block *sb)
fs_info
->
generation
=
btrfs_super_generation
(
disk_super
)
+
1
;
fs_info
->
generation
=
btrfs_super_generation
(
disk_super
)
+
1
;
ret
=
btrfs_find_dead_roots
(
tree_root
);
ret
=
btrfs_find_dead_roots
(
tree_root
);
if
(
ret
)
if
(
ret
)
{
mutex_unlock
(
&
fs_info
->
fs_mutex
);
goto
fail_tree_root
;
goto
fail_tree_root
;
}
mutex_unlock
(
&
fs_info
->
fs_mutex
);
mutex_unlock
(
&
fs_info
->
fs_mutex
);
return
tree_root
;
return
tree_root
;
...
@@ -553,12 +577,15 @@ int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *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
,
radix_tree_delete
(
&
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
root
->
root_key
.
objectid
);
(
unsigned
long
)
root
->
root_key
.
objectid
);
btrfs_sysfs_del_root
(
root
);
if
(
root
->
inode
)
if
(
root
->
inode
)
iput
(
root
->
inode
);
iput
(
root
->
inode
);
if
(
root
->
node
)
if
(
root
->
node
)
brelse
(
root
->
node
);
brelse
(
root
->
node
);
if
(
root
->
commit_root
)
if
(
root
->
commit_root
)
brelse
(
root
->
commit_root
);
brelse
(
root
->
commit_root
);
if
(
root
->
name
)
kfree
(
root
->
name
);
kfree
(
root
);
kfree
(
root
);
return
0
;
return
0
;
}
}
...
...
fs/btrfs/disk-io.h
View file @
58176a96
...
@@ -66,7 +66,8 @@ struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr);
...
@@ -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
,
int
btrfs_csum_data
(
struct
btrfs_root
*
root
,
char
*
data
,
size_t
len
,
char
*
result
);
char
*
result
);
struct
btrfs_root
*
btrfs_read_fs_root
(
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
*
btrfs_read_fs_root_no_radix
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_root
*
btrfs_read_fs_root_no_radix
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_key
*
location
);
struct
btrfs_key
*
location
);
u64
bh_blocknr
(
struct
buffer_head
*
bh
);
u64
bh_blocknr
(
struct
buffer_head
*
bh
);
...
...
fs/btrfs/extent-tree.c
View file @
58176a96
...
@@ -858,16 +858,23 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -858,16 +858,23 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_extent_refs
(
ei
,
refs
);
btrfs_set_extent_refs
(
ei
,
refs
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
if
(
refs
==
0
)
{
if
(
refs
==
0
)
{
u64
super_blocks_used
;
u64
super_blocks_used
,
root_blocks_used
;
if
(
pin
)
{
if
(
pin
)
{
ret
=
pin_down_block
(
root
,
blocknr
,
0
);
ret
=
pin_down_block
(
root
,
blocknr
,
0
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
}
}
/* block accounting for super block */
super_blocks_used
=
btrfs_super_blocks_used
(
&
info
->
super_copy
);
super_blocks_used
=
btrfs_super_blocks_used
(
&
info
->
super_copy
);
btrfs_set_super_blocks_used
(
&
info
->
super_copy
,
btrfs_set_super_blocks_used
(
&
info
->
super_copy
,
super_blocks_used
-
num_blocks
);
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
);
ret
=
btrfs_del_item
(
trans
,
extent_root
,
path
);
if
(
ret
)
{
if
(
ret
)
{
return
ret
;
return
ret
;
...
@@ -1175,7 +1182,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
...
@@ -1175,7 +1182,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
{
{
int
ret
;
int
ret
;
int
pending_ret
;
int
pending_ret
;
u64
super_blocks_used
;
u64
super_blocks_used
,
root_blocks_used
;
u64
search_start
=
0
;
u64
search_start
=
0
;
struct
btrfs_fs_info
*
info
=
root
->
fs_info
;
struct
btrfs_fs_info
*
info
=
root
->
fs_info
;
struct
btrfs_root
*
extent_root
=
info
->
extent_root
;
struct
btrfs_root
*
extent_root
=
info
->
extent_root
;
...
@@ -1193,10 +1200,16 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
...
@@ -1193,10 +1200,16 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
/* block accounting for super block */
super_blocks_used
=
btrfs_super_blocks_used
(
&
info
->
super_copy
);
super_blocks_used
=
btrfs_super_blocks_used
(
&
info
->
super_copy
);
btrfs_set_super_blocks_used
(
&
info
->
super_copy
,
super_blocks_used
+
btrfs_set_super_blocks_used
(
&
info
->
super_copy
,
super_blocks_used
+
num_blocks
);
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
)
{
if
(
root
==
extent_root
)
{
BUG_ON
(
num_blocks
!=
1
);
BUG_ON
(
num_blocks
!=
1
);
set_radix_bit
(
&
root
->
fs_info
->
extent_ins_radix
,
ins
->
objectid
);
set_radix_bit
(
&
root
->
fs_info
->
extent_ins_radix
,
ins
->
objectid
);
...
...
fs/btrfs/inode.c
View file @
58176a96
...
@@ -733,7 +733,8 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
...
@@ -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
,
static
int
fixup_tree_root_location
(
struct
btrfs_root
*
root
,
struct
btrfs_key
*
location
,
struct
btrfs_key
*
location
,
struct
btrfs_root
**
sub_root
)
struct
btrfs_root
**
sub_root
,
struct
dentry
*
dentry
)
{
{
struct
btrfs_path
*
path
;
struct
btrfs_path
*
path
;
struct
btrfs_root_item
*
ri
;
struct
btrfs_root_item
*
ri
;
...
@@ -747,7 +748,9 @@ static int fixup_tree_root_location(struct btrfs_root *root,
...
@@ -747,7 +748,9 @@ static int fixup_tree_root_location(struct btrfs_root *root,
BUG_ON
(
!
path
);
BUG_ON
(
!
path
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
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
))
if
(
IS_ERR
(
*
sub_root
))
return
PTR_ERR
(
*
sub_root
);
return
PTR_ERR
(
*
sub_root
);
...
@@ -812,7 +815,8 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
...
@@ -812,7 +815,8 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
return
ERR_PTR
(
ret
);
return
ERR_PTR
(
ret
);
inode
=
NULL
;
inode
=
NULL
;
if
(
location
.
objectid
)
{
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
)
if
(
ret
<
0
)
return
ERR_PTR
(
ret
);
return
ERR_PTR
(
ret
);
if
(
ret
>
0
)
if
(
ret
>
0
)
...
@@ -1829,6 +1833,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
...
@@ -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_blocknr
(
&
root_item
,
bh_blocknr
(
subvol
));
btrfs_set_root_refs
(
&
root_item
,
1
);
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
));
memset
(
&
root_item
.
drop_progress
,
0
,
sizeof
(
root_item
.
drop_progress
));
root_item
.
drop_level
=
0
;
root_item
.
drop_level
=
0
;
brelse
(
subvol
);
brelse
(
subvol
);
...
@@ -1865,7 +1870,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
...
@@ -1865,7 +1870,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
if
(
ret
)
if
(
ret
)
goto
fail_commit
;
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
);
BUG_ON
(
!
new_root
);
trans
=
btrfs_start_transaction
(
new_root
,
1
);
trans
=
btrfs_start_transaction
(
new_root
,
1
);
...
...
fs/btrfs/super.c
View file @
58176a96
...
@@ -45,12 +45,14 @@ static struct super_operations btrfs_super_ops;
...
@@ -45,12 +45,14 @@ static struct super_operations btrfs_super_ops;
static
void
btrfs_put_super
(
struct
super_block
*
sb
)
static
void
btrfs_put_super
(
struct
super_block
*
sb
)
{
{
struct
btrfs_root
*
root
=
btrfs_sb
(
sb
);
struct
btrfs_root
*
root
=
btrfs_sb
(
sb
);
struct
btrfs_fs_info
*
fs
=
root
->
fs_info
;
int
ret
;
int
ret
;
ret
=
close_ctree
(
root
);
ret
=
close_ctree
(
root
);
if
(
ret
)
{
if
(
ret
)
{
printk
(
"close ctree returns %d
\n
"
,
ret
);
printk
(
"close ctree returns %d
\n
"
,
ret
);
}
}
btrfs_sysfs_del_super
(
fs
);
sb
->
s_fs_info
=
NULL
;
sb
->
s_fs_info
=
NULL
;
}
}
...
@@ -101,6 +103,12 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
...
@@ -101,6 +103,12 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
err
=
-
ENOMEM
;
err
=
-
ENOMEM
;
goto
fail_close
;
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
;
sb
->
s_root
=
root_dentry
;
btrfs_transaction_queue_work
(
tree_root
,
HZ
*
30
);
btrfs_transaction_queue_work
(
tree_root
,
HZ
*
30
);
return
0
;
return
0
;
...
@@ -182,6 +190,11 @@ static struct super_operations btrfs_super_ops = {
...
@@ -182,6 +190,11 @@ static struct super_operations btrfs_super_ops = {
static
int
__init
init_btrfs_fs
(
void
)
static
int
__init
init_btrfs_fs
(
void
)
{
{
int
err
;
int
err
;
err
=
btrfs_init_sysfs
();
if
(
err
)
return
err
;
btrfs_init_transaction_sys
();
btrfs_init_transaction_sys
();
err
=
btrfs_init_cachep
();
err
=
btrfs_init_cachep
();
if
(
err
)
if
(
err
)
...
@@ -196,6 +209,7 @@ static void __exit exit_btrfs_fs(void)
...
@@ -196,6 +209,7 @@ static void __exit exit_btrfs_fs(void)
btrfs_destroy_cachep
();
btrfs_destroy_cachep
();
extent_map_exit
();
extent_map_exit
();
unregister_filesystem
(
&
btrfs_fs_type
);
unregister_filesystem
(
&
btrfs_fs_type
);
btrfs_exit_sysfs
();
}
}
module_init
(
init_btrfs_fs
)
module_init
(
init_btrfs_fs
)
...
...
fs/btrfs/sysfs.c
View file @
58176a96
...
@@ -16,6 +16,242 @@
...
@@ -16,6 +16,242 @@
* Boston, MA 021110-1307, USA.
* 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 "ctree.h"
#include "disk-io.h"
#include "disk-io.h"
#include "transaction.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
View file @
58176a96
...
@@ -236,6 +236,7 @@ static int wait_for_commit(struct btrfs_root *root,
...
@@ -236,6 +236,7 @@ static int wait_for_commit(struct btrfs_root *root,
struct
dirty_root
{
struct
dirty_root
{
struct
list_head
list
;
struct
list_head
list
;
struct
btrfs_root
*
root
;
struct
btrfs_root
*
root
;
struct
btrfs_root
*
latest_root
;
};
};
int
btrfs_add_dead_root
(
struct
btrfs_root
*
root
,
struct
list_head
*
dead_list
)
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,
...
@@ -278,6 +279,15 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
btrfs_root_blocknr
(
&
root
->
root_item
));
btrfs_root_blocknr
(
&
root
->
root_item
));
brelse
(
root
->
commit_root
);
brelse
(
root
->
commit_root
);
root
->
commit_root
=
NULL
;
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
;
continue
;
}
}
dirty
=
kmalloc
(
sizeof
(
*
dirty
),
GFP_NOFS
);
dirty
=
kmalloc
(
sizeof
(
*
dirty
),
GFP_NOFS
);
...
@@ -291,6 +301,7 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
...
@@ -291,6 +301,7 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
memcpy
(
dirty
->
root
,
root
,
sizeof
(
*
root
));
memcpy
(
dirty
->
root
,
root
,
sizeof
(
*
root
));
dirty
->
root
->
node
=
root
->
commit_root
;
dirty
->
root
->
node
=
root
->
commit_root
;
dirty
->
latest_root
=
root
;
root
->
commit_root
=
NULL
;
root
->
commit_root
=
NULL
;
root
->
root_key
.
offset
=
root
->
fs_info
->
generation
;
root
->
root_key
.
offset
=
root
->
fs_info
->
generation
;
...
@@ -384,20 +395,29 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
...
@@ -384,20 +395,29 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
{
{
struct
dirty_root
*
dirty
;
struct
dirty_root
*
dirty
;
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_trans_handle
*
trans
;
u64
num_blocks
;
u64
blocks_used
;
int
ret
=
0
;
int
ret
=
0
;
int
err
;
int
err
;
while
(
!
list_empty
(
list
))
{
while
(
!
list_empty
(
list
))
{
struct
btrfs_root
*
root
;
mutex_lock
(
&
tree_root
->
fs_info
->
fs_mutex
);
mutex_lock
(
&
tree_root
->
fs_info
->
fs_mutex
);
dirty
=
list_entry
(
list
->
next
,
struct
dirty_root
,
list
);
dirty
=
list_entry
(
list
->
next
,
struct
dirty_root
,
list
);
list_del_init
(
&
dirty
->
list
);
list_del_init
(
&
dirty
->
list
);
num_blocks
=
btrfs_root_blocks_used
(
&
dirty
->
root
->
root_item
);
root
=
dirty
->
latest_root
;
while
(
1
)
{
while
(
1
)
{
trans
=
btrfs_start_transaction
(
tree_root
,
1
);
trans
=
btrfs_start_transaction
(
tree_root
,
1
);
ret
=
btrfs_drop_snapshot
(
trans
,
dirty
->
root
);
ret
=
btrfs_drop_snapshot
(
trans
,
dirty
->
root
);
if
(
ret
!=
-
EAGAIN
)
{
if
(
ret
!=
-
EAGAIN
)
{
break
;
break
;
}
}
err
=
btrfs_update_root
(
trans
,
err
=
btrfs_update_root
(
trans
,
tree_root
,
tree_root
,
&
dirty
->
root
->
root_key
,
&
dirty
->
root
->
root_key
,
...
@@ -414,9 +434,19 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
...
@@ -414,9 +434,19 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
mutex_lock
(
&
tree_root
->
fs_info
->
fs_mutex
);
mutex_lock
(
&
tree_root
->
fs_info
->
fs_mutex
);
}
}
BUG_ON
(
ret
);
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
);
ret
=
btrfs_del_root
(
trans
,
tree_root
,
&
dirty
->
root
->
root_key
);
if
(
ret
)
if
(
ret
)
{
BUG
();
break
;
break
;
}
ret
=
btrfs_end_transaction
(
trans
,
tree_root
);
ret
=
btrfs_end_transaction
(
trans
,
tree_root
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
...
@@ -534,10 +564,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
...
@@ -534,10 +564,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
wake_up
(
&
cur_trans
->
commit_wait
);
wake_up
(
&
cur_trans
->
commit_wait
);
put_transaction
(
cur_trans
);
put_transaction
(
cur_trans
);
put_transaction
(
cur_trans
);
put_transaction
(
cur_trans
);
if
(
root
->
fs_info
->
closing
)
if
(
root
->
fs_info
->
closing
)
list_splice_init
(
&
root
->
fs_info
->
dead_roots
,
&
dirty_fs_roots
);
list_splice_init
(
&
root
->
fs_info
->
dead_roots
,
&
dirty_fs_roots
);
else
else
list_splice_init
(
&
dirty_fs_roots
,
&
root
->
fs_info
->
dead_roots
);
list_splice_init
(
&
dirty_fs_roots
,
&
root
->
fs_info
->
dead_roots
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
kmem_cache_free
(
btrfs_trans_handle_cachep
,
trans
);
kmem_cache_free
(
btrfs_trans_handle_cachep
,
trans
);
...
...
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