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
Kirill Smelkov
linux
Commits
e06afa83
Commit
e06afa83
authored
May 23, 2007
by
Chris Mason
Committed by
David Woodhouse
May 23, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: rename
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
f9f3c6b6
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
143 additions
and
18 deletions
+143
-18
fs/btrfs/TODO
fs/btrfs/TODO
+1
-0
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+1
-0
fs/btrfs/dir-item.c
fs/btrfs/dir-item.c
+21
-6
fs/btrfs/super.c
fs/btrfs/super.c
+120
-12
No files found.
fs/btrfs/TODO
View file @
e06afa83
...
...
@@ -8,6 +8,7 @@
* Add generation number to key pointer in nodes
* Add generation number to inode
* Add ability to switch a block group from data to metadata or vice versa
* forbid cross subvolume renames and hardlinks
* Release
* Do real tree locking
* Add extent mirroring (backup copies of blocks)
...
...
fs/btrfs/ctree.h
View file @
e06afa83
...
...
@@ -32,6 +32,7 @@ extern struct kmem_cache *btrfs_path_cachep;
#define BTRFS_CSUM_SIZE 32
/* four bytes for CRC32 */
#define BTRFS_CRC32_SIZE 4
#define BTRFS_EMPTY_DIR_SIZE 6
/*
* the key defines the order in the tree, and so it also defines (optimal)
...
...
fs/btrfs/dir-item.c
View file @
e06afa83
...
...
@@ -9,7 +9,9 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_key
*
cpu_key
,
u32
data_size
)
u32
data_size
,
const
char
*
name
,
int
name_len
)
{
int
ret
;
char
*
ptr
;
...
...
@@ -18,6 +20,10 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
cpu_key
,
data_size
);
if
(
ret
==
-
EEXIST
)
{
struct
btrfs_dir_item
*
di
;
di
=
btrfs_match_dir_item_name
(
root
,
path
,
name
,
name_len
);
if
(
di
)
return
ERR_PTR
(
-
EEXIST
);
ret
=
btrfs_extend_item
(
trans
,
root
,
path
,
data_size
);
WARN_ON
(
ret
>
0
);
if
(
ret
)
...
...
@@ -37,6 +43,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
struct
btrfs_key
*
location
,
u8
type
)
{
int
ret
=
0
;
int
ret2
=
0
;
struct
btrfs_path
*
path
;
struct
btrfs_dir_item
*
dir_item
;
char
*
name_ptr
;
...
...
@@ -51,9 +58,12 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
path
=
btrfs_alloc_path
();
btrfs_init_path
(
path
);
data_size
=
sizeof
(
*
dir_item
)
+
name_len
;
dir_item
=
insert_with_overflow
(
trans
,
root
,
path
,
&
key
,
data_size
);
dir_item
=
insert_with_overflow
(
trans
,
root
,
path
,
&
key
,
data_size
,
name
,
name_len
);
if
(
IS_ERR
(
dir_item
))
{
ret
=
PTR_ERR
(
dir_item
);
if
(
ret
==
-
EEXIST
)
goto
second_insert
;
goto
out
;
}
...
...
@@ -66,19 +76,20 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_memcpy
(
root
,
path
->
nodes
[
0
]
->
b_data
,
name_ptr
,
name
,
name_len
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
second_insert:
/* FIXME, use some real flag for selecting the extra index */
if
(
root
==
root
->
fs_info
->
tree_root
)
{
ret
=
0
;
goto
out
;
}
btrfs_release_path
(
root
,
path
);
btrfs_set_key_type
(
&
key
,
BTRFS_DIR_INDEX_KEY
);
key
.
offset
=
location
->
objectid
;
dir_item
=
insert_with_overflow
(
trans
,
root
,
path
,
&
key
,
data_size
);
dir_item
=
insert_with_overflow
(
trans
,
root
,
path
,
&
key
,
data_size
,
name
,
name_len
);
if
(
IS_ERR
(
dir_item
))
{
ret
=
PTR_ERR
(
dir_item
);
ret
2
=
PTR_ERR
(
dir_item
);
goto
out
;
}
btrfs_cpu_key_to_disk
(
&
dir_item
->
location
,
location
);
...
...
@@ -90,7 +101,11 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
out:
btrfs_free_path
(
path
);
return
ret
;
if
(
ret
)
return
ret
;
if
(
ret2
)
return
ret2
;
return
0
;
}
struct
btrfs_dir_item
*
btrfs_lookup_dir_item
(
struct
btrfs_trans_handle
*
trans
,
...
...
fs/btrfs/super.c
View file @
e06afa83
...
...
@@ -375,6 +375,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
struct
btrfs_path
*
path
;
struct
btrfs_key
key
;
struct
btrfs_disk_key
*
found_key
;
u32
found_type
;
struct
btrfs_leaf
*
leaf
;
struct
btrfs_file_extent_item
*
fi
=
NULL
;
u64
extent_start
=
0
;
...
...
@@ -386,12 +387,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
/* FIXME, add redo link to tree so we don't leak on crash */
key
.
objectid
=
inode
->
i_ino
;
key
.
offset
=
(
u64
)
-
1
;
key
.
flags
=
0
;
/*
* use BTRFS_CSUM_ITEM_KEY because it is larger than inline keys
* or extent data
*/
btrfs_set_key_type
(
&
key
,
BTRFS_CSUM_ITEM_KEY
);
key
.
flags
=
(
u32
)
-
1
;
while
(
1
)
{
btrfs_init_path
(
path
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
-
1
,
1
);
...
...
@@ -405,10 +401,13 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
reada_truncate
(
root
,
path
,
inode
->
i_ino
);
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
found_key
=
&
leaf
->
items
[
path
->
slots
[
0
]].
key
;
found_type
=
btrfs_disk_key_type
(
found_key
);
if
(
btrfs_disk_key_objectid
(
found_key
)
!=
inode
->
i_ino
)
break
;
if
(
btrfs_disk_key_type
(
found_key
)
!=
BTRFS_CSUM_ITEM_KEY
&&
btrfs_disk_key_type
(
found_key
)
!=
BTRFS_EXTENT_DATA_KEY
)
if
(
found_type
!=
BTRFS_CSUM_ITEM_KEY
&&
found_type
!=
BTRFS_DIR_ITEM_KEY
&&
found_type
!=
BTRFS_DIR_INDEX_KEY
&&
found_type
!=
BTRFS_EXTENT_DATA_KEY
)
break
;
if
(
btrfs_disk_key_offset
(
found_key
)
<
inode
->
i_size
)
break
;
...
...
@@ -460,10 +459,8 @@ static void btrfs_delete_inode(struct inode *inode)
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
);
}
ret
=
btrfs_truncate_in_trans
(
trans
,
root
,
inode
);
BUG_ON
(
ret
);
btrfs_free_inode
(
trans
,
root
,
inode
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
...
...
@@ -2504,6 +2501,116 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
return
0
;
}
static
int
btrfs_rename
(
struct
inode
*
old_dir
,
struct
dentry
*
old_dentry
,
struct
inode
*
new_dir
,
struct
dentry
*
new_dentry
)
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_root
*
root
=
BTRFS_I
(
old_dir
)
->
root
;
struct
inode
*
new_inode
=
new_dentry
->
d_inode
;
struct
inode
*
old_inode
=
old_dentry
->
d_inode
;
struct
timespec
ctime
=
CURRENT_TIME
;
struct
btrfs_path
*
path
;
struct
btrfs_dir_item
*
di
;
int
ret
;
if
(
S_ISDIR
(
old_inode
->
i_mode
)
&&
new_inode
&&
new_inode
->
i_size
>
BTRFS_EMPTY_DIR_SIZE
)
{
return
-
ENOTEMPTY
;
}
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
new_dir
);
path
=
btrfs_alloc_path
();
if
(
!
path
)
{
ret
=
-
ENOMEM
;
goto
out_fail
;
}
old_dentry
->
d_inode
->
i_nlink
++
;
old_dir
->
i_ctime
=
old_dir
->
i_mtime
=
ctime
;
new_dir
->
i_ctime
=
new_dir
->
i_mtime
=
ctime
;
old_inode
->
i_ctime
=
ctime
;
if
(
S_ISDIR
(
old_inode
->
i_mode
)
&&
old_dir
!=
new_dir
)
{
struct
btrfs_key
*
location
=
&
BTRFS_I
(
new_dir
)
->
location
;
u64
old_parent_oid
;
di
=
btrfs_lookup_dir_item
(
trans
,
root
,
path
,
old_inode
->
i_ino
,
".."
,
2
,
-
1
);
if
(
IS_ERR
(
di
))
{
ret
=
PTR_ERR
(
di
);
goto
out_fail
;
}
if
(
!
di
)
{
ret
=
-
ENOENT
;
goto
out_fail
;
}
old_parent_oid
=
btrfs_disk_key_objectid
(
&
di
->
location
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
if
(
ret
)
{
ret
=
-
EIO
;
goto
out_fail
;
}
btrfs_release_path
(
root
,
path
);
di
=
btrfs_lookup_dir_index_item
(
trans
,
root
,
path
,
old_inode
->
i_ino
,
old_parent_oid
,
".."
,
2
,
-
1
);
if
(
IS_ERR
(
di
))
{
ret
=
PTR_ERR
(
di
);
goto
out_fail
;
}
if
(
!
di
)
{
ret
=
-
ENOENT
;
goto
out_fail
;
}
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
if
(
ret
)
{
ret
=
-
EIO
;
goto
out_fail
;
}
btrfs_release_path
(
root
,
path
);
ret
=
btrfs_insert_dir_item
(
trans
,
root
,
".."
,
2
,
old_inode
->
i_ino
,
location
,
0
);
if
(
ret
)
goto
out_fail
;
}
ret
=
btrfs_add_link
(
trans
,
new_dentry
,
old_inode
);
if
(
ret
==
-
EEXIST
&&
new_inode
)
ret
=
0
;
else
if
(
ret
)
goto
out_fail
;
ret
=
btrfs_unlink_trans
(
trans
,
root
,
old_dir
,
old_dentry
);
if
(
ret
)
goto
out_fail
;
if
(
new_inode
)
{
new_inode
->
i_ctime
=
CURRENT_TIME
;
di
=
btrfs_lookup_dir_index_item
(
trans
,
root
,
path
,
new_dir
->
i_ino
,
new_inode
->
i_ino
,
new_dentry
->
d_name
.
name
,
new_dentry
->
d_name
.
len
,
-
1
);
if
(
di
&&
!
IS_ERR
(
di
))
{
btrfs_del_item
(
trans
,
root
,
path
);
btrfs_release_path
(
root
,
path
);
}
if
(
S_ISDIR
(
new_inode
->
i_mode
))
clear_nlink
(
new_inode
);
else
drop_nlink
(
new_inode
);
btrfs_update_inode
(
trans
,
root
,
new_inode
);
}
out_fail:
btrfs_free_path
(
path
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
return
ret
;
}
static
struct
file_system_type
btrfs_fs_type
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"btrfs"
,
...
...
@@ -2531,6 +2638,7 @@ static struct inode_operations btrfs_dir_inode_operations = {
.
unlink
=
btrfs_unlink
,
.
mkdir
=
btrfs_mkdir
,
.
rmdir
=
btrfs_rmdir
,
.
rename
=
btrfs_rename
,
};
static
struct
inode_operations
btrfs_dir_ro_inode_operations
=
{
...
...
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