Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
41fefa36
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
41fefa36
编写于
10月 07, 2016
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'fuse/xattr' into work.xattr
上级
6c6ef9f2
703c7362
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
221 addition
and
157 deletion
+221
-157
fs/fuse/Makefile
fs/fuse/Makefile
+1
-1
fs/fuse/dir.c
fs/fuse/dir.c
+11
-156
fs/fuse/fuse_i.h
fs/fuse/fuse_i.h
+5
-0
fs/fuse/inode.c
fs/fuse/inode.c
+1
-0
fs/fuse/xattr.c
fs/fuse/xattr.c
+203
-0
未找到文件。
fs/fuse/Makefile
浏览文件 @
41fefa36
...
...
@@ -5,4 +5,4 @@
obj-$(CONFIG_FUSE_FS)
+=
fuse.o
obj-$(CONFIG_CUSE)
+=
cuse.o
fuse-objs
:=
dev.o dir.o file.o inode.o control.o
fuse-objs
:=
dev.o dir.o file.o inode.o control.o
xattr.o
fs/fuse/dir.c
浏览文件 @
41fefa36
...
...
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/namei.h>
#include <linux/slab.h>
#include <linux/xattr.h>
static
bool
fuse_use_readdirplus
(
struct
inode
*
dir
,
struct
dir_context
*
ctx
)
{
...
...
@@ -634,7 +635,7 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
return
create_new_entry
(
fc
,
&
args
,
dir
,
entry
,
S_IFLNK
);
}
static
inline
void
fuse_update_ctime
(
struct
inode
*
inode
)
void
fuse_update_ctime
(
struct
inode
*
inode
)
{
if
(
!
IS_NOCMTIME
(
inode
))
{
inode
->
i_ctime
=
current_fs_time
(
inode
->
i_sb
);
...
...
@@ -1724,152 +1725,6 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
return
fuse_update_attributes
(
inode
,
stat
,
NULL
,
NULL
);
}
static
int
fuse_setxattr
(
struct
dentry
*
unused
,
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
)
{
struct
fuse_conn
*
fc
=
get_fuse_conn
(
inode
);
FUSE_ARGS
(
args
);
struct
fuse_setxattr_in
inarg
;
int
err
;
if
(
fc
->
no_setxattr
)
return
-
EOPNOTSUPP
;
memset
(
&
inarg
,
0
,
sizeof
(
inarg
));
inarg
.
size
=
size
;
inarg
.
flags
=
flags
;
args
.
in
.
h
.
opcode
=
FUSE_SETXATTR
;
args
.
in
.
h
.
nodeid
=
get_node_id
(
inode
);
args
.
in
.
numargs
=
3
;
args
.
in
.
args
[
0
].
size
=
sizeof
(
inarg
);
args
.
in
.
args
[
0
].
value
=
&
inarg
;
args
.
in
.
args
[
1
].
size
=
strlen
(
name
)
+
1
;
args
.
in
.
args
[
1
].
value
=
name
;
args
.
in
.
args
[
2
].
size
=
size
;
args
.
in
.
args
[
2
].
value
=
value
;
err
=
fuse_simple_request
(
fc
,
&
args
);
if
(
err
==
-
ENOSYS
)
{
fc
->
no_setxattr
=
1
;
err
=
-
EOPNOTSUPP
;
}
if
(
!
err
)
{
fuse_invalidate_attr
(
inode
);
fuse_update_ctime
(
inode
);
}
return
err
;
}
static
ssize_t
fuse_getxattr
(
struct
dentry
*
entry
,
struct
inode
*
inode
,
const
char
*
name
,
void
*
value
,
size_t
size
)
{
struct
fuse_conn
*
fc
=
get_fuse_conn
(
inode
);
FUSE_ARGS
(
args
);
struct
fuse_getxattr_in
inarg
;
struct
fuse_getxattr_out
outarg
;
ssize_t
ret
;
if
(
fc
->
no_getxattr
)
return
-
EOPNOTSUPP
;
memset
(
&
inarg
,
0
,
sizeof
(
inarg
));
inarg
.
size
=
size
;
args
.
in
.
h
.
opcode
=
FUSE_GETXATTR
;
args
.
in
.
h
.
nodeid
=
get_node_id
(
inode
);
args
.
in
.
numargs
=
2
;
args
.
in
.
args
[
0
].
size
=
sizeof
(
inarg
);
args
.
in
.
args
[
0
].
value
=
&
inarg
;
args
.
in
.
args
[
1
].
size
=
strlen
(
name
)
+
1
;
args
.
in
.
args
[
1
].
value
=
name
;
/* This is really two different operations rolled into one */
args
.
out
.
numargs
=
1
;
if
(
size
)
{
args
.
out
.
argvar
=
1
;
args
.
out
.
args
[
0
].
size
=
size
;
args
.
out
.
args
[
0
].
value
=
value
;
}
else
{
args
.
out
.
args
[
0
].
size
=
sizeof
(
outarg
);
args
.
out
.
args
[
0
].
value
=
&
outarg
;
}
ret
=
fuse_simple_request
(
fc
,
&
args
);
if
(
!
ret
&&
!
size
)
ret
=
outarg
.
size
;
if
(
ret
==
-
ENOSYS
)
{
fc
->
no_getxattr
=
1
;
ret
=
-
EOPNOTSUPP
;
}
return
ret
;
}
static
ssize_t
fuse_listxattr
(
struct
dentry
*
entry
,
char
*
list
,
size_t
size
)
{
struct
inode
*
inode
=
d_inode
(
entry
);
struct
fuse_conn
*
fc
=
get_fuse_conn
(
inode
);
FUSE_ARGS
(
args
);
struct
fuse_getxattr_in
inarg
;
struct
fuse_getxattr_out
outarg
;
ssize_t
ret
;
if
(
!
fuse_allow_current_process
(
fc
))
return
-
EACCES
;
if
(
fc
->
no_listxattr
)
return
-
EOPNOTSUPP
;
memset
(
&
inarg
,
0
,
sizeof
(
inarg
));
inarg
.
size
=
size
;
args
.
in
.
h
.
opcode
=
FUSE_LISTXATTR
;
args
.
in
.
h
.
nodeid
=
get_node_id
(
inode
);
args
.
in
.
numargs
=
1
;
args
.
in
.
args
[
0
].
size
=
sizeof
(
inarg
);
args
.
in
.
args
[
0
].
value
=
&
inarg
;
/* This is really two different operations rolled into one */
args
.
out
.
numargs
=
1
;
if
(
size
)
{
args
.
out
.
argvar
=
1
;
args
.
out
.
args
[
0
].
size
=
size
;
args
.
out
.
args
[
0
].
value
=
list
;
}
else
{
args
.
out
.
args
[
0
].
size
=
sizeof
(
outarg
);
args
.
out
.
args
[
0
].
value
=
&
outarg
;
}
ret
=
fuse_simple_request
(
fc
,
&
args
);
if
(
!
ret
&&
!
size
)
ret
=
outarg
.
size
;
if
(
ret
==
-
ENOSYS
)
{
fc
->
no_listxattr
=
1
;
ret
=
-
EOPNOTSUPP
;
}
return
ret
;
}
static
int
fuse_removexattr
(
struct
dentry
*
entry
,
const
char
*
name
)
{
struct
inode
*
inode
=
d_inode
(
entry
);
struct
fuse_conn
*
fc
=
get_fuse_conn
(
inode
);
FUSE_ARGS
(
args
);
int
err
;
if
(
fc
->
no_removexattr
)
return
-
EOPNOTSUPP
;
args
.
in
.
h
.
opcode
=
FUSE_REMOVEXATTR
;
args
.
in
.
h
.
nodeid
=
get_node_id
(
inode
);
args
.
in
.
numargs
=
1
;
args
.
in
.
args
[
0
].
size
=
strlen
(
name
)
+
1
;
args
.
in
.
args
[
0
].
value
=
name
;
err
=
fuse_simple_request
(
fc
,
&
args
);
if
(
err
==
-
ENOSYS
)
{
fc
->
no_removexattr
=
1
;
err
=
-
EOPNOTSUPP
;
}
if
(
!
err
)
{
fuse_invalidate_attr
(
inode
);
fuse_update_ctime
(
inode
);
}
return
err
;
}
static
const
struct
inode_operations
fuse_dir_inode_operations
=
{
.
lookup
=
fuse_lookup
,
.
mkdir
=
fuse_mkdir
,
...
...
@@ -1884,10 +1739,10 @@ static const struct inode_operations fuse_dir_inode_operations = {
.
mknod
=
fuse_mknod
,
.
permission
=
fuse_permission
,
.
getattr
=
fuse_getattr
,
.
setxattr
=
fuse
_setxattr
,
.
getxattr
=
fuse
_getxattr
,
.
setxattr
=
generic
_setxattr
,
.
getxattr
=
generic
_getxattr
,
.
listxattr
=
fuse_listxattr
,
.
removexattr
=
fuse
_removexattr
,
.
removexattr
=
generic
_removexattr
,
};
static
const
struct
file_operations
fuse_dir_operations
=
{
...
...
@@ -1905,10 +1760,10 @@ static const struct inode_operations fuse_common_inode_operations = {
.
setattr
=
fuse_setattr
,
.
permission
=
fuse_permission
,
.
getattr
=
fuse_getattr
,
.
setxattr
=
fuse
_setxattr
,
.
getxattr
=
fuse
_getxattr
,
.
setxattr
=
generic
_setxattr
,
.
getxattr
=
generic
_getxattr
,
.
listxattr
=
fuse_listxattr
,
.
removexattr
=
fuse
_removexattr
,
.
removexattr
=
generic
_removexattr
,
};
static
const
struct
inode_operations
fuse_symlink_inode_operations
=
{
...
...
@@ -1916,10 +1771,10 @@ static const struct inode_operations fuse_symlink_inode_operations = {
.
get_link
=
fuse_get_link
,
.
readlink
=
generic_readlink
,
.
getattr
=
fuse_getattr
,
.
setxattr
=
fuse
_setxattr
,
.
getxattr
=
fuse
_getxattr
,
.
setxattr
=
generic
_setxattr
,
.
getxattr
=
generic
_getxattr
,
.
listxattr
=
fuse_listxattr
,
.
removexattr
=
fuse
_removexattr
,
.
removexattr
=
generic
_removexattr
,
};
void
fuse_init_common
(
struct
inode
*
inode
)
...
...
fs/fuse/fuse_i.h
浏览文件 @
41fefa36
...
...
@@ -902,6 +902,8 @@ int fuse_allow_current_process(struct fuse_conn *fc);
u64
fuse_lock_owner_id
(
struct
fuse_conn
*
fc
,
fl_owner_t
id
);
void
fuse_update_ctime
(
struct
inode
*
inode
);
int
fuse_update_attributes
(
struct
inode
*
inode
,
struct
kstat
*
stat
,
struct
file
*
file
,
bool
*
refreshed
);
...
...
@@ -966,4 +968,7 @@ void fuse_set_initialized(struct fuse_conn *fc);
void
fuse_unlock_inode
(
struct
inode
*
inode
);
void
fuse_lock_inode
(
struct
inode
*
inode
);
ssize_t
fuse_listxattr
(
struct
dentry
*
entry
,
char
*
list
,
size_t
size
);
extern
const
struct
xattr_handler
*
fuse_xattr_handlers
[];
#endif
/* _FS_FUSE_I_H */
fs/fuse/inode.c
浏览文件 @
41fefa36
...
...
@@ -1071,6 +1071,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
}
sb
->
s_magic
=
FUSE_SUPER_MAGIC
;
sb
->
s_op
=
&
fuse_super_operations
;
sb
->
s_xattr
=
fuse_xattr_handlers
;
sb
->
s_maxbytes
=
MAX_LFS_FILESIZE
;
sb
->
s_time_gran
=
1
;
sb
->
s_export_op
=
&
fuse_export_operations
;
...
...
fs/fuse/xattr.c
0 → 100644
浏览文件 @
41fefa36
/*
* FUSE: Filesystem in Userspace
* Copyright (C) 2001-2016 Miklos Szeredi <miklos@szeredi.hu>
*
* This program can be distributed under the terms of the GNU GPL.
* See the file COPYING.
*/
#include "fuse_i.h"
#include <linux/xattr.h>
static
int
fuse_setxattr
(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
)
{
struct
fuse_conn
*
fc
=
get_fuse_conn
(
inode
);
FUSE_ARGS
(
args
);
struct
fuse_setxattr_in
inarg
;
int
err
;
if
(
fc
->
no_setxattr
)
return
-
EOPNOTSUPP
;
memset
(
&
inarg
,
0
,
sizeof
(
inarg
));
inarg
.
size
=
size
;
inarg
.
flags
=
flags
;
args
.
in
.
h
.
opcode
=
FUSE_SETXATTR
;
args
.
in
.
h
.
nodeid
=
get_node_id
(
inode
);
args
.
in
.
numargs
=
3
;
args
.
in
.
args
[
0
].
size
=
sizeof
(
inarg
);
args
.
in
.
args
[
0
].
value
=
&
inarg
;
args
.
in
.
args
[
1
].
size
=
strlen
(
name
)
+
1
;
args
.
in
.
args
[
1
].
value
=
name
;
args
.
in
.
args
[
2
].
size
=
size
;
args
.
in
.
args
[
2
].
value
=
value
;
err
=
fuse_simple_request
(
fc
,
&
args
);
if
(
err
==
-
ENOSYS
)
{
fc
->
no_setxattr
=
1
;
err
=
-
EOPNOTSUPP
;
}
if
(
!
err
)
{
fuse_invalidate_attr
(
inode
);
fuse_update_ctime
(
inode
);
}
return
err
;
}
static
ssize_t
fuse_getxattr
(
struct
inode
*
inode
,
const
char
*
name
,
void
*
value
,
size_t
size
)
{
struct
fuse_conn
*
fc
=
get_fuse_conn
(
inode
);
FUSE_ARGS
(
args
);
struct
fuse_getxattr_in
inarg
;
struct
fuse_getxattr_out
outarg
;
ssize_t
ret
;
if
(
fc
->
no_getxattr
)
return
-
EOPNOTSUPP
;
memset
(
&
inarg
,
0
,
sizeof
(
inarg
));
inarg
.
size
=
size
;
args
.
in
.
h
.
opcode
=
FUSE_GETXATTR
;
args
.
in
.
h
.
nodeid
=
get_node_id
(
inode
);
args
.
in
.
numargs
=
2
;
args
.
in
.
args
[
0
].
size
=
sizeof
(
inarg
);
args
.
in
.
args
[
0
].
value
=
&
inarg
;
args
.
in
.
args
[
1
].
size
=
strlen
(
name
)
+
1
;
args
.
in
.
args
[
1
].
value
=
name
;
/* This is really two different operations rolled into one */
args
.
out
.
numargs
=
1
;
if
(
size
)
{
args
.
out
.
argvar
=
1
;
args
.
out
.
args
[
0
].
size
=
size
;
args
.
out
.
args
[
0
].
value
=
value
;
}
else
{
args
.
out
.
args
[
0
].
size
=
sizeof
(
outarg
);
args
.
out
.
args
[
0
].
value
=
&
outarg
;
}
ret
=
fuse_simple_request
(
fc
,
&
args
);
if
(
!
ret
&&
!
size
)
ret
=
outarg
.
size
;
if
(
ret
==
-
ENOSYS
)
{
fc
->
no_getxattr
=
1
;
ret
=
-
EOPNOTSUPP
;
}
return
ret
;
}
static
int
fuse_verify_xattr_list
(
char
*
list
,
size_t
size
)
{
size_t
origsize
=
size
;
while
(
size
)
{
size_t
thislen
=
strnlen
(
list
,
size
);
if
(
!
thislen
||
thislen
==
size
)
return
-
EIO
;
size
-=
thislen
+
1
;
list
+=
thislen
+
1
;
}
return
origsize
;
}
ssize_t
fuse_listxattr
(
struct
dentry
*
entry
,
char
*
list
,
size_t
size
)
{
struct
inode
*
inode
=
d_inode
(
entry
);
struct
fuse_conn
*
fc
=
get_fuse_conn
(
inode
);
FUSE_ARGS
(
args
);
struct
fuse_getxattr_in
inarg
;
struct
fuse_getxattr_out
outarg
;
ssize_t
ret
;
if
(
!
fuse_allow_current_process
(
fc
))
return
-
EACCES
;
if
(
fc
->
no_listxattr
)
return
-
EOPNOTSUPP
;
memset
(
&
inarg
,
0
,
sizeof
(
inarg
));
inarg
.
size
=
size
;
args
.
in
.
h
.
opcode
=
FUSE_LISTXATTR
;
args
.
in
.
h
.
nodeid
=
get_node_id
(
inode
);
args
.
in
.
numargs
=
1
;
args
.
in
.
args
[
0
].
size
=
sizeof
(
inarg
);
args
.
in
.
args
[
0
].
value
=
&
inarg
;
/* This is really two different operations rolled into one */
args
.
out
.
numargs
=
1
;
if
(
size
)
{
args
.
out
.
argvar
=
1
;
args
.
out
.
args
[
0
].
size
=
size
;
args
.
out
.
args
[
0
].
value
=
list
;
}
else
{
args
.
out
.
args
[
0
].
size
=
sizeof
(
outarg
);
args
.
out
.
args
[
0
].
value
=
&
outarg
;
}
ret
=
fuse_simple_request
(
fc
,
&
args
);
if
(
!
ret
&&
!
size
)
ret
=
outarg
.
size
;
if
(
ret
>
0
&&
size
)
ret
=
fuse_verify_xattr_list
(
list
,
ret
);
if
(
ret
==
-
ENOSYS
)
{
fc
->
no_listxattr
=
1
;
ret
=
-
EOPNOTSUPP
;
}
return
ret
;
}
static
int
fuse_removexattr
(
struct
inode
*
inode
,
const
char
*
name
)
{
struct
fuse_conn
*
fc
=
get_fuse_conn
(
inode
);
FUSE_ARGS
(
args
);
int
err
;
if
(
fc
->
no_removexattr
)
return
-
EOPNOTSUPP
;
args
.
in
.
h
.
opcode
=
FUSE_REMOVEXATTR
;
args
.
in
.
h
.
nodeid
=
get_node_id
(
inode
);
args
.
in
.
numargs
=
1
;
args
.
in
.
args
[
0
].
size
=
strlen
(
name
)
+
1
;
args
.
in
.
args
[
0
].
value
=
name
;
err
=
fuse_simple_request
(
fc
,
&
args
);
if
(
err
==
-
ENOSYS
)
{
fc
->
no_removexattr
=
1
;
err
=
-
EOPNOTSUPP
;
}
if
(
!
err
)
{
fuse_invalidate_attr
(
inode
);
fuse_update_ctime
(
inode
);
}
return
err
;
}
static
int
fuse_xattr_get
(
const
struct
xattr_handler
*
handler
,
struct
dentry
*
dentry
,
struct
inode
*
inode
,
const
char
*
name
,
void
*
value
,
size_t
size
)
{
return
fuse_getxattr
(
inode
,
name
,
value
,
size
);
}
static
int
fuse_xattr_set
(
const
struct
xattr_handler
*
handler
,
struct
dentry
*
dentry
,
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
)
{
if
(
!
value
)
return
fuse_removexattr
(
inode
,
name
);
return
fuse_setxattr
(
inode
,
name
,
value
,
size
,
flags
);
}
static
const
struct
xattr_handler
fuse_xattr_handler
=
{
.
prefix
=
""
,
.
get
=
fuse_xattr_get
,
.
set
=
fuse_xattr_set
,
};
const
struct
xattr_handler
*
fuse_xattr_handlers
[]
=
{
&
fuse_xattr_handler
,
NULL
};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录