Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
2d6dcc6d
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
170
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看板
提交
2d6dcc6d
编写于
5月 15, 2014
作者:
D
Dave Chinner
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'xfs-attr-cleanup' into for-next
Conflicts: fs/xfs/xfs_attr.c
上级
ff14ee42
6c888af0
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
117 addition
and
211 deletion
+117
-211
fs/xfs/xfs_attr.c
fs/xfs/xfs_attr.c
+117
-211
未找到文件。
fs/xfs/xfs_attr.c
浏览文件 @
2d6dcc6d
...
...
@@ -77,17 +77,26 @@ STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
STATIC
int
xfs_attr_name_to_xname
(
struct
xfs_name
*
xname
,
const
unsigned
char
*
aname
)
xfs_attr_args_init
(
struct
xfs_da_args
*
args
,
struct
xfs_inode
*
dp
,
const
unsigned
char
*
name
,
int
flags
)
{
if
(
!
aname
)
if
(
!
name
)
return
EINVAL
;
xname
->
name
=
aname
;
xname
->
len
=
strlen
((
char
*
)
aname
);
if
(
xname
->
len
>=
MAXNAMELEN
)
memset
(
args
,
0
,
sizeof
(
*
args
));
args
->
whichfork
=
XFS_ATTR_FORK
;
args
->
dp
=
dp
;
args
->
flags
=
flags
;
args
->
name
=
name
;
args
->
namelen
=
strlen
((
const
char
*
)
name
);
if
(
args
->
namelen
>=
MAXNAMELEN
)
return
EFAULT
;
/* match IRIX behaviour */
args
->
hashval
=
xfs_da_hashname
(
args
->
name
,
args
->
namelen
);
return
0
;
}
...
...
@@ -106,79 +115,46 @@ xfs_inode_hasattr(
* Overall external interface routines.
*========================================================================*/
STATIC
int
xfs_attr_get
_int
(
int
xfs_attr_get
(
struct
xfs_inode
*
ip
,
struct
xfs_name
*
name
,
const
unsigned
char
*
name
,
unsigned
char
*
value
,
int
*
valuelenp
,
int
flags
)
{
xfs_da_args_t
args
;
int
error
;
struct
xfs_da_args
args
;
uint
lock_mode
;
int
error
;
XFS_STATS_INC
(
xs_attr_get
);
if
(
XFS_FORCED_SHUTDOWN
(
ip
->
i_mount
))
return
EIO
;
if
(
!
xfs_inode_hasattr
(
ip
))
return
ENOATTR
;
/*
* Fill in the arg structure for this request.
*/
memset
((
char
*
)
&
args
,
0
,
sizeof
(
args
));
args
.
name
=
name
->
name
;
args
.
namelen
=
name
->
len
;
error
=
xfs_attr_args_init
(
&
args
,
ip
,
name
,
flags
);
if
(
error
)
return
error
;
args
.
value
=
value
;
args
.
valuelen
=
*
valuelenp
;
args
.
flags
=
flags
;
args
.
hashval
=
xfs_da_hashname
(
args
.
name
,
args
.
namelen
);
args
.
dp
=
ip
;
args
.
whichfork
=
XFS_ATTR_FORK
;
/*
* Decide on what work routines to call based on the inode size.
*/
if
(
ip
->
i_d
.
di_aformat
==
XFS_DINODE_FMT_LOCAL
)
{
lock_mode
=
xfs_ilock_attr_map_shared
(
ip
);
if
(
!
xfs_inode_hasattr
(
ip
))
error
=
ENOATTR
;
else
if
(
ip
->
i_d
.
di_aformat
==
XFS_DINODE_FMT_LOCAL
)
error
=
xfs_attr_shortform_getvalue
(
&
args
);
}
else
if
(
xfs_bmap_one_block
(
ip
,
XFS_ATTR_FORK
))
{
else
if
(
xfs_bmap_one_block
(
ip
,
XFS_ATTR_FORK
))
error
=
xfs_attr_leaf_get
(
&
args
);
}
else
{
else
error
=
xfs_attr_node_get
(
&
args
);
}
xfs_iunlock
(
ip
,
lock_mode
);
/*
* Return the number of bytes in the value to the caller.
*/
*
valuelenp
=
args
.
valuelen
;
if
(
error
==
EEXIST
)
error
=
0
;
return
(
error
);
}
int
xfs_attr_get
(
xfs_inode_t
*
ip
,
const
unsigned
char
*
name
,
unsigned
char
*
value
,
int
*
valuelenp
,
int
flags
)
{
int
error
;
struct
xfs_name
xname
;
uint
lock_mode
;
XFS_STATS_INC
(
xs_attr_get
);
if
(
XFS_FORCED_SHUTDOWN
(
ip
->
i_mount
))
return
(
EIO
);
error
=
xfs_attr_name_to_xname
(
&
xname
,
name
);
if
(
error
)
return
error
;
lock_mode
=
xfs_ilock_attr_map_shared
(
ip
);
error
=
xfs_attr_get_int
(
ip
,
&
xname
,
value
,
valuelenp
,
flags
);
xfs_iunlock
(
ip
,
lock_mode
);
return
(
error
);
return
error
==
EEXIST
?
0
:
error
;
}
/*
...
...
@@ -186,12 +162,10 @@ xfs_attr_get(
*/
STATIC
int
xfs_attr_calc_size
(
struct
xfs_inode
*
ip
,
int
namelen
,
int
valuelen
,
struct
xfs_da_args
*
args
,
int
*
local
)
{
struct
xfs_mount
*
mp
=
i
p
->
i_mount
;
struct
xfs_mount
*
mp
=
args
->
d
p
->
i_mount
;
int
size
;
int
nblks
;
...
...
@@ -199,7 +173,7 @@ xfs_attr_calc_size(
* Determine space new attribute will use, and if it would be
* "local" or "remote" (note: local != inline).
*/
size
=
xfs_attr_leaf_newentsize
(
namelen
,
valuelen
,
size
=
xfs_attr_leaf_newentsize
(
args
->
namelen
,
args
->
valuelen
,
mp
->
m_sb
.
sb_blocksize
,
local
);
nblks
=
XFS_DAENTER_SPACE_RES
(
mp
,
XFS_ATTR_FORK
);
...
...
@@ -213,7 +187,7 @@ xfs_attr_calc_size(
* Out of line attribute, cannot double split, but
* make room for the attribute value itself.
*/
uint
dblocks
=
xfs_attr3_rmt_blocks
(
mp
,
valuelen
);
uint
dblocks
=
xfs_attr3_rmt_blocks
(
mp
,
args
->
valuelen
);
nblks
+=
dblocks
;
nblks
+=
XFS_NEXTENTADD_SPACE_RES
(
mp
,
dblocks
,
XFS_ATTR_FORK
);
}
...
...
@@ -221,26 +195,38 @@ xfs_attr_calc_size(
return
nblks
;
}
STATIC
int
xfs_attr_set
_int
(
struct
xfs_inode
*
dp
,
struct
xfs_name
*
name
,
unsigned
char
*
value
,
int
valuelen
,
int
flags
)
int
xfs_attr_set
(
struct
xfs_inode
*
dp
,
const
unsigned
char
*
name
,
unsigned
char
*
value
,
int
valuelen
,
int
flags
)
{
xfs_da_args_t
args
;
xfs_fsblock_t
firstblock
;
xfs_bmap_free_t
flist
;
int
error
,
err2
,
committed
;
struct
xfs_mount
*
mp
=
dp
->
i_mount
;
struct
xfs_da_args
args
;
struct
xfs_bmap_free
flist
;
struct
xfs_trans_res
tres
;
xfs_fsblock_t
firstblock
;
int
rsvd
=
(
flags
&
ATTR_ROOT
)
!=
0
;
int
local
;
int
error
,
err2
,
committed
,
local
;
XFS_STATS_INC
(
xs_attr_set
);
if
(
XFS_FORCED_SHUTDOWN
(
dp
->
i_mount
))
return
EIO
;
error
=
xfs_attr_args_init
(
&
args
,
dp
,
name
,
flags
);
if
(
error
)
return
error
;
args
.
value
=
value
;
args
.
valuelen
=
valuelen
;
args
.
firstblock
=
&
firstblock
;
args
.
flist
=
&
flist
;
args
.
op_flags
=
XFS_DA_OP_ADDNAME
|
XFS_DA_OP_OKNOENT
;
args
.
total
=
xfs_attr_calc_size
(
&
args
,
&
local
);
/*
* Attach the dquots to the inode.
*/
error
=
xfs_qm_dqattach
(
dp
,
0
);
if
(
error
)
return
error
;
...
...
@@ -251,31 +237,13 @@ xfs_attr_set_int(
*/
if
(
XFS_IFORK_Q
(
dp
)
==
0
)
{
int
sf_size
=
sizeof
(
xfs_attr_sf_hdr_t
)
+
XFS_ATTR_SF_ENTSIZE_BYNAME
(
name
->
len
,
valuelen
);
XFS_ATTR_SF_ENTSIZE_BYNAME
(
args
.
name
len
,
valuelen
);
if
((
error
=
xfs_bmap_add_attrfork
(
dp
,
sf_size
,
rsvd
)))
return
(
error
);
error
=
xfs_bmap_add_attrfork
(
dp
,
sf_size
,
rsvd
);
if
(
error
)
return
error
;
}
/*
* Fill in the arg structure for this request.
*/
memset
((
char
*
)
&
args
,
0
,
sizeof
(
args
));
args
.
name
=
name
->
name
;
args
.
namelen
=
name
->
len
;
args
.
value
=
value
;
args
.
valuelen
=
valuelen
;
args
.
flags
=
flags
;
args
.
hashval
=
xfs_da_hashname
(
args
.
name
,
args
.
namelen
);
args
.
dp
=
dp
;
args
.
firstblock
=
&
firstblock
;
args
.
flist
=
&
flist
;
args
.
whichfork
=
XFS_ATTR_FORK
;
args
.
op_flags
=
XFS_DA_OP_ADDNAME
|
XFS_DA_OP_OKNOENT
;
/* Size is now blocks for attribute data */
args
.
total
=
xfs_attr_calc_size
(
dp
,
name
->
len
,
valuelen
,
&
local
);
/*
* Start our first transaction of the day.
*
...
...
@@ -303,7 +271,7 @@ xfs_attr_set_int(
error
=
xfs_trans_reserve
(
args
.
trans
,
&
tres
,
args
.
total
,
0
);
if
(
error
)
{
xfs_trans_cancel
(
args
.
trans
,
0
);
return
(
error
)
;
return
error
;
}
xfs_ilock
(
dp
,
XFS_ILOCK_EXCL
);
...
...
@@ -313,7 +281,7 @@ xfs_attr_set_int(
if
(
error
)
{
xfs_iunlock
(
dp
,
XFS_ILOCK_EXCL
);
xfs_trans_cancel
(
args
.
trans
,
XFS_TRANS_RELEASE_LOG_RES
);
return
(
error
)
;
return
error
;
}
xfs_trans_ijoin
(
args
.
trans
,
dp
,
0
);
...
...
@@ -322,9 +290,9 @@ xfs_attr_set_int(
* If the attribute list is non-existent or a shortform list,
* upgrade it to a single-leaf-block attribute list.
*/
if
(
(
dp
->
i_d
.
di_aformat
==
XFS_DINODE_FMT_LOCAL
)
||
(
(
dp
->
i_d
.
di_aformat
==
XFS_DINODE_FMT_EXTENTS
)
&&
(
dp
->
i_d
.
di_anextents
==
0
)
))
{
if
(
dp
->
i_d
.
di_aformat
==
XFS_DINODE_FMT_LOCAL
||
(
dp
->
i_d
.
di_aformat
==
XFS_DINODE_FMT_EXTENTS
&&
dp
->
i_d
.
di_anextents
==
0
))
{
/*
* Build initial attribute list (if required).
...
...
@@ -349,9 +317,8 @@ xfs_attr_set_int(
* the transaction goes to disk before returning
* to the user.
*/
if
(
mp
->
m_flags
&
XFS_MOUNT_WSYNC
)
{
if
(
mp
->
m_flags
&
XFS_MOUNT_WSYNC
)
xfs_trans_set_sync
(
args
.
trans
);
}
if
(
!
error
&&
(
flags
&
ATTR_KERNOTIME
)
==
0
)
{
xfs_trans_ichgtime
(
args
.
trans
,
dp
,
...
...
@@ -361,7 +328,7 @@ xfs_attr_set_int(
XFS_TRANS_RELEASE_LOG_RES
);
xfs_iunlock
(
dp
,
XFS_ILOCK_EXCL
);
return
(
error
==
0
?
err2
:
error
)
;
return
error
?
error
:
err2
;
}
/*
...
...
@@ -399,22 +366,19 @@ xfs_attr_set_int(
}
if
(
xfs_bmap_one_block
(
dp
,
XFS_ATTR_FORK
))
{
if
(
xfs_bmap_one_block
(
dp
,
XFS_ATTR_FORK
))
error
=
xfs_attr_leaf_addname
(
&
args
);
}
else
{
else
error
=
xfs_attr_node_addname
(
&
args
);
}
if
(
error
)
{
if
(
error
)
goto
out
;
}
/*
* If this is a synchronous mount, make sure that the
* transaction goes to disk before returning to the user.
*/
if
(
mp
->
m_flags
&
XFS_MOUNT_WSYNC
)
{
if
(
mp
->
m_flags
&
XFS_MOUNT_WSYNC
)
xfs_trans_set_sync
(
args
.
trans
);
}
if
((
flags
&
ATTR_KERNOTIME
)
==
0
)
xfs_trans_ichgtime
(
args
.
trans
,
dp
,
XFS_ICHGTIME_CHG
);
...
...
@@ -426,65 +390,47 @@ xfs_attr_set_int(
error
=
xfs_trans_commit
(
args
.
trans
,
XFS_TRANS_RELEASE_LOG_RES
);
xfs_iunlock
(
dp
,
XFS_ILOCK_EXCL
);
return
(
error
)
;
return
error
;
out:
if
(
args
.
trans
)
if
(
args
.
trans
)
{
xfs_trans_cancel
(
args
.
trans
,
XFS_TRANS_RELEASE_LOG_RES
|
XFS_TRANS_ABORT
);
}
xfs_iunlock
(
dp
,
XFS_ILOCK_EXCL
);
return
(
error
)
;
return
error
;
}
/*
* Generic handler routine to remove a name from an attribute list.
* Transitions attribute list from Btree to shortform as necessary.
*/
int
xfs_attr_set
(
xfs_inode_t
*
dp
,
const
unsigned
char
*
name
,
unsigned
char
*
value
,
int
valuelen
,
int
flags
)
xfs_attr_remove
(
struct
xfs_inode
*
dp
,
const
unsigned
char
*
name
,
int
flags
)
{
int
error
;
struct
xfs_name
xname
;
struct
xfs_mount
*
mp
=
dp
->
i_mount
;
struct
xfs_da_args
args
;
struct
xfs_bmap_free
flist
;
xfs_fsblock_t
firstblock
;
int
error
;
XFS_STATS_INC
(
xs_attr_
set
);
XFS_STATS_INC
(
xs_attr_
remove
);
if
(
XFS_FORCED_SHUTDOWN
(
dp
->
i_mount
))
return
(
EIO
)
;
return
EIO
;
error
=
xfs_attr_name_to_xname
(
&
xname
,
name
);
if
(
!
xfs_inode_hasattr
(
dp
))
return
ENOATTR
;
error
=
xfs_attr_args_init
(
&
args
,
dp
,
name
,
flags
);
if
(
error
)
return
error
;
return
xfs_attr_set_int
(
dp
,
&
xname
,
value
,
valuelen
,
flags
);
}
/*
* Generic handler routine to remove a name from an attribute list.
* Transitions attribute list from Btree to shortform as necessary.
*/
STATIC
int
xfs_attr_remove_int
(
xfs_inode_t
*
dp
,
struct
xfs_name
*
name
,
int
flags
)
{
xfs_da_args_t
args
;
xfs_fsblock_t
firstblock
;
xfs_bmap_free_t
flist
;
int
error
;
xfs_mount_t
*
mp
=
dp
->
i_mount
;
/*
* Fill in the arg structure for this request.
*/
memset
((
char
*
)
&
args
,
0
,
sizeof
(
args
));
args
.
name
=
name
->
name
;
args
.
namelen
=
name
->
len
;
args
.
flags
=
flags
;
args
.
hashval
=
xfs_da_hashname
(
args
.
name
,
args
.
namelen
);
args
.
dp
=
dp
;
args
.
firstblock
=
&
firstblock
;
args
.
flist
=
&
flist
;
args
.
total
=
0
;
args
.
whichfork
=
XFS_ATTR_FORK
;
/*
* we have no control over the attribute names that userspace passes us
...
...
@@ -493,9 +439,6 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
*/
args
.
op_flags
=
XFS_DA_OP_OKNOENT
;
/*
* Attach the dquots to the inode.
*/
error
=
xfs_qm_dqattach
(
dp
,
0
);
if
(
error
)
return
error
;
...
...
@@ -524,7 +467,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
XFS_ATTRRM_SPACE_RES
(
mp
),
0
);
if
(
error
)
{
xfs_trans_cancel
(
args
.
trans
,
0
);
return
(
error
)
;
return
error
;
}
xfs_ilock
(
dp
,
XFS_ILOCK_EXCL
);
...
...
@@ -534,35 +477,26 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
*/
xfs_trans_ijoin
(
args
.
trans
,
dp
,
0
);
/*
* Decide on what work routines to call based on the inode size.
*/
if
(
!
xfs_inode_hasattr
(
dp
))
{
error
=
XFS_ERROR
(
ENOATTR
);
goto
out
;
}
if
(
dp
->
i_d
.
di_aformat
==
XFS_DINODE_FMT_LOCAL
)
{
}
else
if
(
dp
->
i_d
.
di_aformat
==
XFS_DINODE_FMT_LOCAL
)
{
ASSERT
(
dp
->
i_afp
->
if_flags
&
XFS_IFINLINE
);
error
=
xfs_attr_shortform_remove
(
&
args
);
if
(
error
)
{
goto
out
;
}
}
else
if
(
xfs_bmap_one_block
(
dp
,
XFS_ATTR_FORK
))
{
error
=
xfs_attr_leaf_removename
(
&
args
);
}
else
{
error
=
xfs_attr_node_removename
(
&
args
);
}
if
(
error
)
{
if
(
error
)
goto
out
;
}
/*
* If this is a synchronous mount, make sure that the
* transaction goes to disk before returning to the user.
*/
if
(
mp
->
m_flags
&
XFS_MOUNT_WSYNC
)
{
if
(
mp
->
m_flags
&
XFS_MOUNT_WSYNC
)
xfs_trans_set_sync
(
args
.
trans
);
}
if
((
flags
&
ATTR_KERNOTIME
)
==
0
)
xfs_trans_ichgtime
(
args
.
trans
,
dp
,
XFS_ICHGTIME_CHG
);
...
...
@@ -574,45 +508,17 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
error
=
xfs_trans_commit
(
args
.
trans
,
XFS_TRANS_RELEASE_LOG_RES
);
xfs_iunlock
(
dp
,
XFS_ILOCK_EXCL
);
return
(
error
)
;
return
error
;
out:
if
(
args
.
trans
)
if
(
args
.
trans
)
{
xfs_trans_cancel
(
args
.
trans
,
XFS_TRANS_RELEASE_LOG_RES
|
XFS_TRANS_ABORT
);
xfs_iunlock
(
dp
,
XFS_ILOCK_EXCL
);
return
(
error
);
}
int
xfs_attr_remove
(
xfs_inode_t
*
dp
,
const
unsigned
char
*
name
,
int
flags
)
{
int
error
;
struct
xfs_name
xname
;
XFS_STATS_INC
(
xs_attr_remove
);
if
(
XFS_FORCED_SHUTDOWN
(
dp
->
i_mount
))
return
(
EIO
);
error
=
xfs_attr_name_to_xname
(
&
xname
,
name
);
if
(
error
)
return
error
;
xfs_ilock
(
dp
,
XFS_ILOCK_SHARED
);
if
(
!
xfs_inode_hasattr
(
dp
))
{
xfs_iunlock
(
dp
,
XFS_ILOCK_SHARED
);
return
XFS_ERROR
(
ENOATTR
);
}
xfs_iunlock
(
dp
,
XFS_ILOCK_SHARED
);
return
xfs_attr_remove_int
(
dp
,
&
xname
,
flags
);
xfs_iunlock
(
dp
,
XFS_ILOCK_EXCL
);
return
error
;
}
/*========================================================================
* External routines when attribute list is inside the inode
*========================================================================*/
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录