Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
26c79f6b
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
26c79f6b
编写于
1月 16, 2011
作者:
C
Chris Mason
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'readonly-snapshots' of
git://repo.or.cz/linux-btrfs-devel
into btrfs-38
上级
65e5341b
0caa102d
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
195 addition
and
49 deletion
+195
-49
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+7
-0
fs/btrfs/inode.c
fs/btrfs/inode.c
+8
-0
fs/btrfs/ioctl.c
fs/btrfs/ioctl.c
+150
-49
fs/btrfs/ioctl.h
fs/btrfs/ioctl.h
+3
-0
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+8
-0
fs/btrfs/transaction.h
fs/btrfs/transaction.h
+1
-0
fs/btrfs/xattr.c
fs/btrfs/xattr.c
+18
-0
未找到文件。
fs/btrfs/ctree.h
浏览文件 @
26c79f6b
...
...
@@ -597,6 +597,8 @@ struct btrfs_dir_item {
u8
type
;
}
__attribute__
((
__packed__
));
#define BTRFS_ROOT_SUBVOL_RDONLY (1ULL << 0)
struct
btrfs_root_item
{
struct
btrfs_inode_item
inode
;
__le64
generation
;
...
...
@@ -1893,6 +1895,11 @@ BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, byte_limit, 64);
BTRFS_SETGET_STACK_FUNCS
(
root_last_snapshot
,
struct
btrfs_root_item
,
last_snapshot
,
64
);
static
inline
bool
btrfs_root_readonly
(
struct
btrfs_root
*
root
)
{
return
root
->
root_item
.
flags
&
BTRFS_ROOT_SUBVOL_RDONLY
;
}
/* struct btrfs_super_block */
BTRFS_SETGET_STACK_FUNCS
(
super_bytenr
,
struct
btrfs_super_block
,
bytenr
,
64
);
...
...
fs/btrfs/inode.c
浏览文件 @
26c79f6b
...
...
@@ -3671,8 +3671,12 @@ static int btrfs_setattr_size(struct inode *inode, struct iattr *attr)
static
int
btrfs_setattr
(
struct
dentry
*
dentry
,
struct
iattr
*
attr
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
int
err
;
if
(
btrfs_root_readonly
(
root
))
return
-
EROFS
;
err
=
inode_change_ok
(
inode
,
attr
);
if
(
err
)
return
err
;
...
...
@@ -7206,6 +7210,10 @@ static int btrfs_set_page_dirty(struct page *page)
static
int
btrfs_permission
(
struct
inode
*
inode
,
int
mask
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
if
(
btrfs_root_readonly
(
root
)
&&
(
mask
&
MAY_WRITE
))
return
-
EROFS
;
if
((
BTRFS_I
(
inode
)
->
flags
&
BTRFS_INODE_READONLY
)
&&
(
mask
&
MAY_WRITE
))
return
-
EACCES
;
return
generic_permission
(
inode
,
mask
,
btrfs_check_acl
);
...
...
fs/btrfs/ioctl.c
浏览文件 @
26c79f6b
...
...
@@ -147,6 +147,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
unsigned
int
flags
,
oldflags
;
int
ret
;
if
(
btrfs_root_readonly
(
root
))
return
-
EROFS
;
if
(
copy_from_user
(
&
flags
,
arg
,
sizeof
(
flags
)))
return
-
EFAULT
;
...
...
@@ -360,7 +363,8 @@ static noinline int create_subvol(struct btrfs_root *root,
}
static
int
create_snapshot
(
struct
btrfs_root
*
root
,
struct
dentry
*
dentry
,
char
*
name
,
int
namelen
,
u64
*
async_transid
)
char
*
name
,
int
namelen
,
u64
*
async_transid
,
bool
readonly
)
{
struct
inode
*
inode
;
struct
dentry
*
parent
;
...
...
@@ -378,6 +382,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
btrfs_init_block_rsv
(
&
pending_snapshot
->
block_rsv
);
pending_snapshot
->
dentry
=
dentry
;
pending_snapshot
->
root
=
root
;
pending_snapshot
->
readonly
=
readonly
;
trans
=
btrfs_start_transaction
(
root
->
fs_info
->
extent_root
,
5
);
if
(
IS_ERR
(
trans
))
{
...
...
@@ -509,7 +514,7 @@ static inline int btrfs_may_create(struct inode *dir, struct dentry *child)
static
noinline
int
btrfs_mksubvol
(
struct
path
*
parent
,
char
*
name
,
int
namelen
,
struct
btrfs_root
*
snap_src
,
u64
*
async_transid
)
u64
*
async_transid
,
bool
readonly
)
{
struct
inode
*
dir
=
parent
->
dentry
->
d_inode
;
struct
dentry
*
dentry
;
...
...
@@ -541,7 +546,7 @@ static noinline int btrfs_mksubvol(struct path *parent,
if
(
snap_src
)
{
error
=
create_snapshot
(
snap_src
,
dentry
,
name
,
namelen
,
async_transid
);
name
,
namelen
,
async_transid
,
readonly
);
}
else
{
error
=
create_subvol
(
BTRFS_I
(
dir
)
->
root
,
dentry
,
name
,
namelen
,
async_transid
);
...
...
@@ -901,7 +906,8 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
char
*
name
,
unsigned
long
fd
,
int
subvol
,
u64
*
transid
)
u64
*
transid
,
bool
readonly
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
fdentry
(
file
)
->
d_inode
)
->
root
;
struct
file
*
src_file
;
...
...
@@ -919,7 +925,7 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
if
(
subvol
)
{
ret
=
btrfs_mksubvol
(
&
file
->
f_path
,
name
,
namelen
,
NULL
,
transid
);
NULL
,
transid
,
readonly
);
}
else
{
struct
inode
*
src_inode
;
src_file
=
fget
(
fd
);
...
...
@@ -938,7 +944,7 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
}
ret
=
btrfs_mksubvol
(
&
file
->
f_path
,
name
,
namelen
,
BTRFS_I
(
src_inode
)
->
root
,
transid
);
transid
,
readonly
);
fput
(
src_file
);
}
out:
...
...
@@ -946,58 +952,139 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
}
static
noinline
int
btrfs_ioctl_snap_create
(
struct
file
*
file
,
void
__user
*
arg
,
int
subvol
,
int
v2
)
void
__user
*
arg
,
int
subvol
)
{
struct
btrfs_ioctl_vol_args
*
vol_args
=
NULL
;
struct
btrfs_ioctl_vol_args_v2
*
vol_args_v2
=
NULL
;
char
*
name
;
u64
fd
;
struct
btrfs_ioctl_vol_args
*
vol_args
;
int
ret
;
if
(
v2
)
{
u64
transid
=
0
;
u64
*
ptr
=
NULL
;
vol_args_v2
=
memdup_user
(
arg
,
sizeof
(
*
vol_args_v2
));
if
(
IS_ERR
(
vol_args_v2
))
return
PTR_ERR
(
vol_args_v2
);
vol_args
=
memdup_user
(
arg
,
sizeof
(
*
vol_args
));
if
(
IS_ERR
(
vol_args
))
return
PTR_ERR
(
vol_args
);
vol_args
->
name
[
BTRFS_PATH_NAME_MAX
]
=
'\0'
;
if
(
vol_args_v2
->
flags
&
~
BTRFS_SUBVOL_CREATE_ASYNC
)
{
ret
=
-
EINVAL
;
goto
out
;
}
ret
=
btrfs_ioctl_snap_create_transid
(
file
,
vol_args
->
name
,
vol_args
->
fd
,
subvol
,
NULL
,
false
);
name
=
vol_args_v2
->
name
;
fd
=
vol_args_v2
->
fd
;
vol_args_v2
->
name
[
BTRFS_SUBVOL_NAME_MAX
]
=
'\0'
;
kfree
(
vol_args
)
;
return
ret
;
}
if
(
vol_args_v2
->
flags
&
BTRFS_SUBVOL_CREATE_ASYNC
)
ptr
=
&
transid
;
static
noinline
int
btrfs_ioctl_snap_create_v2
(
struct
file
*
file
,
void
__user
*
arg
,
int
subvol
)
{
struct
btrfs_ioctl_vol_args_v2
*
vol_args
;
int
ret
;
u64
transid
=
0
;
u64
*
ptr
=
NULL
;
bool
readonly
=
false
;
ret
=
btrfs_ioctl_snap_create_transid
(
file
,
name
,
fd
,
subvol
,
ptr
);
vol_args
=
memdup_user
(
arg
,
sizeof
(
*
vol_args
));
if
(
IS_ERR
(
vol_args
))
return
PTR_ERR
(
vol_args
);
vol_args
->
name
[
BTRFS_SUBVOL_NAME_MAX
]
=
'\0'
;
if
(
ret
==
0
&&
ptr
&&
copy_to_user
(
arg
+
offsetof
(
struct
btrfs_ioctl_vol_args_v2
,
transid
),
ptr
,
sizeof
(
*
ptr
)))
ret
=
-
EFAULT
;
}
else
{
vol_args
=
memdup_user
(
arg
,
sizeof
(
*
vol_args
));
if
(
IS_ERR
(
vol_args
))
return
PTR_ERR
(
vol_args
);
name
=
vol_args
->
name
;
fd
=
vol_args
->
fd
;
vol_args
->
name
[
BTRFS_PATH_NAME_MAX
]
=
'\0'
;
ret
=
btrfs_ioctl_snap_create_transid
(
file
,
name
,
fd
,
subvol
,
NULL
);
if
(
vol_args
->
flags
&
~
(
BTRFS_SUBVOL_CREATE_ASYNC
|
BTRFS_SUBVOL_RDONLY
))
{
ret
=
-
EOPNOTSUPP
;
goto
out
;
}
if
(
vol_args
->
flags
&
BTRFS_SUBVOL_CREATE_ASYNC
)
ptr
=
&
transid
;
if
(
vol_args
->
flags
&
BTRFS_SUBVOL_RDONLY
)
readonly
=
true
;
ret
=
btrfs_ioctl_snap_create_transid
(
file
,
vol_args
->
name
,
vol_args
->
fd
,
subvol
,
ptr
,
readonly
);
if
(
ret
==
0
&&
ptr
&&
copy_to_user
(
arg
+
offsetof
(
struct
btrfs_ioctl_vol_args_v2
,
transid
),
ptr
,
sizeof
(
*
ptr
)))
ret
=
-
EFAULT
;
out:
kfree
(
vol_args
);
kfree
(
vol_args_v2
);
return
ret
;
}
static
noinline
int
btrfs_ioctl_subvol_getflags
(
struct
file
*
file
,
void
__user
*
arg
)
{
struct
inode
*
inode
=
fdentry
(
file
)
->
d_inode
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
int
ret
=
0
;
u64
flags
=
0
;
if
(
inode
->
i_ino
!=
BTRFS_FIRST_FREE_OBJECTID
)
return
-
EINVAL
;
down_read
(
&
root
->
fs_info
->
subvol_sem
);
if
(
btrfs_root_readonly
(
root
))
flags
|=
BTRFS_SUBVOL_RDONLY
;
up_read
(
&
root
->
fs_info
->
subvol_sem
);
if
(
copy_to_user
(
arg
,
&
flags
,
sizeof
(
flags
)))
ret
=
-
EFAULT
;
return
ret
;
}
static
noinline
int
btrfs_ioctl_subvol_setflags
(
struct
file
*
file
,
void
__user
*
arg
)
{
struct
inode
*
inode
=
fdentry
(
file
)
->
d_inode
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
btrfs_trans_handle
*
trans
;
u64
root_flags
;
u64
flags
;
int
ret
=
0
;
if
(
root
->
fs_info
->
sb
->
s_flags
&
MS_RDONLY
)
return
-
EROFS
;
if
(
inode
->
i_ino
!=
BTRFS_FIRST_FREE_OBJECTID
)
return
-
EINVAL
;
if
(
copy_from_user
(
&
flags
,
arg
,
sizeof
(
flags
)))
return
-
EFAULT
;
if
(
flags
&
~
BTRFS_SUBVOL_CREATE_ASYNC
)
return
-
EINVAL
;
if
(
flags
&
~
BTRFS_SUBVOL_RDONLY
)
return
-
EOPNOTSUPP
;
down_write
(
&
root
->
fs_info
->
subvol_sem
);
/* nothing to do */
if
(
!!
(
flags
&
BTRFS_SUBVOL_RDONLY
)
==
btrfs_root_readonly
(
root
))
goto
out
;
root_flags
=
btrfs_root_flags
(
&
root
->
root_item
);
if
(
flags
&
BTRFS_SUBVOL_RDONLY
)
btrfs_set_root_flags
(
&
root
->
root_item
,
root_flags
|
BTRFS_ROOT_SUBVOL_RDONLY
);
else
btrfs_set_root_flags
(
&
root
->
root_item
,
root_flags
&
~
BTRFS_ROOT_SUBVOL_RDONLY
);
trans
=
btrfs_start_transaction
(
root
,
1
);
if
(
IS_ERR
(
trans
))
{
ret
=
PTR_ERR
(
trans
);
goto
out_reset
;
}
ret
=
btrfs_update_root
(
trans
,
root
,
&
root
->
root_key
,
&
root
->
root_item
);
btrfs_commit_transaction
(
trans
,
root
);
out_reset:
if
(
ret
)
btrfs_set_root_flags
(
&
root
->
root_item
,
root_flags
);
out:
up_write
(
&
root
->
fs_info
->
subvol_sem
);
return
ret
;
}
...
...
@@ -1509,6 +1596,9 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
struct
btrfs_ioctl_defrag_range_args
*
range
;
int
ret
;
if
(
btrfs_root_readonly
(
root
))
return
-
EROFS
;
ret
=
mnt_want_write
(
file
->
f_path
.
mnt
);
if
(
ret
)
return
ret
;
...
...
@@ -1637,6 +1727,9 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
if
(
!
(
file
->
f_mode
&
FMODE_WRITE
)
||
(
file
->
f_flags
&
O_APPEND
))
return
-
EINVAL
;
if
(
btrfs_root_readonly
(
root
))
return
-
EROFS
;
ret
=
mnt_want_write
(
file
->
f_path
.
mnt
);
if
(
ret
)
return
ret
;
...
...
@@ -1958,6 +2051,10 @@ static long btrfs_ioctl_trans_start(struct file *file)
if
(
file
->
private_data
)
goto
out
;
ret
=
-
EROFS
;
if
(
btrfs_root_readonly
(
root
))
goto
out
;
ret
=
mnt_want_write
(
file
->
f_path
.
mnt
);
if
(
ret
)
goto
out
;
...
...
@@ -2257,13 +2354,17 @@ long btrfs_ioctl(struct file *file, unsigned int
case
FS_IOC_GETVERSION
:
return
btrfs_ioctl_getversion
(
file
,
argp
);
case
BTRFS_IOC_SNAP_CREATE
:
return
btrfs_ioctl_snap_create
(
file
,
argp
,
0
,
0
);
return
btrfs_ioctl_snap_create
(
file
,
argp
,
0
);
case
BTRFS_IOC_SNAP_CREATE_V2
:
return
btrfs_ioctl_snap_create
(
file
,
argp
,
0
,
1
);
return
btrfs_ioctl_snap_create
_v2
(
file
,
argp
,
0
);
case
BTRFS_IOC_SUBVOL_CREATE
:
return
btrfs_ioctl_snap_create
(
file
,
argp
,
1
,
0
);
return
btrfs_ioctl_snap_create
(
file
,
argp
,
1
);
case
BTRFS_IOC_SNAP_DESTROY
:
return
btrfs_ioctl_snap_destroy
(
file
,
argp
);
case
BTRFS_IOC_SUBVOL_GETFLAGS
:
return
btrfs_ioctl_subvol_getflags
(
file
,
argp
);
case
BTRFS_IOC_SUBVOL_SETFLAGS
:
return
btrfs_ioctl_subvol_setflags
(
file
,
argp
);
case
BTRFS_IOC_DEFAULT_SUBVOL
:
return
btrfs_ioctl_default_subvol
(
file
,
argp
);
case
BTRFS_IOC_DEFRAG
:
...
...
fs/btrfs/ioctl.h
浏览文件 @
26c79f6b
...
...
@@ -31,6 +31,7 @@ struct btrfs_ioctl_vol_args {
};
#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0)
#define BTRFS_SUBVOL_RDONLY (1ULL << 1)
#define BTRFS_SUBVOL_NAME_MAX 4039
struct
btrfs_ioctl_vol_args_v2
{
...
...
@@ -193,4 +194,6 @@ struct btrfs_ioctl_space_args {
#define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
struct btrfs_ioctl_vol_args_v2)
#define BTRFS_IOC_SUBVOL_GETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 25, __u64)
#define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64)
#endif
fs/btrfs/transaction.c
浏览文件 @
26c79f6b
...
...
@@ -910,6 +910,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
u64
to_reserve
=
0
;
u64
index
=
0
;
u64
objectid
;
u64
root_flags
;
new_root_item
=
kmalloc
(
sizeof
(
*
new_root_item
),
GFP_NOFS
);
if
(
!
new_root_item
)
{
...
...
@@ -967,6 +968,13 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
btrfs_set_root_last_snapshot
(
&
root
->
root_item
,
trans
->
transid
);
memcpy
(
new_root_item
,
&
root
->
root_item
,
sizeof
(
*
new_root_item
));
root_flags
=
btrfs_root_flags
(
new_root_item
);
if
(
pending
->
readonly
)
root_flags
|=
BTRFS_ROOT_SUBVOL_RDONLY
;
else
root_flags
&=
~
BTRFS_ROOT_SUBVOL_RDONLY
;
btrfs_set_root_flags
(
new_root_item
,
root_flags
);
old
=
btrfs_lock_root_node
(
root
);
btrfs_cow_block
(
trans
,
root
,
old
,
NULL
,
0
,
&
old
);
btrfs_set_lock_blocking
(
old
);
...
...
fs/btrfs/transaction.h
浏览文件 @
26c79f6b
...
...
@@ -62,6 +62,7 @@ struct btrfs_pending_snapshot {
struct
btrfs_block_rsv
block_rsv
;
/* extra metadata reseration for relocation */
int
error
;
bool
readonly
;
struct
list_head
list
;
};
...
...
fs/btrfs/xattr.c
浏览文件 @
26c79f6b
...
...
@@ -316,6 +316,15 @@ ssize_t btrfs_getxattr(struct dentry *dentry, const char *name,
int
btrfs_setxattr
(
struct
dentry
*
dentry
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
dentry
->
d_inode
)
->
root
;
/*
* The permission on security.* and system.* is not checked
* in permission().
*/
if
(
btrfs_root_readonly
(
root
))
return
-
EROFS
;
/*
* If this is a request for a synthetic attribute in the system.*
* namespace use the generic infrastructure to resolve a handler
...
...
@@ -336,6 +345,15 @@ int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value,
int
btrfs_removexattr
(
struct
dentry
*
dentry
,
const
char
*
name
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
dentry
->
d_inode
)
->
root
;
/*
* The permission on security.* and system.* is not checked
* in permission().
*/
if
(
btrfs_root_readonly
(
root
))
return
-
EROFS
;
/*
* If this is a request for a synthetic attribute in the system.*
* namespace use the generic infrastructure to resolve a handler
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录