Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
31f3c99b
Commit
31f3c99b
authored
Apr 30, 2007
by
Chris Mason
Committed by
David Woodhouse
Apr 30, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: allocator improvements, inode block groups
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
308535a0
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
181 additions
and
55 deletions
+181
-55
fs/btrfs/btrfs_inode.h
fs/btrfs/btrfs_inode.h
+1
-0
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+5
-5
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+17
-1
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+98
-40
fs/btrfs/super.c
fs/btrfs/super.c
+44
-9
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+1
-0
fs/btrfs/transaction.h
fs/btrfs/transaction.h
+15
-0
No files found.
fs/btrfs/btrfs_inode.h
View file @
31f3c99b
...
...
@@ -3,6 +3,7 @@
struct
btrfs_inode
{
struct
btrfs_root
*
root
;
struct
btrfs_block_group_cache
*
block_group
;
struct
btrfs_key
location
;
struct
inode
vfs_inode
;
};
...
...
fs/btrfs/ctree.c
View file @
31f3c99b
...
...
@@ -61,7 +61,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
*
cow_ret
=
buf
;
return
0
;
}
cow
=
btrfs_alloc_free_block
(
trans
,
root
);
cow
=
btrfs_alloc_free_block
(
trans
,
root
,
buf
->
b_blocknr
);
cow_node
=
btrfs_buffer_node
(
cow
);
if
(
buf
->
b_size
!=
root
->
blocksize
||
cow
->
b_size
!=
root
->
blocksize
)
WARN_ON
(
1
);
...
...
@@ -800,7 +800,7 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
BUG_ON
(
path
->
nodes
[
level
]);
BUG_ON
(
path
->
nodes
[
level
-
1
]
!=
root
->
node
);
t
=
btrfs_alloc_free_block
(
trans
,
root
);
t
=
btrfs_alloc_free_block
(
trans
,
root
,
root
->
node
->
b_blocknr
);
c
=
btrfs_buffer_node
(
t
);
memset
(
c
,
0
,
root
->
blocksize
);
btrfs_set_header_nritems
(
&
c
->
header
,
1
);
...
...
@@ -905,7 +905,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
}
c_nritems
=
btrfs_header_nritems
(
&
c
->
header
);
split_buffer
=
btrfs_alloc_free_block
(
trans
,
root
);
split_buffer
=
btrfs_alloc_free_block
(
trans
,
root
,
t
->
b_blocknr
);
split
=
btrfs_buffer_node
(
split_buffer
);
btrfs_set_header_flags
(
&
split
->
header
,
btrfs_header_flags
(
&
c
->
header
));
btrfs_set_header_level
(
&
split
->
header
,
btrfs_header_level
(
&
c
->
header
));
...
...
@@ -1277,7 +1277,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
slot
=
path
->
slots
[
0
];
nritems
=
btrfs_header_nritems
(
&
l
->
header
);
mid
=
(
nritems
+
1
)
/
2
;
right_buffer
=
btrfs_alloc_free_block
(
trans
,
root
);
right_buffer
=
btrfs_alloc_free_block
(
trans
,
root
,
l_buf
->
b_blocknr
);
BUG_ON
(
!
right_buffer
);
right
=
btrfs_buffer_leaf
(
right_buffer
);
memset
(
&
right
->
header
,
0
,
sizeof
(
right
->
header
));
...
...
@@ -1374,7 +1374,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
if
(
!
double_split
)
return
ret
;
right_buffer
=
btrfs_alloc_free_block
(
trans
,
root
);
right_buffer
=
btrfs_alloc_free_block
(
trans
,
root
,
l_buf
->
b_blocknr
);
BUG_ON
(
!
right_buffer
);
right
=
btrfs_buffer_leaf
(
right_buffer
);
memset
(
&
right
->
header
,
0
,
sizeof
(
right
->
header
));
...
...
fs/btrfs/ctree.h
View file @
31f3c99b
...
...
@@ -174,6 +174,7 @@ struct btrfs_inode_item {
__le64
generation
;
__le64
size
;
__le64
nblocks
;
__le64
block_group
;
__le32
nlink
;
__le32
uid
;
__le32
gid
;
...
...
@@ -241,6 +242,7 @@ struct btrfs_device_item {
/* tag for the radix tree of block groups in ram */
#define BTRFS_BLOCK_GROUP_DIRTY 0
#define BTRFS_BLOCK_GROUP_AVAIL 1
#define BTRFS_BLOCK_GROUP_HINTS 8
#define BTRFS_BLOCK_GROUP_SIZE (256 * 1024 * 1024)
struct
btrfs_block_group_item
{
...
...
@@ -410,6 +412,17 @@ static inline void btrfs_set_inode_nblocks(struct btrfs_inode_item *i, u64 val)
i
->
nblocks
=
cpu_to_le64
(
val
);
}
static
inline
u64
btrfs_inode_block_group
(
struct
btrfs_inode_item
*
i
)
{
return
le64_to_cpu
(
i
->
block_group
);
}
static
inline
void
btrfs_set_inode_block_group
(
struct
btrfs_inode_item
*
i
,
u64
val
)
{
i
->
block_group
=
cpu_to_le64
(
val
);
}
static
inline
u32
btrfs_inode_nlink
(
struct
btrfs_inode_item
*
i
)
{
return
le32_to_cpu
(
i
->
nlink
);
...
...
@@ -1054,10 +1067,13 @@ static inline void btrfs_mark_buffer_dirty(struct buffer_head *bh)
btrfs_item_offset((leaf)->items + (slot))))
/* extent-tree.c */
struct
btrfs_block_group_cache
*
btrfs_find_block_group
(
struct
btrfs_root
*
root
,
struct
btrfs_block_group_cache
*
hint
,
int
data
);
int
btrfs_inc_root_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
);
struct
buffer_head
*
btrfs_alloc_free_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
);
struct
btrfs_root
*
root
,
u64
hint
);
int
btrfs_alloc_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
owner
,
u64
num_blocks
,
u64
search_start
,
...
...
fs/btrfs/extent-tree.c
View file @
31f3c99b
...
...
@@ -12,42 +12,57 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
static
int
del_pending_extents
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
extent_root
);
static
int
find_search_start
(
struct
btrfs_root
*
root
,
int
data
)
struct
btrfs_block_group_cache
*
btrfs_find_block_group
(
struct
btrfs_root
*
root
,
struct
btrfs_block_group_cache
*
hint
,
int
data
)
{
struct
btrfs_block_group_cache
*
cache
[
8
];
struct
btrfs_block_group_cache
*
found_group
=
NULL
;
struct
btrfs_fs_info
*
info
=
root
->
fs_info
;
u64
used
;
u64
last
;
u64
last
=
0
;
u64
hint_last
;
int
i
;
int
ret
;
cache
[
0
]
=
info
->
block_group_cache
;
if
(
!
cache
[
0
])
goto
find_new
;
used
=
btrfs_block_group_used
(
&
cache
[
0
]
->
item
);
if
(
used
<
(
cache
[
0
]
->
key
.
offset
*
3
/
2
))
return
0
;
find_new:
last
=
0
;
int
full_search
=
0
;
if
(
hint
)
{
used
=
btrfs_block_group_used
(
&
hint
->
item
);
if
(
used
<
(
hint
->
key
.
offset
*
2
)
/
3
)
{
return
hint
;
}
radix_tree_tag_clear
(
&
info
->
block_group_radix
,
hint
->
key
.
objectid
+
hint
->
key
.
offset
-
1
,
BTRFS_BLOCK_GROUP_AVAIL
);
last
=
hint
->
key
.
objectid
+
hint
->
key
.
offset
;
hint_last
=
last
;
}
else
{
hint_last
=
0
;
last
=
0
;
}
while
(
1
)
{
ret
=
radix_tree_gang_lookup_tag
(
&
info
->
block_group_radix
,
(
void
**
)
cache
,
last
,
ARRAY_SIZE
(
cache
),
BTRFS_BLOCK_GROUP_
DIRTY
);
BTRFS_BLOCK_GROUP_
AVAIL
);
if
(
!
ret
)
break
;
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
used
=
btrfs_block_group_used
(
&
cache
[
i
]
->
item
);
if
(
used
<
(
cache
[
i
]
->
key
.
offset
*
3
/
2
)
)
{
if
(
used
<
(
cache
[
i
]
->
key
.
offset
*
2
)
/
3
)
{
info
->
block_group_cache
=
cache
[
i
];
cache
[
i
]
->
last_alloc
=
cache
[
i
]
->
first_free
;
return
0
;
found_group
=
cache
[
i
]
;
goto
found
;
}
radix_tree_tag_clear
(
&
info
->
block_group_radix
,
cache
[
i
]
->
key
.
objectid
+
cache
[
i
]
->
key
.
offset
-
1
,
BTRFS_BLOCK_GROUP_AVAIL
);
last
=
cache
[
i
]
->
key
.
objectid
+
cache
[
i
]
->
key
.
offset
-
1
;
cache
[
i
]
->
key
.
offset
;
}
}
last
=
0
;
last
=
hint_last
;
again:
while
(
1
)
{
ret
=
radix_tree_gang_lookup
(
&
info
->
block_group_radix
,
(
void
**
)
cache
,
...
...
@@ -56,17 +71,32 @@ find_new:
break
;
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
used
=
btrfs_block_group_used
(
&
cache
[
i
]
->
item
);
if
(
used
<
(
cache
[
i
]
->
key
.
offset
*
3
/
2
)
)
{
if
(
used
<
cache
[
i
]
->
key
.
offset
)
{
info
->
block_group_cache
=
cache
[
i
];
cache
[
i
]
->
last_alloc
=
cache
[
i
]
->
first_free
;
return
0
;
found_group
=
cache
[
i
]
;
goto
found
;
}
radix_tree_tag_clear
(
&
info
->
block_group_radix
,
cache
[
i
]
->
key
.
objectid
+
cache
[
i
]
->
key
.
offset
-
1
,
BTRFS_BLOCK_GROUP_AVAIL
);
last
=
cache
[
i
]
->
key
.
objectid
+
cache
[
i
]
->
key
.
offset
-
1
;
cache
[
i
]
->
key
.
offset
;
}
}
info
->
block_group_cache
=
NULL
;
return
0
;
if
(
!
full_search
)
{
last
=
0
;
full_search
=
1
;
goto
again
;
}
found:
if
(
!
found_group
)
{
ret
=
radix_tree_gang_lookup
(
&
info
->
block_group_radix
,
(
void
**
)
&
found_group
,
0
,
1
);
BUG_ON
(
ret
!=
1
);
}
return
found_group
;
}
int
btrfs_inc_extent_ref
(
struct
btrfs_trans_handle
*
trans
,
...
...
@@ -243,6 +273,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
path
,
cache
[
i
]);
if
(
err
)
werr
=
err
;
cache
[
i
]
->
last_alloc
=
cache
[
i
]
->
first_free
;
}
}
btrfs_free_path
(
path
);
...
...
@@ -322,10 +353,6 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
btree_inode
->
i_blkbits
));
}
}
if
(
root
->
fs_info
->
block_group_cache
)
{
root
->
fs_info
->
block_group_cache
->
last_alloc
=
root
->
fs_info
->
block_group_cache
->
first_free
;
}
return
0
;
}
...
...
@@ -532,22 +559,43 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
int
total_found
=
0
;
int
fill_prealloc
=
0
;
int
level
;
int
update_block_group
=
0
;
struct
btrfs_block_group_cache
*
hint_block_group
;
path
=
btrfs_alloc_path
();
ins
->
flags
=
0
;
btrfs_set_key_type
(
ins
,
BTRFS_EXTENT_ITEM_KEY
);
level
=
btrfs_header_level
(
btrfs_buffer_header
(
root
->
node
));
/* find search start here */
if
(
0
&&
search_start
&&
num_blocks
)
{
u64
used
;
ret
=
radix_tree_gang_lookup
(
&
info
->
block_group_radix
,
(
void
**
)
&
hint_block_group
,
search_start
,
1
);
if
(
ret
)
{
used
=
btrfs_block_group_used
(
&
hint_block_group
->
item
);
if
(
used
>
(
hint_block_group
->
key
.
offset
*
9
)
/
10
)
search_start
=
0
;
else
if
(
search_start
<
hint_block_group
->
last_alloc
)
search_start
=
hint_block_group
->
last_alloc
;
}
else
{
search_start
=
0
;
}
}
if
(
num_blocks
==
0
)
{
fill_prealloc
=
1
;
num_blocks
=
1
;
total_needed
=
(
min
(
level
+
1
,
BTRFS_MAX_LEVEL
)
+
2
)
*
3
;
}
find_search_start
(
root
,
0
);
if
(
info
->
block_group_cache
&&
info
->
block_group_cache
->
last_alloc
>
search_start
)
search_start
=
info
->
block_group_cache
->
last_alloc
;
if
(
1
||
!
search_start
)
{
trans
->
block_group
=
btrfs_find_block_group
(
root
,
trans
->
block_group
,
0
);
if
(
trans
->
block_group
->
last_alloc
>
search_start
)
search_start
=
trans
->
block_group
->
last_alloc
;
update_block_group
=
1
;
}
check_failed:
btrfs_init_path
(
path
);
ins
->
objectid
=
search_start
;
...
...
@@ -662,11 +710,13 @@ check_pending:
}
info
->
extent_tree_prealloc_nr
=
total_found
;
}
ret
=
radix_tree_gang_lookup
(
&
info
->
block_group_radix
,
(
void
**
)
&
info
->
block_group_cache
,
ins
->
objectid
,
1
);
if
(
ret
)
{
info
->
block_group_cache
->
last_alloc
=
ins
->
objectid
;
if
(
update_block_group
)
{
ret
=
radix_tree_gang_lookup
(
&
info
->
block_group_radix
,
(
void
**
)
&
trans
->
block_group
,
ins
->
objectid
,
1
);
if
(
ret
)
{
trans
->
block_group
->
last_alloc
=
ins
->
objectid
;
}
}
ins
->
offset
=
num_blocks
;
btrfs_free_path
(
path
);
...
...
@@ -747,14 +797,14 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
* returns the tree buffer or NULL.
*/
struct
buffer_head
*
btrfs_alloc_free_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
)
struct
btrfs_root
*
root
,
u64
hint
)
{
struct
btrfs_key
ins
;
int
ret
;
struct
buffer_head
*
buf
;
ret
=
btrfs_alloc_extent
(
trans
,
root
,
root
->
root_key
.
objectid
,
1
,
0
,
(
unsigned
long
)
-
1
,
&
ins
);
1
,
hint
,
(
unsigned
long
)
-
1
,
&
ins
);
if
(
ret
)
{
BUG
();
return
NULL
;
...
...
@@ -975,6 +1025,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
struct
btrfs_key
found_key
;
struct
btrfs_leaf
*
leaf
;
u64
group_size_blocks
=
BTRFS_BLOCK_GROUP_SIZE
/
root
->
blocksize
;
u64
used
;
root
=
root
->
fs_info
->
extent_root
;
key
.
objectid
=
0
;
...
...
@@ -1005,8 +1056,8 @@ int btrfs_read_block_groups(struct btrfs_root *root)
struct
btrfs_block_group_item
);
memcpy
(
&
cache
->
item
,
bi
,
sizeof
(
*
bi
));
memcpy
(
&
cache
->
key
,
&
found_key
,
sizeof
(
found_key
));
cache
->
last_alloc
=
0
;
cache
->
first_free
=
0
;
cache
->
last_alloc
=
cache
->
key
.
objectid
;
cache
->
first_free
=
cache
->
key
.
objectid
;
key
.
objectid
=
found_key
.
objectid
+
found_key
.
offset
;
btrfs_release_path
(
root
,
path
);
ret
=
radix_tree_insert
(
&
root
->
fs_info
->
block_group_radix
,
...
...
@@ -1014,6 +1065,13 @@ int btrfs_read_block_groups(struct btrfs_root *root)
found_key
.
offset
-
1
,
(
void
*
)
cache
);
BUG_ON
(
ret
);
used
=
btrfs_block_group_used
(
bi
);
if
(
used
<
(
key
.
offset
*
2
)
/
3
)
{
radix_tree_tag_set
(
&
root
->
fs_info
->
block_group_radix
,
found_key
.
objectid
+
found_key
.
offset
-
1
,
BTRFS_BLOCK_GROUP_AVAIL
);
}
if
(
key
.
objectid
>=
btrfs_super_total_blocks
(
root
->
fs_info
->
disk_super
))
break
;
...
...
fs/btrfs/super.c
View file @
31f3c99b
...
...
@@ -52,6 +52,8 @@ static void btrfs_read_locked_inode(struct inode *inode)
struct
btrfs_inode_item
*
inode_item
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
btrfs_key
location
;
struct
btrfs_block_group_cache
*
alloc_group
;
u64
alloc_group_block
;
int
ret
;
path
=
btrfs_alloc_path
();
...
...
@@ -82,6 +84,12 @@ static void btrfs_read_locked_inode(struct inode *inode)
inode
->
i_ctime
.
tv_nsec
=
btrfs_timespec_nsec
(
&
inode_item
->
ctime
);
inode
->
i_blocks
=
btrfs_inode_nblocks
(
inode_item
);
inode
->
i_generation
=
btrfs_inode_generation
(
inode_item
);
alloc_group_block
=
btrfs_inode_block_group
(
inode_item
);
ret
=
radix_tree_gang_lookup
(
&
root
->
fs_info
->
block_group_radix
,
(
void
**
)
&
alloc_group
,
alloc_group_block
,
1
);
BUG_ON
(
!
ret
);
BTRFS_I
(
inode
)
->
block_group
=
alloc_group
;
btrfs_free_path
(
path
);
inode_item
=
NULL
;
...
...
@@ -136,6 +144,8 @@ static void fill_inode_item(struct btrfs_inode_item *item,
btrfs_set_timespec_nsec
(
&
item
->
ctime
,
inode
->
i_ctime
.
tv_nsec
);
btrfs_set_inode_nblocks
(
item
,
inode
->
i_blocks
);
btrfs_set_inode_generation
(
item
,
inode
->
i_generation
);
btrfs_set_inode_block_group
(
item
,
BTRFS_I
(
inode
)
->
block_group
->
key
.
objectid
);
}
...
...
@@ -237,6 +247,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
root
=
BTRFS_I
(
dir
)
->
root
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
dir
);
ret
=
btrfs_unlink_trans
(
trans
,
root
,
dir
,
dentry
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
...
...
@@ -262,6 +273,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
btrfs_init_path
(
path
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
dir
);
key
.
objectid
=
inode
->
i_ino
;
key
.
offset
=
(
u64
)
-
1
;
key
.
flags
=
(
u32
)
-
1
;
...
...
@@ -429,6 +441,7 @@ static void btrfs_delete_inode(struct inode *inode)
inode
->
i_size
=
0
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
inode
);
if
(
S_ISREG
(
inode
->
i_mode
))
{
ret
=
btrfs_truncate_in_trans
(
trans
,
root
,
inode
);
BUG_ON
(
ret
);
...
...
@@ -731,6 +744,7 @@ static int btrfs_write_inode(struct inode *inode, int wait)
if
(
wait
)
{
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
inode
);
ret
=
btrfs_commit_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
}
...
...
@@ -744,6 +758,7 @@ static void btrfs_dirty_inode(struct inode *inode)
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
inode
);
btrfs_update_inode
(
trans
,
root
,
inode
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
...
...
@@ -751,7 +766,9 @@ static void btrfs_dirty_inode(struct inode *inode)
static
struct
inode
*
btrfs_new_inode
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
int
mode
)
u64
objectid
,
struct
btrfs_block_group_cache
*
group
,
int
mode
)
{
struct
inode
*
inode
;
struct
btrfs_inode_item
inode_item
;
...
...
@@ -763,6 +780,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
return
ERR_PTR
(
-
ENOMEM
);
BTRFS_I
(
inode
)
->
root
=
root
;
group
=
btrfs_find_block_group
(
root
,
group
,
0
);
BTRFS_I
(
inode
)
->
block_group
=
group
;
inode
->
i_uid
=
current
->
fsuid
;
inode
->
i_gid
=
current
->
fsgid
;
...
...
@@ -832,6 +851,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
dir
);
err
=
btrfs_find_free_objectid
(
trans
,
root
,
dir
->
i_ino
,
&
objectid
);
if
(
err
)
{
...
...
@@ -839,11 +859,13 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
goto
out_unlock
;
}
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
mode
);
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
BTRFS_I
(
dir
)
->
block_group
,
mode
);
err
=
PTR_ERR
(
inode
);
if
(
IS_ERR
(
inode
))
goto
out_unlock
;
// FIXME mark the inode dirty
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
);
if
(
err
)
drop_inode
=
1
;
...
...
@@ -853,6 +875,8 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
inode
->
i_op
=
&
btrfs_file_inode_operations
;
}
dir
->
i_sb
->
s_dirt
=
1
;
btrfs_update_inode_block_group
(
trans
,
inode
);
btrfs_update_inode_block_group
(
trans
,
dir
);
out_unlock:
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
...
...
@@ -904,6 +928,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
dir
);
if
(
IS_ERR
(
trans
))
{
err
=
PTR_ERR
(
trans
);
goto
out_unlock
;
...
...
@@ -915,7 +940,8 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
goto
out_unlock
;
}
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
S_IFDIR
|
mode
);
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
BTRFS_I
(
dir
)
->
block_group
,
S_IFDIR
|
mode
);
if
(
IS_ERR
(
inode
))
{
err
=
PTR_ERR
(
inode
);
goto
out_fail
;
...
...
@@ -923,6 +949,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
drop_on_err
=
1
;
inode
->
i_op
=
&
btrfs_dir_inode_operations
;
inode
->
i_fop
=
&
btrfs_dir_file_operations
;
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_make_empty_dir
(
trans
,
root
,
inode
->
i_ino
,
dir
->
i_ino
);
if
(
err
)
...
...
@@ -938,6 +965,8 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
d_instantiate
(
dentry
,
inode
);
drop_on_err
=
0
;
dir
->
i_sb
->
s_dirt
=
1
;
btrfs_update_inode_block_group
(
trans
,
inode
);
btrfs_update_inode_block_group
(
trans
,
dir
);
out_fail:
btrfs_end_transaction
(
trans
,
root
);
...
...
@@ -1349,6 +1378,7 @@ static void btrfs_truncate(struct inode *inode)
/* FIXME, add redo link to tree so we don't leak on crash */
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
inode
);
ret
=
btrfs_truncate_in_trans
(
trans
,
root
,
inode
);
BUG_ON
(
ret
);
ret
=
btrfs_end_transaction
(
trans
,
root
);
...
...
@@ -1445,6 +1475,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
inode
);
bh
=
page_buffers
(
pages
[
i
]);
if
(
buffer_mapped
(
bh
)
&&
bh
->
b_blocknr
==
0
)
{
...
...
@@ -1481,6 +1512,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
kunmap
(
pages
[
i
]);
}
SetPageChecked
(
pages
[
i
]);
btrfs_update_inode_block_group
(
trans
,
inode
);
ret
=
btrfs_end_transaction
(
trans
,
root
);
BUG_ON
(
ret
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
...
...
@@ -1821,6 +1853,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
goto
out_unlock
;
}
btrfs_set_trans_block_group
(
trans
,
inode
);
/* FIXME blocksize != 4096 */
inode
->
i_blocks
+=
num_blocks
<<
3
;
if
(
start_pos
<
inode
->
i_size
)
{
...
...
@@ -1845,6 +1878,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
}
BUG_ON
(
ret
);
alloc_extent_start
=
ins
.
objectid
;
btrfs_update_inode_block_group
(
trans
,
inode
);
ret
=
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
...
...
@@ -2017,6 +2051,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
struct
btrfs_leaf
*
leaf
;
struct
btrfs_root
*
new_root
;
struct
inode
*
inode
;
struct
inode
*
dir
;
int
ret
;
u64
objectid
;
u64
new_dirid
=
BTRFS_FIRST_FREE_OBJECTID
;
...
...
@@ -2025,7 +2060,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
trans
=
btrfs_start_transaction
(
root
,
1
);
BUG_ON
(
!
trans
);
subvol
=
btrfs_alloc_free_block
(
trans
,
root
);
subvol
=
btrfs_alloc_free_block
(
trans
,
root
,
0
);
if
(
subvol
==
NULL
)
return
-
ENOSPC
;
leaf
=
btrfs_buffer_leaf
(
subvol
);
...
...
@@ -2069,10 +2104,9 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
* insert the directory item
*/
key
.
offset
=
(
u64
)
-
1
;
dir
=
root
->
fs_info
->
sb
->
s_root
->
d_inode
;
ret
=
btrfs_insert_dir_item
(
trans
,
root
->
fs_info
->
tree_root
,
name
,
namelen
,
root
->
fs_info
->
sb
->
s_root
->
d_inode
->
i_ino
,
&
key
,
0
);
name
,
namelen
,
dir
->
i_ino
,
&
key
,
0
);
BUG_ON
(
ret
);
ret
=
btrfs_commit_transaction
(
trans
,
root
);
...
...
@@ -2084,7 +2118,8 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
trans
=
btrfs_start_transaction
(
new_root
,
1
);
BUG_ON
(
!
trans
);
inode
=
btrfs_new_inode
(
trans
,
new_root
,
new_dirid
,
S_IFDIR
|
0700
);
inode
=
btrfs_new_inode
(
trans
,
new_root
,
new_dirid
,
BTRFS_I
(
dir
)
->
block_group
,
S_IFDIR
|
0700
);
inode
->
i_op
=
&
btrfs_dir_inode_operations
;
inode
->
i_fop
=
&
btrfs_dir_file_operations
;
...
...
fs/btrfs/transaction.c
View file @
31f3c99b
...
...
@@ -77,6 +77,7 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
h
->
transaction
=
root
->
fs_info
->
running_transaction
;
h
->
blocks_reserved
=
num_blocks
;
h
->
blocks_used
=
0
;
h
->
block_group
=
NULL
;
root
->
fs_info
->
running_transaction
->
use_count
++
;
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
h
->
magic
=
h
->
magic2
=
TRANS_MAGIC
;
...
...
fs/btrfs/transaction.h
View file @
31f3c99b
#ifndef __TRANSACTION__
#define __TRANSACTION__
#include "btrfs_inode.h"
struct
btrfs_transaction
{
u64
transid
;
...
...
@@ -20,10 +21,24 @@ struct btrfs_trans_handle {
unsigned
long
blocks_reserved
;
unsigned
long
blocks_used
;
struct
btrfs_transaction
*
transaction
;
struct
btrfs_block_group_cache
*
block_group
;
int
magic2
;
};
static
inline
void
btrfs_set_trans_block_group
(
struct
btrfs_trans_handle
*
trans
,
struct
inode
*
inode
)
{
trans
->
block_group
=
BTRFS_I
(
inode
)
->
block_group
;
}
static
inline
void
btrfs_update_inode_block_group
(
struct
btrfs_trans_handle
*
trans
,
struct
inode
*
inode
)
{
BTRFS_I
(
inode
)
->
block_group
=
trans
->
block_group
;
}
int
btrfs_end_transaction
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
);
struct
btrfs_trans_handle
*
btrfs_start_transaction
(
struct
btrfs_root
*
root
,
...
...
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