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
2b8d99a7
Commit
2b8d99a7
authored
May 24, 2007
by
Chris Mason
Committed by
David Woodhouse
May 24, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: symlinks and hard links
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
e06afa83
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
147 additions
and
16 deletions
+147
-16
fs/btrfs/super.c
fs/btrfs/super.c
+147
-16
No files found.
fs/btrfs/super.c
View file @
2b8d99a7
...
...
@@ -26,11 +26,13 @@ struct btrfs_iget_args {
#define BTRFS_SUPER_MAGIC 0x9123682E
static
struct
inode_operations
btrfs_dir_inode_operations
;
static
struct
inode_operations
btrfs_symlink_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
;
static
struct
address_space_operations
btrfs_aops
;
static
struct
address_space_operations
btrfs_symlink_aops
;
static
struct
file_operations
btrfs_file_operations
;
static
void
btrfs_read_locked_inode
(
struct
inode
*
inode
)
...
...
@@ -103,7 +105,8 @@ static void btrfs_read_locked_inode(struct inode *inode)
inode
->
i_op
=
&
btrfs_dir_inode_operations
;
break
;
case
S_IFLNK
:
// inode->i_op = &page_symlink_inode_operations;
inode
->
i_op
=
&
btrfs_symlink_inode_operations
;
inode
->
i_mapping
->
a_ops
=
&
btrfs_symlink_aops
;
break
;
}
return
;
...
...
@@ -940,6 +943,41 @@ out_unlock:
return
err
;
}
static
int
btrfs_link
(
struct
dentry
*
old_dentry
,
struct
inode
*
dir
,
struct
dentry
*
dentry
)
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
struct
inode
*
inode
=
old_dentry
->
d_inode
;
int
err
;
int
drop_inode
=
0
;
if
(
inode
->
i_nlink
==
0
)
return
-
ENOENT
;
inc_nlink
(
inode
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
dir
);
atomic_inc
(
&
inode
->
i_count
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
);
if
(
err
)
drop_inode
=
1
;
dir
->
i_sb
->
s_dirt
=
1
;
btrfs_update_inode_block_group
(
trans
,
dir
);
btrfs_update_inode
(
trans
,
root
,
inode
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
if
(
drop_inode
)
{
inode_dec_link_count
(
inode
);
iput
(
inode
);
}
btrfs_btree_balance_dirty
(
root
);
return
err
;
}
static
int
btrfs_make_empty_dir
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
u64
dirid
)
...
...
@@ -2577,33 +2615,25 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
}
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
);
}
ret
=
btrfs_unlink_trans
(
trans
,
root
,
new_dir
,
new_dentry
);
if
(
ret
)
goto
out_fail
;
if
(
S_ISDIR
(
new_inode
->
i_mode
))
clear_nlink
(
new_inode
);
else
drop_nlink
(
new_inode
);
btrfs_update_inode
(
trans
,
root
,
new_inode
);
}
ret
=
btrfs_add_link
(
trans
,
new_dentry
,
old_inode
);
if
(
ret
)
goto
out_fail
;
out_fail:
btrfs_free_path
(
path
);
btrfs_end_transaction
(
trans
,
root
);
...
...
@@ -2611,6 +2641,94 @@ out_fail:
return
ret
;
}
static
int
btrfs_symlink
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
const
char
*
symname
)
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
struct
btrfs_path
*
path
;
struct
btrfs_key
key
;
struct
inode
*
inode
;
int
err
;
int
drop_inode
=
0
;
u64
objectid
;
int
name_len
;
int
datasize
;
char
*
ptr
;
struct
btrfs_file_extent_item
*
ei
;
name_len
=
strlen
(
symname
)
+
1
;
if
(
name_len
>
BTRFS_MAX_INLINE_DATA_SIZE
(
root
))
return
-
ENAMETOOLONG
;
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
)
{
err
=
-
ENOSPC
;
goto
out_unlock
;
}
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
BTRFS_I
(
dir
)
->
block_group
,
S_IFLNK
|
S_IRWXUGO
);
err
=
PTR_ERR
(
inode
);
if
(
IS_ERR
(
inode
))
goto
out_unlock
;
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
);
if
(
err
)
drop_inode
=
1
;
else
{
inode
->
i_mapping
->
a_ops
=
&
btrfs_aops
;
inode
->
i_fop
=
&
btrfs_file_operations
;
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
);
if
(
drop_inode
)
goto
out_unlock
;
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
key
.
objectid
=
inode
->
i_ino
;
key
.
offset
=
0
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_EXTENT_DATA_KEY
);
datasize
=
btrfs_file_extent_calc_inline_size
(
name_len
);
err
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
&
key
,
datasize
);
BUG_ON
(
err
);
ei
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
btrfs_set_file_extent_generation
(
ei
,
trans
->
transid
);
btrfs_set_file_extent_type
(
ei
,
BTRFS_FILE_EXTENT_INLINE
);
ptr
=
btrfs_file_extent_inline_start
(
ei
);
btrfs_memcpy
(
root
,
path
->
nodes
[
0
]
->
b_data
,
ptr
,
symname
,
name_len
);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_free_path
(
path
);
inode
->
i_op
=
&
btrfs_symlink_inode_operations
;
inode
->
i_mapping
->
a_ops
=
&
btrfs_symlink_aops
;
inode
->
i_size
=
name_len
-
1
;
btrfs_update_inode
(
trans
,
root
,
inode
);
err
=
0
;
out_unlock:
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
if
(
drop_inode
)
{
inode_dec_link_count
(
inode
);
iput
(
inode
);
}
btrfs_btree_balance_dirty
(
root
);
return
err
;
}
static
struct
file_system_type
btrfs_fs_type
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"btrfs"
,
...
...
@@ -2636,9 +2754,11 @@ static struct inode_operations btrfs_dir_inode_operations = {
.
lookup
=
btrfs_lookup
,
.
create
=
btrfs_create
,
.
unlink
=
btrfs_unlink
,
.
link
=
btrfs_link
,
.
mkdir
=
btrfs_mkdir
,
.
rmdir
=
btrfs_rmdir
,
.
rename
=
btrfs_rename
,
.
symlink
=
btrfs_symlink
,
};
static
struct
inode_operations
btrfs_dir_ro_inode_operations
=
{
...
...
@@ -2660,6 +2780,11 @@ static struct address_space_operations btrfs_aops = {
.
commit_write
=
btrfs_commit_write
,
};
static
struct
address_space_operations
btrfs_symlink_aops
=
{
.
readpage
=
btrfs_readpage
,
.
writepage
=
btrfs_writepage
,
};
static
struct
inode_operations
btrfs_file_inode_operations
=
{
.
truncate
=
btrfs_truncate
,
.
getattr
=
btrfs_getattr
,
...
...
@@ -2676,6 +2801,12 @@ static struct file_operations btrfs_file_operations = {
.
fsync
=
btrfs_sync_file
,
};
static
struct
inode_operations
btrfs_symlink_inode_operations
=
{
.
readlink
=
generic_readlink
,
.
follow_link
=
page_follow_link_light
,
.
put_link
=
page_put_link
,
};
static
int
__init
init_btrfs_fs
(
void
)
{
int
err
;
...
...
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