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
c5739bba
Commit
c5739bba
authored
Apr 10, 2007
by
Chris Mason
Committed by
David Woodhouse
Apr 10, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: snapshot progress
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
0f7d52f4
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
183 additions
and
12 deletions
+183
-12
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+14
-1
fs/btrfs/dir-item.c
fs/btrfs/dir-item.c
+4
-2
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+0
-4
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+6
-0
fs/btrfs/ioctl.h
fs/btrfs/ioctl.h
+13
-0
fs/btrfs/root-tree.c
fs/btrfs/root-tree.c
+15
-1
fs/btrfs/super.c
fs/btrfs/super.c
+131
-4
No files found.
fs/btrfs/ctree.h
View file @
c5739bba
...
...
@@ -227,7 +227,7 @@ struct btrfs_csum_item {
}
__attribute__
((
__packed__
));
struct
btrfs_inode_map_item
{
struct
btrfs_disk_key
key
;
u32
refs
;
}
__attribute__
((
__packed__
));
struct
crypto_hash
;
...
...
@@ -883,6 +883,17 @@ static inline void btrfs_set_file_extent_num_blocks(struct
e
->
num_blocks
=
cpu_to_le64
(
val
);
}
static
inline
u32
btrfs_inode_map_refs
(
struct
btrfs_inode_map_item
*
m
)
{
return
le32_to_cpu
(
m
->
refs
);
}
static
inline
void
btrfs_set_inode_map_refs
(
struct
btrfs_inode_map_item
*
m
,
u32
val
)
{
m
->
refs
=
cpu_to_le32
(
val
);
}
static
inline
struct
btrfs_root
*
btrfs_sb
(
struct
super_block
*
sb
)
{
return
sb
->
s_fs_info
;
...
...
@@ -925,6 +936,8 @@ static inline void btrfs_mark_buffer_dirty(struct buffer_head *bh)
btrfs_item_offset((leaf)->items + (slot))))
/* extent-item.c */
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
);
int
btrfs_alloc_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
...
...
fs/btrfs/dir-item.c
View file @
c5739bba
...
...
@@ -55,12 +55,14 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_dir_flags
(
dir_item
,
0
);
btrfs_set_dir_name_len
(
dir_item
,
name_len
);
name_ptr
=
(
char
*
)(
dir_item
+
1
);
btrfs_memcpy
(
root
,
path
->
nodes
[
0
]
->
b_data
,
name_ptr
,
name
,
name_len
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
/* 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
);
...
...
fs/btrfs/disk-io.c
View file @
c5739bba
...
...
@@ -16,10 +16,6 @@ static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf)
if
(
buf
->
b_blocknr
!=
btrfs_header_blocknr
(
&
node
->
header
))
{
BUG
();
}
if
(
root
->
node
&&
btrfs_header_parentid
(
&
node
->
header
)
!=
btrfs_header_parentid
(
btrfs_buffer_header
(
root
->
node
)))
{
BUG
();
}
return
0
;
}
...
...
fs/btrfs/extent-tree.c
View file @
c5739bba
...
...
@@ -77,6 +77,12 @@ static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
return
0
;
}
int
btrfs_inc_root_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
)
{
return
inc_block_ref
(
trans
,
root
,
root
->
node
->
b_blocknr
,
1
);
}
int
btrfs_inc_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
buffer_head
*
buf
)
{
...
...
fs/btrfs/ioctl.h
0 → 100644
View file @
c5739bba
#ifndef __IOCTL_
#define __IOCTL_
#include <linux/ioctl.h>
#define BTRFS_IOCTL_MAGIC 0x94
#define BTRFS_VOL_NAME_MAX 255
struct
btrfs_ioctl_vol_args
{
char
name
[
BTRFS_VOL_NAME_MAX
+
1
];
};
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args)
#endif
fs/btrfs/root-tree.c
View file @
c5739bba
...
...
@@ -83,6 +83,8 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
{
struct
btrfs_path
*
path
;
int
ret
;
u32
refs
;
struct
btrfs_root_item
*
ri
;
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
...
...
@@ -91,7 +93,19 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
if
(
ret
<
0
)
goto
out
;
BUG_ON
(
ret
!=
0
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
ri
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_root_item
);
refs
=
btrfs_root_refs
(
ri
);
BUG_ON
(
refs
==
0
);
if
(
refs
==
1
)
{
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
printk
(
"deleting root %Lu %Lu %u
\n
"
,
key
->
objectid
,
key
->
offset
,
key
->
flags
);
}
else
{
btrfs_set_root_refs
(
ri
,
refs
-
1
);
printk
(
"ref now %u root %Lu %Lu %u
\n
"
,
refs
-
1
,
key
->
objectid
,
key
->
offset
,
key
->
flags
);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
}
out:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
...
...
fs/btrfs/super.c
View file @
c5739bba
...
...
@@ -15,6 +15,7 @@
#include "disk-io.h"
#include "transaction.h"
#include "btrfs_inode.h"
#include "ioctl.h"
void
btrfs_fsinfo_release
(
struct
kobject
*
obj
)
{
...
...
@@ -27,6 +28,11 @@ struct kobj_type btrfs_fsinfo_ktype = {
.
release
=
btrfs_fsinfo_release
,
};
struct
btrfs_iget_args
{
u64
ino
;
struct
btrfs_root
*
root
;
};
decl_subsys
(
btrfs
,
&
btrfs_fsinfo_ktype
,
NULL
);
#define BTRFS_SUPER_MAGIC 0x9123682E
...
...
@@ -461,6 +467,34 @@ int fixup_tree_root_location(struct btrfs_root *root,
return
0
;
}
int
btrfs_init_locked_inode
(
struct
inode
*
inode
,
void
*
p
)
{
struct
btrfs_iget_args
*
args
=
p
;
inode
->
i_ino
=
args
->
ino
;
BTRFS_I
(
inode
)
->
root
=
args
->
root
;
return
0
;
}
int
btrfs_find_actor
(
struct
inode
*
inode
,
void
*
opaque
)
{
struct
btrfs_iget_args
*
args
=
opaque
;
return
(
args
->
ino
==
inode
->
i_ino
&&
args
->
root
==
BTRFS_I
(
inode
)
->
root
);
}
struct
inode
*
btrfs_iget_locked
(
struct
super_block
*
s
,
u64
objectid
,
struct
btrfs_root
*
root
)
{
struct
inode
*
inode
;
struct
btrfs_iget_args
args
;
args
.
ino
=
objectid
;
args
.
root
=
root
;
inode
=
iget5_locked
(
s
,
objectid
,
btrfs_find_actor
,
btrfs_init_locked_inode
,
(
void
*
)
&
args
);
return
inode
;
}
static
struct
dentry
*
btrfs_lookup
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
struct
nameidata
*
nd
)
...
...
@@ -486,7 +520,8 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
return
ERR_PTR
(
ret
);
if
(
ret
>
0
)
return
ERR_PTR
(
-
ENOENT
);
inode
=
iget_locked
(
dir
->
i_sb
,
location
.
objectid
);
inode
=
btrfs_iget_locked
(
dir
->
i_sb
,
location
.
objectid
,
sub_root
);
if
(
!
inode
)
return
ERR_PTR
(
-
EACCES
);
if
(
inode
->
i_state
&
I_NEW
)
{
...
...
@@ -495,7 +530,7 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
&
root
->
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
sub_root
,
sub_root
);
printk
(
"adding new root for inode %lu
\n
"
,
inode
->
i_ino
);
printk
(
"adding new root for inode %lu
root %p (found %p)
\n
"
,
inode
->
i_ino
,
sub_root
,
BTRFS_I
(
inode
)
->
root
);
igrab
(
inode
);
sub_root
->
inode
=
inode
;
}
...
...
@@ -630,7 +665,8 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
btrfs_super_total_blocks
(
disk_super
),
btrfs_super_root_dir
(
disk_super
));
inode
=
iget_locked
(
sb
,
btrfs_super_root_dir
(
disk_super
));
inode
=
btrfs_iget_locked
(
sb
,
btrfs_super_root_dir
(
disk_super
),
tree_root
);
bi
=
BTRFS_I
(
inode
);
bi
->
location
.
objectid
=
inode
->
i_ino
;
bi
->
location
.
offset
=
0
;
...
...
@@ -750,7 +786,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
inode
->
i_mode
=
mode
;
inode
->
i_ino
=
objectid
;
inode
->
i_blocks
=
0
;
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
CURRENT_TIME
_SEC
;
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
CURRENT_TIME
;
fill_inode_item
(
&
inode_item
,
inode
);
key
->
objectid
=
objectid
;
...
...
@@ -1650,6 +1686,95 @@ static ssize_t btrfs_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
return
retval
;
}
static
int
create_snapshot
(
struct
btrfs_root
*
root
,
char
*
name
,
int
namelen
)
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_key
key
;
struct
btrfs_root_item
new_root_item
;
int
ret
;
u64
objectid
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
BUG_ON
(
!
trans
);
ret
=
btrfs_update_inode
(
trans
,
root
,
root
->
inode
);
BUG_ON
(
ret
);
ret
=
btrfs_find_free_objectid
(
trans
,
root
,
0
,
&
objectid
);
BUG_ON
(
ret
);
memset
(
&
new_root_item
,
0
,
sizeof
(
new_root_item
));
memcpy
(
&
new_root_item
,
&
root
->
root_item
,
sizeof
(
new_root_item
));
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
);
key
.
objectid
=
objectid
;
key
.
offset
=
1
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_ROOT_ITEM_KEY
);
btrfs_set_root_blocknr
(
&
new_root_item
,
root
->
node
->
b_blocknr
);
ret
=
btrfs_insert_root
(
trans
,
root
->
fs_info
->
tree_root
,
&
key
,
&
new_root_item
);
BUG_ON
(
ret
);
printk
(
"adding snapshot name %.*s root %Lu %Lu %u
\n
"
,
namelen
,
name
,
key
.
objectid
,
key
.
offset
,
key
.
flags
);
/*
* insert the directory item
*/
key
.
offset
=
(
u64
)
-
1
;
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
);
BUG_ON
(
ret
);
ret
=
btrfs_inc_root_ref
(
trans
,
root
);
BUG_ON
(
ret
);
ret
=
btrfs_commit_transaction
(
trans
,
root
);
BUG_ON
(
ret
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
return
0
;
}
static
int
btrfs_ioctl
(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
btrfs_ioctl_vol_args
vol_args
;
int
ret
;
int
namelen
;
if
(
!
root
->
ref_cows
)
return
-
EINVAL
;
switch
(
cmd
)
{
case
BTRFS_IOC_SNAP_CREATE
:
if
(
copy_from_user
(
&
vol_args
,
(
struct
btrfs_ioctl_vol_args
__user
*
)
arg
,
sizeof
(
vol_args
)))
return
-
EFAULT
;
namelen
=
strlen
(
vol_args
.
name
);
if
(
namelen
>
BTRFS_VOL_NAME_MAX
)
return
-
EINVAL
;
ret
=
create_snapshot
(
root
,
vol_args
.
name
,
namelen
);
WARN_ON
(
ret
);
break
;
default:
return
-
ENOTTY
;
}
return
0
;
}
static
struct
kmem_cache
*
btrfs_inode_cachep
;
struct
kmem_cache
*
btrfs_trans_handle_cachep
;
struct
kmem_cache
*
btrfs_transaction_cachep
;
...
...
@@ -1781,6 +1906,7 @@ static struct file_operations btrfs_dir_file_operations = {
.
llseek
=
generic_file_llseek
,
.
read
=
generic_read_dir
,
.
readdir
=
btrfs_readdir
,
.
ioctl
=
btrfs_ioctl
,
};
static
struct
address_space_operations
btrfs_aops
=
{
...
...
@@ -1803,6 +1929,7 @@ static struct file_operations btrfs_file_operations = {
.
write
=
btrfs_file_write
,
.
mmap
=
generic_file_mmap
,
.
open
=
generic_file_open
,
.
ioctl
=
btrfs_ioctl
,
};
static
int
__init
init_btrfs_fs
(
void
)
...
...
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