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
d6e4a428
Commit
d6e4a428
authored
Apr 06, 2007
by
Chris Mason
Committed by
David Woodhouse
Apr 06, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: start of support for many FS volumes
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
3eb0314d
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
242 additions
and
79 deletions
+242
-79
fs/btrfs/TODO
fs/btrfs/TODO
+7
-0
fs/btrfs/btrfs_inode.h
fs/btrfs/btrfs_inode.h
+2
-0
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+22
-14
fs/btrfs/dir-item.c
fs/btrfs/dir-item.c
+9
-5
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+5
-2
fs/btrfs/inode-item.c
fs/btrfs/inode-item.c
+19
-7
fs/btrfs/print-tree.c
fs/btrfs/print-tree.c
+1
-1
fs/btrfs/super.c
fs/btrfs/super.c
+168
-50
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+9
-0
No files found.
fs/btrfs/TODO
View file @
d6e4a428
...
...
@@ -19,3 +19,10 @@
* fsck
* Scrub & defrag
---
metata FS ideas:
mount metadata FS on /sys/fs/btrfs/dev/
subvolumes in /sys/fs/btrfs/dev/fs/
snapshots in /sys/fs/btrfs/dev/fs/snapshots
mount -o bind
ioctl to create a snapshot
fs/btrfs/btrfs_inode.h
View file @
d6e4a428
...
...
@@ -3,6 +3,8 @@
struct
btrfs_inode
{
u32
magic
;
struct
btrfs_root
*
root
;
struct
btrfs_key
location
;
struct
inode
vfs_inode
;
u32
magic2
;
};
...
...
fs/btrfs/ctree.h
View file @
d6e4a428
...
...
@@ -3,6 +3,7 @@
#include <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/kobject.h>
#include "bit-radix.h"
struct
btrfs_trans_handle
;
...
...
@@ -183,13 +184,15 @@ struct btrfs_inline_data_item {
}
__attribute__
((
__packed__
));
struct
btrfs_dir_item
{
__le64
objectid
;
struct
btrfs_disk_key
location
;
__le16
flags
;
__le16
name_len
;
u8
type
;
}
__attribute__
((
__packed__
));
struct
btrfs_root_item
{
struct
btrfs_inode_item
inode
;
__le64
root_dirid
;
__le64
blocknr
;
__le32
flags
;
__le64
block_limit
;
...
...
@@ -249,6 +252,7 @@ struct btrfs_fs_info {
struct
mutex
fs_mutex
;
struct
crypto_hash
*
hash_tfm
;
spinlock_t
hash_lock
;
struct
kobject
kobj
;
};
/*
...
...
@@ -504,16 +508,6 @@ static inline void btrfs_set_item_size(struct btrfs_item *item, u16 val)
item
->
size
=
cpu_to_le16
(
val
);
}
static
inline
u64
btrfs_dir_objectid
(
struct
btrfs_dir_item
*
d
)
{
return
le64_to_cpu
(
d
->
objectid
);
}
static
inline
void
btrfs_set_dir_objectid
(
struct
btrfs_dir_item
*
d
,
u64
val
)
{
d
->
objectid
=
cpu_to_le64
(
val
);
}
static
inline
u16
btrfs_dir_flags
(
struct
btrfs_dir_item
*
d
)
{
return
le16_to_cpu
(
d
->
flags
);
...
...
@@ -724,6 +718,16 @@ static inline void btrfs_set_root_blocknr(struct btrfs_root_item *item, u64 val)
item
->
blocknr
=
cpu_to_le64
(
val
);
}
static
inline
u64
btrfs_root_dirid
(
struct
btrfs_root_item
*
item
)
{
return
le64_to_cpu
(
item
->
root_dirid
);
}
static
inline
void
btrfs_set_root_dirid
(
struct
btrfs_root_item
*
item
,
u64
val
)
{
item
->
root_dirid
=
cpu_to_le64
(
val
);
}
static
inline
u32
btrfs_root_refs
(
struct
btrfs_root_item
*
item
)
{
return
le32_to_cpu
(
item
->
refs
);
...
...
@@ -950,8 +954,8 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct
btrfs_root_item
*
item
,
struct
btrfs_key
*
key
);
/* dir-item.c */
int
btrfs_insert_dir_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
const
char
*
name
,
int
name_len
,
u64
dir
,
u64
objectid
,
u8
type
);
*
root
,
const
char
*
name
,
int
name_len
,
u64
dir
,
struct
btrfs_key
*
location
,
u8
type
);
int
btrfs_lookup_dir_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
dir
,
const
char
*
name
,
int
name_len
,
int
mod
);
...
...
@@ -978,7 +982,8 @@ int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root
*
root
,
u64
objectid
,
struct
btrfs_inode_item
*
inode_item
);
int
btrfs_lookup_inode
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
objectid
,
int
mod
);
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_key
*
location
,
int
mod
);
/* file-item.c */
int
btrfs_alloc_file_extent
(
struct
btrfs_trans_handle
*
trans
,
...
...
@@ -997,4 +1002,7 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
int
btrfs_csum_verify_file_block
(
struct
btrfs_root
*
root
,
u64
objectid
,
u64
offset
,
char
*
data
,
size_t
len
);
/* super.c */
extern
struct
subsystem
btrfs_subsys
;
#endif
fs/btrfs/dir-item.c
View file @
d6e4a428
...
...
@@ -25,8 +25,8 @@ int insert_with_overflow(struct btrfs_trans_handle *trans, struct btrfs_root
}
int
btrfs_insert_dir_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
const
char
*
name
,
int
name_len
,
u64
dir
,
u64
objectid
,
u8
type
)
*
root
,
const
char
*
name
,
int
name_len
,
u64
dir
,
struct
btrfs_key
*
location
,
u8
type
)
{
int
ret
=
0
;
struct
btrfs_path
*
path
;
...
...
@@ -50,17 +50,21 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
dir_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_dir_item
);
btrfs_
set_dir_objectid
(
dir_item
,
objectid
);
btrfs_
cpu_key_to_disk
(
&
dir_item
->
location
,
location
);
btrfs_set_dir_type
(
dir_item
,
type
);
btrfs_set_dir_flags
(
dir_item
,
0
);
btrfs_set_dir_name_len
(
dir_item
,
name_len
);
name_ptr
=
(
char
*
)(
dir_item
+
1
);
/* FIXME, use some real flag for selecting the extra index */
if
(
root
==
root
->
fs_info
->
tree_root
)
goto
out
;
btrfs_memcpy
(
root
,
path
->
nodes
[
0
]
->
b_data
,
name_ptr
,
name
,
name_len
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_release_path
(
root
,
path
);
btrfs_set_key_type
(
&
key
,
BTRFS_DIR_INDEX_KEY
);
key
.
offset
=
objectid
;
key
.
offset
=
location
->
objectid
;
ret
=
insert_with_overflow
(
trans
,
root
,
path
,
&
key
,
data_size
);
// FIXME clear the dirindex bit
if
(
ret
)
...
...
@@ -69,7 +73,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
dir_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_dir_item
);
btrfs_
set_dir_objectid
(
dir_item
,
objectid
);
btrfs_
cpu_key_to_disk
(
&
dir_item
->
location
,
location
);
btrfs_set_dir_type
(
dir_item
,
type
);
btrfs_set_dir_flags
(
dir_item
,
0
);
btrfs_set_dir_name_len
(
dir_item
,
name_len
);
...
...
fs/btrfs/disk-io.c
View file @
d6e4a428
...
...
@@ -338,7 +338,6 @@ struct btrfs_root *open_ctree(struct super_block *sb)
sb
->
s_blocksize
);
if
(
!
fs_info
->
sb_buffer
)
{
printk
(
"failed2
\n
"
);
return
NULL
;
}
disk_super
=
(
struct
btrfs_super_block
*
)
fs_info
->
sb_buffer
->
b_data
;
...
...
@@ -369,6 +368,10 @@ printk("failed2\n");
ret
=
btrfs_find_highest_inode
(
root
,
&
root
->
fs_info
->
last_inode_alloc
);
if
(
ret
==
0
)
fs_info
->
highest_inode
=
fs_info
->
last_inode_alloc
;
memset
(
&
fs_info
->
kobj
,
0
,
sizeof
(
fs_info
->
kobj
));
kobj_set_kset_s
(
fs_info
,
btrfs_subsys
);
kobject_set_name
(
&
fs_info
->
kobj
,
"%s"
,
sb
->
s_id
);
kobject_register
(
&
fs_info
->
kobj
);
mutex_unlock
(
&
fs_info
->
fs_mutex
);
return
root
;
}
...
...
@@ -430,7 +433,7 @@ int close_ctree(struct btrfs_root *root)
kfree
(
root
->
fs_info
->
extent_root
);
kfree
(
root
->
fs_info
->
inode_root
);
kfree
(
root
->
fs_info
->
tree_root
);
k
free
(
root
->
fs_info
);
k
object_unregister
(
&
root
->
fs_info
->
kobj
);
kfree
(
root
);
return
0
;
}
...
...
fs/btrfs/inode-item.c
View file @
d6e4a428
...
...
@@ -26,15 +26,27 @@ int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root
}
int
btrfs_lookup_inode
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
objectid
,
int
mod
)
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_key
*
location
,
int
mod
)
{
struct
btrfs_key
key
;
int
ins_len
=
mod
<
0
?
-
1
:
0
;
int
cow
=
mod
!=
0
;
int
ret
;
int
slot
;
struct
btrfs_leaf
*
leaf
;
struct
btrfs_key
found_key
;
key
.
objectid
=
objectid
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_INODE_ITEM_KEY
);
key
.
offset
=
0
;
return
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
ins_len
,
cow
);
ret
=
btrfs_search_slot
(
trans
,
root
,
location
,
path
,
ins_len
,
cow
);
if
(
ret
>
0
&&
btrfs_key_type
(
location
)
==
BTRFS_ROOT_ITEM_KEY
&&
location
->
offset
==
(
u64
)
-
1
&&
path
->
slots
[
0
]
!=
0
)
{
slot
=
path
->
slots
[
0
]
-
1
;
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
btrfs_disk_key_to_cpu
(
&
found_key
,
&
leaf
->
items
[
slot
].
key
);
if
(
found_key
.
objectid
==
location
->
objectid
&&
btrfs_key_type
(
&
found_key
)
==
btrfs_key_type
(
location
))
{
path
->
slots
[
0
]
--
;
return
0
;
}
}
return
ret
;
}
fs/btrfs/print-tree.c
View file @
d6e4a428
...
...
@@ -38,7 +38,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
case
BTRFS_DIR_ITEM_KEY
:
di
=
btrfs_item_ptr
(
l
,
i
,
struct
btrfs_dir_item
);
printk
(
"
\t\t
dir oid %Lu flags %u type %u
\n
"
,
btrfs_di
r_objectid
(
di
),
btrfs_di
sk_key_objectid
(
&
di
->
location
),
btrfs_dir_flags
(
di
),
btrfs_dir_type
(
di
));
printk
(
"
\t\t
name %.*s
\n
"
,
...
...
fs/btrfs/super.c
View file @
d6e4a428
...
...
@@ -16,9 +16,23 @@
#include "transaction.h"
#include "btrfs_inode.h"
void
btrfs_fsinfo_release
(
struct
kobject
*
obj
)
{
struct
btrfs_fs_info
*
fsinfo
=
container_of
(
obj
,
struct
btrfs_fs_info
,
kobj
);
kfree
(
fsinfo
);
}
struct
kobj_type
btrfs_fsinfo_ktype
=
{
.
release
=
btrfs_fsinfo_release
,
};
decl_subsys
(
btrfs
,
&
btrfs_fsinfo_ktype
,
NULL
);
#define BTRFS_SUPER_MAGIC 0x9123682E
static
struct
inode_operations
btrfs_dir_inode_operations
;
static
struct
inode_operations
btrfs_dir_ro_inode_operations
;
static
struct
super_operations
btrfs_super_ops
;
static
struct
file_operations
btrfs_dir_file_operations
;
static
struct
inode_operations
btrfs_file_inode_operations
;
...
...
@@ -37,7 +51,8 @@ static void btrfs_read_locked_inode(struct inode *inode)
{
struct
btrfs_path
*
path
;
struct
btrfs_inode_item
*
inode_item
;
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
);
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
btrfs_key
location
;
int
ret
;
path
=
btrfs_alloc_path
();
...
...
@@ -46,13 +61,12 @@ static void btrfs_read_locked_inode(struct inode *inode)
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
check_inode
(
inode
);
ret
=
btrfs_lookup_inode
(
NULL
,
root
,
path
,
inode
->
i_ino
,
0
);
memcpy
(
&
location
,
&
BTRFS_I
(
inode
)
->
location
,
sizeof
(
location
));
ret
=
btrfs_lookup_inode
(
NULL
,
root
,
path
,
&
location
,
0
);
if
(
ret
)
{
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
make_bad_inode
(
inode
);
return
;
goto
make_bad
;
}
check_inode
(
inode
);
inode_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
...
...
@@ -73,7 +87,6 @@ static void btrfs_read_locked_inode(struct inode *inode)
inode
->
i_blocks
=
btrfs_inode_nblocks
(
inode_item
);
inode
->
i_generation
=
btrfs_inode_generation
(
inode_item
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
inode_item
=
NULL
;
...
...
@@ -92,8 +105,11 @@ static void btrfs_read_locked_inode(struct inode *inode)
inode
->
i_op
=
&
btrfs_file_inode_operations
;
break
;
case
S_IFDIR
:
inode
->
i_op
=
&
btrfs_dir_inode_operations
;
inode
->
i_fop
=
&
btrfs_dir_file_operations
;
if
(
root
==
root
->
fs_info
->
tree_root
)
inode
->
i_op
=
&
btrfs_dir_ro_inode_operations
;
else
inode
->
i_op
=
&
btrfs_dir_inode_operations
;
break
;
case
S_IFLNK
:
// inode->i_op = &page_symlink_inode_operations;
...
...
@@ -101,6 +117,12 @@ static void btrfs_read_locked_inode(struct inode *inode)
}
check_inode
(
inode
);
return
;
make_bad:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
make_bad_inode
(
inode
);
}
static
int
btrfs_unlink_trans
(
struct
btrfs_trans_handle
*
trans
,
...
...
@@ -128,7 +150,7 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans,
}
di
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_dir_item
);
objectid
=
btrfs_di
r_objectid
(
di
);
objectid
=
btrfs_di
sk_key_objectid
(
&
di
->
location
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
BUG_ON
(
ret
);
...
...
@@ -157,7 +179,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
struct
btrfs_trans_handle
*
trans
;
int
ret
;
root
=
btrfs_sb
(
dir
->
i_sb
)
;
root
=
BTRFS_I
(
dir
)
->
root
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
ret
=
btrfs_unlink_trans
(
trans
,
root
,
dir
,
dentry
);
...
...
@@ -171,7 +193,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
struct
inode
*
inode
=
dentry
->
d_inode
;
int
err
;
int
ret
;
struct
btrfs_root
*
root
=
btrfs_sb
(
dir
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
struct
btrfs_path
*
path
;
struct
btrfs_key
key
;
struct
btrfs_trans_handle
*
trans
;
...
...
@@ -268,7 +290,8 @@ static int btrfs_free_inode(struct btrfs_trans_handle *trans,
BUG_ON
(
ret
);
btrfs_release_path
(
root
,
path
);
ret
=
btrfs_lookup_inode
(
trans
,
root
,
path
,
objectid
,
-
1
);
ret
=
btrfs_lookup_inode
(
trans
,
root
,
path
,
&
BTRFS_I
(
inode
)
->
location
,
-
1
);
BUG_ON
(
ret
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
BUG_ON
(
ret
);
...
...
@@ -355,7 +378,7 @@ error:
static
void
btrfs_delete_inode
(
struct
inode
*
inode
)
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
int
ret
;
truncate_inode_pages
(
&
inode
->
i_data
,
0
);
...
...
@@ -378,13 +401,13 @@ no_delete:
}
static
int
btrfs_inode_by_name
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
ino_t
*
ino
)
struct
btrfs_key
*
location
)
{
const
char
*
name
=
dentry
->
d_name
.
name
;
int
namelen
=
dentry
->
d_name
.
len
;
struct
btrfs_dir_item
*
di
;
struct
btrfs_path
*
path
;
struct
btrfs_root
*
root
=
btrfs_sb
(
dir
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
int
ret
;
path
=
btrfs_alloc_path
();
...
...
@@ -393,13 +416,13 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
ret
=
btrfs_lookup_dir_item
(
NULL
,
root
,
path
,
dir
->
i_ino
,
name
,
namelen
,
0
);
if
(
ret
||
!
btrfs_match_dir_item_name
(
root
,
path
,
name
,
namelen
))
{
*
ino
=
0
;
location
->
objectid
=
0
;
ret
=
0
;
goto
out
;
}
di
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_dir_item
);
*
ino
=
btrfs_dir_objectid
(
di
);
btrfs_disk_key_to_cpu
(
location
,
&
di
->
location
);
out:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
...
...
@@ -407,26 +430,76 @@ out:
return
ret
;
}
int
fixup_tree_root_location
(
struct
btrfs_root
*
root
,
struct
btrfs_key
*
location
,
struct
btrfs_root
**
sub_root
)
{
struct
btrfs_path
*
path
;
struct
btrfs_root_item
*
ri
;
int
ret
;
if
(
btrfs_key_type
(
location
)
!=
BTRFS_ROOT_ITEM_KEY
)
return
0
;
if
(
location
->
objectid
==
BTRFS_ROOT_TREE_OBJECTID
)
return
0
;
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
ret
=
btrfs_lookup_inode
(
NULL
,
root
,
path
,
location
,
0
);
if
(
ret
)
goto
out
;
ri
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_root_item
);
location
->
objectid
=
btrfs_root_dirid
(
ri
);
location
->
flags
=
0
;
btrfs_set_key_type
(
location
,
BTRFS_INODE_ITEM_KEY
);
location
->
offset
=
0
;
/* FIXME properly select the root */
*
sub_root
=
root
->
fs_info
->
fs_root
;
out:
btrfs_free_path
(
path
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
return
ret
;
}
static
struct
dentry
*
btrfs_lookup
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
struct
nameidata
*
nd
)
{
struct
inode
*
inode
;
struct
btrfs_root
*
root
=
btrfs_sb
(
dir
->
i_sb
);
ino_t
ino
;
struct
btrfs_inode
*
bi
=
BTRFS_I
(
dir
);
struct
btrfs_root
*
root
=
bi
->
root
;
struct
btrfs_root
*
sub_root
=
root
;
struct
btrfs_key
location
;
int
ret
;
if
(
dentry
->
d_name
.
len
>
BTRFS_NAME_LEN
)
return
ERR_PTR
(
-
ENAMETOOLONG
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
ret
=
btrfs_inode_by_name
(
dir
,
dentry
,
&
ino
);
ret
=
btrfs_inode_by_name
(
dir
,
dentry
,
&
location
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
if
(
ret
<
0
)
return
ERR_PTR
(
ret
);
inode
=
NULL
;
if
(
ino
)
{
inode
=
iget
(
dir
->
i_sb
,
ino
);
if
(
location
.
objectid
)
{
ret
=
fixup_tree_root_location
(
root
,
&
location
,
&
sub_root
);
if
(
ret
<
0
)
return
ERR_PTR
(
ret
);
if
(
ret
>
0
)
return
ERR_PTR
(
-
ENOENT
);
inode
=
iget_locked
(
dir
->
i_sb
,
location
.
objectid
);
if
(
!
inode
)
return
ERR_PTR
(
-
EACCES
);
if
(
inode
->
i_state
&
I_NEW
)
{
BTRFS_I
(
inode
)
->
root
=
sub_root
;
memcpy
(
&
BTRFS_I
(
inode
)
->
location
,
&
location
,
sizeof
(
location
));
btrfs_read_locked_inode
(
inode
);
unlock_new_inode
(
inode
);
}
check_inode
(
inode
);
}
check_inode
(
dir
);
...
...
@@ -436,7 +509,7 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
static
int
btrfs_readdir
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
)
{
struct
inode
*
inode
=
filp
->
f_path
.
dentry
->
d_inode
;
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
btrfs_item
*
item
;
struct
btrfs_dir_item
*
di
;
struct
btrfs_key
key
;
...
...
@@ -448,11 +521,16 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
int
advance
;
unsigned
char
d_type
=
DT_UNKNOWN
;
int
over
=
0
;
int
key_type
=
BTRFS_DIR_INDEX_KEY
;
/* FIXME, use a real flag for deciding about the key type */
if
(
root
->
fs_info
->
tree_root
==
root
)
key_type
=
BTRFS_DIR_ITEM_KEY
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
key
.
objectid
=
inode
->
i_ino
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_DIR_INDEX_KEY
);
btrfs_set_key_type
(
&
key
,
key_type
);
key
.
offset
=
filp
->
f_pos
;
path
=
btrfs_alloc_path
();
btrfs_init_path
(
path
);
...
...
@@ -482,10 +560,11 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
item
=
leaf
->
items
+
slot
;
if
(
btrfs_disk_key_objectid
(
&
item
->
key
)
!=
key
.
objectid
)
break
;
if
(
btrfs_disk_key_offset
(
&
item
->
key
)
>
if
(
key_type
==
BTRFS_DIR_INDEX_KEY
&&
btrfs_disk_key_offset
(
&
item
->
key
)
>
root
->
fs_info
->
highest_inode
)
break
;
if
(
btrfs_disk_key_type
(
&
item
->
key
)
!=
BTRFS_DIR_INDEX_KEY
)
if
(
btrfs_disk_key_type
(
&
item
->
key
)
!=
key_type
)
continue
;
if
(
btrfs_disk_key_offset
(
&
item
->
key
)
<
filp
->
f_pos
)
continue
;
...
...
@@ -495,7 +574,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
over
=
filldir
(
dirent
,
(
const
char
*
)(
di
+
1
),
btrfs_dir_name_len
(
di
),
btrfs_disk_key_offset
(
&
item
->
key
),
btrfs_di
r_objectid
(
di
),
d_type
);
btrfs_di
sk_key_objectid
(
&
di
->
location
),
d_type
);
if
(
over
)
goto
nopos
;
}
...
...
@@ -527,6 +606,7 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
struct
dentry
*
root_dentry
;
struct
btrfs_super_block
*
disk_super
;
struct
btrfs_root
*
root
;
struct
btrfs_inode
*
bi
;
sb
->
s_maxbytes
=
MAX_LFS_FILESIZE
;
sb
->
s_magic
=
BTRFS_SUPER_MAGIC
;
...
...
@@ -546,6 +626,13 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
btrfs_super_root_dir
(
disk_super
));
inode
=
iget_locked
(
sb
,
btrfs_super_root_dir
(
disk_super
));
bi
=
BTRFS_I
(
inode
);
bi
->
location
.
objectid
=
inode
->
i_ino
;
bi
->
location
.
offset
=
0
;
bi
->
location
.
flags
=
0
;
bi
->
root
=
root
->
fs_info
->
tree_root
;
btrfs_set_key_type
(
&
bi
->
location
,
BTRFS_INODE_ITEM_KEY
);
if
(
!
inode
)
return
-
ENOMEM
;
if
(
inode
->
i_state
&
I_NEW
)
{
...
...
@@ -594,7 +681,8 @@ static int btrfs_update_inode(struct btrfs_trans_handle *trans,
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_lookup_inode
(
trans
,
root
,
path
,
inode
->
i_ino
,
1
);
ret
=
btrfs_lookup_inode
(
trans
,
root
,
path
,
&
BTRFS_I
(
inode
)
->
location
,
1
);
if
(
ret
)
{
if
(
ret
>
0
)
ret
=
-
ENOENT
;
...
...
@@ -616,7 +704,7 @@ failed:
static
int
btrfs_write_inode
(
struct
inode
*
inode
,
int
wait
)
{
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
btrfs_trans_handle
*
trans
;
int
ret
;
...
...
@@ -637,8 +725,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
{
struct
inode
*
inode
;
struct
btrfs_inode_item
inode_item
;
struct
btrfs_root
*
root
=
btrfs_sb
(
dir
->
i_sb
)
;
struct
btrfs_key
key
;
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
struct
btrfs_key
*
key
;
int
ret
;
u64
objectid
;
...
...
@@ -646,6 +734,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
if
(
!
inode
)
return
ERR_PTR
(
-
ENOMEM
);
BTRFS_I
(
inode
)
->
root
=
BTRFS_I
(
dir
)
->
root
;
key
=
&
BTRFS_I
(
inode
)
->
location
;
check_inode
(
inode
);
ret
=
btrfs_find_free_objectid
(
trans
,
root
,
dir
->
i_ino
,
&
objectid
);
BUG_ON
(
ret
);
...
...
@@ -658,11 +748,11 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
CURRENT_TIME_SEC
;
fill_inode_item
(
&
inode_item
,
inode
);
key
.
objectid
=
objectid
;
key
.
flags
=
0
;
key
.
offset
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_INODE_ITEM_KEY
);
ret
=
btrfs_insert_inode_map
(
trans
,
root
,
objectid
,
&
key
);
key
->
objectid
=
objectid
;
key
->
flags
=
0
;
key
->
offset
=
0
;
btrfs_set_key_type
(
key
,
BTRFS_INODE_ITEM_KEY
);
ret
=
btrfs_insert_inode_map
(
trans
,
root
,
objectid
,
key
);
BUG_ON
(
ret
);
ret
=
btrfs_insert_inode
(
trans
,
root
,
objectid
,
&
inode_item
);
...
...
@@ -678,13 +768,20 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
struct
dentry
*
dentry
,
struct
inode
*
inode
)
{
int
ret
;
ret
=
btrfs_insert_dir_item
(
trans
,
btrfs_sb
(
inode
->
i_sb
),
struct
btrfs_key
key
;
struct
btrfs_root
*
root
=
BTRFS_I
(
dentry
->
d_parent
->
d_inode
)
->
root
;
key
.
objectid
=
inode
->
i_ino
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_INODE_ITEM_KEY
);
key
.
offset
=
0
;
ret
=
btrfs_insert_dir_item
(
trans
,
root
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
dentry
->
d_parent
->
d_inode
->
i_ino
,
inode
->
i_ino
,
0
);
&
key
,
0
);
if
(
ret
==
0
)
{
dentry
->
d_parent
->
d_inode
->
i_size
+=
dentry
->
d_name
.
len
*
2
;
ret
=
btrfs_update_inode
(
trans
,
btrfs_sb
(
inode
->
i_sb
)
,
ret
=
btrfs_update_inode
(
trans
,
root
,
dentry
->
d_parent
->
d_inode
);
}
check_inode
(
inode
);
...
...
@@ -710,7 +807,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
int
mode
,
struct
nameidata
*
nd
)
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_root
*
root
=
btrfs_sb
(
dir
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
struct
inode
*
inode
;
int
err
;
int
drop_inode
=
0
;
...
...
@@ -747,18 +844,26 @@ out_unlock:
static
int
btrfs_make_empty_dir
(
struct
btrfs_trans_handle
*
trans
,
struct
inode
*
inode
,
struct
inode
*
dir
)
{
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
int
ret
;
char
buf
[
2
];
struct
btrfs_key
key
;
buf
[
0
]
=
'.'
;
buf
[
1
]
=
'.'
;
key
.
objectid
=
inode
->
i_ino
;
key
.
offset
=
0
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_INODE_ITEM_KEY
);
ret
=
btrfs_insert_dir_item
(
trans
,
root
,
buf
,
1
,
inode
->
i_ino
,
inode
->
i_ino
,
1
);
&
key
,
1
);
if
(
ret
)
goto
error
;
key
.
objectid
=
dir
->
i_ino
;
ret
=
btrfs_insert_dir_item
(
trans
,
root
,
buf
,
2
,
inode
->
i_ino
,
dir
->
i_ino
,
1
);
&
key
,
1
);
if
(
ret
)
goto
error
;
inode
->
i_size
=
6
;
...
...
@@ -771,7 +876,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
struct
inode
*
inode
;
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_root
*
root
=
btrfs_sb
(
dir
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
int
err
=
0
;
int
drop_on_err
=
0
;
...
...
@@ -910,7 +1015,7 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
u64
extent_end
=
0
;
u64
objectid
=
inode
->
i_ino
;
struct
btrfs_path
*
path
;
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
btrfs_trans_handle
*
trans
=
NULL
;
struct
btrfs_file_extent_item
*
item
;
struct
btrfs_leaf
*
leaf
;
...
...
@@ -999,7 +1104,7 @@ static int btrfs_get_block(struct inode *inode, sector_t iblock,
struct
buffer_head
*
result
,
int
create
)
{
int
err
;
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
err
=
btrfs_get_block_lock
(
inode
,
iblock
,
result
,
create
);
// err = btrfs_get_block_inline(inode, iblock, result, create);
...
...
@@ -1041,7 +1146,7 @@ static int btrfs_writepage(struct page *page, struct writeback_control *wbc)
static
void
btrfs_truncate
(
struct
inode
*
inode
)
{
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
int
ret
;
struct
btrfs_trans_handle
*
trans
;
...
...
@@ -1208,7 +1313,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
int
err
=
0
;
int
ret
=
0
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
page
*
pages
[
1
];
if
(
file
->
f_flags
&
O_DIRECT
)
...
...
@@ -1365,7 +1470,7 @@ static ssize_t btrfs_file_inline_write(struct file *file,
int err = 0;
int ret = 0;
struct inode *inode = file->f_path.dentry->d_inode;
struct btrfs_root *root =
btrfs_sb(inode->i_sb)
;
struct btrfs_root *root =
BTRFS_I(inode)->root
;
unsigned long page_index;
if (file->f_flags & O_DIRECT)
...
...
@@ -1432,13 +1537,14 @@ static int btrfs_read_actor(read_descriptor_t *desc, struct page *page,
{
char
*
kaddr
;
unsigned
long
left
,
count
=
desc
->
count
;
struct
inode
*
inode
=
page
->
mapping
->
host
;
if
(
size
>
count
)
size
=
count
;
if
(
!
PageChecked
(
page
))
{
/* FIXME, do it per block */
struct
btrfs_root
*
root
=
btrfs_sb
(
page
->
mapping
->
host
->
i_sb
)
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
int
ret
=
btrfs_csum_verify_file_block
(
root
,
page
->
mapping
->
host
->
i_ino
,
page
->
index
<<
PAGE_CACHE_SHIFT
,
...
...
@@ -1662,6 +1768,10 @@ static struct inode_operations btrfs_dir_inode_operations = {
.
rmdir
=
btrfs_rmdir
,
};
static
struct
inode_operations
btrfs_dir_ro_inode_operations
=
{
.
lookup
=
btrfs_lookup
,
};
static
struct
file_operations
btrfs_dir_file_operations
=
{
.
llseek
=
generic_file_llseek
,
.
read
=
generic_read_dir
,
...
...
@@ -1697,13 +1807,21 @@ static int __init init_btrfs_fs(void)
err
=
init_inodecache
();
if
(
err
)
return
err
;
kset_set_kset_s
(
&
btrfs_subsys
,
fs_subsys
);
err
=
subsystem_register
(
&
btrfs_subsys
);
if
(
err
)
goto
out
;
return
register_filesystem
(
&
btrfs_fs_type
);
out:
destroy_inodecache
();
return
err
;
}
static
void
__exit
exit_btrfs_fs
(
void
)
{
destroy_inodecache
();
unregister_filesystem
(
&
btrfs_fs_type
);
subsystem_unregister
(
&
btrfs_subsys
);
printk
(
"btrfs unloaded
\n
"
);
}
...
...
fs/btrfs/transaction.c
View file @
d6e4a428
...
...
@@ -52,6 +52,8 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
kmem_cache_alloc
(
btrfs_trans_handle_cachep
,
GFP_NOFS
);
int
ret
;
/* FIXME, use the right root */
root
=
root
->
fs_info
->
fs_root
;
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
ret
=
join_transaction
(
root
);
BUG_ON
(
ret
);
...
...
@@ -69,6 +71,10 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
struct
btrfs_root
*
root
)
{
struct
btrfs_transaction
*
cur_trans
;
/* FIXME, use the right root */
root
=
root
->
fs_info
->
fs_root
;
WARN_ON
(
trans
->
magic
!=
TRANS_MAGIC
);
WARN_ON
(
trans
->
magic2
!=
TRANS_MAGIC
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
...
...
@@ -148,6 +154,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
struct
btrfs_transaction
*
cur_trans
;
DEFINE_WAIT
(
wait
);
/* FIXME, use the right root */
root
=
root
->
fs_info
->
fs_root
;
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
if
(
trans
->
transaction
->
in_commit
)
{
printk
(
"already in commit!, waiting
\n
"
);
...
...
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