Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
33268eaf
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
33268eaf
编写于
7月 24, 2008
作者:
J
Josef Bacik
提交者:
Chris Mason
9月 25, 2008
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Add ACL support
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
6099afe8
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
335 addition
and
48 deletion
+335
-48
fs/btrfs/acl.c
fs/btrfs/acl.c
+261
-35
fs/btrfs/btrfs_inode.h
fs/btrfs/btrfs_inode.h
+3
-0
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+7
-0
fs/btrfs/inode.c
fs/btrfs/inode.c
+41
-1
fs/btrfs/super.c
fs/btrfs/super.c
+7
-2
fs/btrfs/xattr.c
fs/btrfs/xattr.c
+16
-10
未找到文件。
fs/btrfs/acl.c
浏览文件 @
33268eaf
...
...
@@ -20,76 +20,302 @@
#include <linux/string.h>
#include <linux/xattr.h>
#include <linux/posix_acl_xattr.h>
#include <linux/posix_acl.h>
#include <linux/sched.h>
#include "ctree.h"
#include "btrfs_inode.h"
#include "xattr.h"
#ifndef is_owner_or_cap
#define is_owner_or_cap(inode) \
((current->fsuid == (inode)->i_uid) || capable(CAP_FOWNER))
#endif
static
void
btrfs_update_cached_acl
(
struct
inode
*
inode
,
struct
posix_acl
**
p_acl
,
struct
posix_acl
*
acl
)
{
spin_lock
(
&
inode
->
i_lock
);
if
(
*
p_acl
&&
*
p_acl
!=
BTRFS_ACL_NOT_CACHED
)
posix_acl_release
(
*
p_acl
);
*
p_acl
=
posix_acl_dup
(
acl
);
spin_unlock
(
&
inode
->
i_lock
);
}
static
struct
posix_acl
*
btrfs_get_acl
(
struct
inode
*
inode
,
int
type
)
{
int
size
,
name_index
;
char
*
value
=
NULL
;
struct
posix_acl
*
acl
=
NULL
,
**
p_acl
;
switch
(
type
)
{
case
ACL_TYPE_ACCESS
:
name_index
=
BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS
;
p_acl
=
&
BTRFS_I
(
inode
)
->
i_acl
;
break
;
case
ACL_TYPE_DEFAULT
:
name_index
=
BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT
;
p_acl
=
&
BTRFS_I
(
inode
)
->
i_default_acl
;
break
;
default:
return
ERR_PTR
(
-
EINVAL
);
}
spin_lock
(
&
inode
->
i_lock
);
if
(
*
p_acl
!=
BTRFS_ACL_NOT_CACHED
)
acl
=
posix_acl_dup
(
*
p_acl
);
spin_unlock
(
&
inode
->
i_lock
);
if
(
acl
)
return
acl
;
size
=
btrfs_xattr_get
(
inode
,
name_index
,
""
,
NULL
,
0
);
if
(
size
>
0
)
{
value
=
kzalloc
(
size
,
GFP_NOFS
);
if
(
!
value
)
return
ERR_PTR
(
-
ENOMEM
);
size
=
btrfs_xattr_get
(
inode
,
name_index
,
""
,
value
,
size
);
if
(
size
>
0
)
{
acl
=
posix_acl_from_xattr
(
value
,
size
);
btrfs_update_cached_acl
(
inode
,
p_acl
,
acl
);
}
kfree
(
value
);
}
else
if
(
size
==
-
ENOENT
)
{
acl
=
NULL
;
btrfs_update_cached_acl
(
inode
,
p_acl
,
acl
);
}
return
acl
;
}
static
int
btrfs_xattr_get_acl
(
struct
inode
*
inode
,
int
type
,
void
*
value
,
size_t
size
)
{
struct
posix_acl
*
acl
;
int
ret
=
0
;
acl
=
btrfs_get_acl
(
inode
,
type
);
if
(
IS_ERR
(
acl
))
return
PTR_ERR
(
acl
);
if
(
acl
==
NULL
)
return
-
ENODATA
;
ret
=
posix_acl_to_xattr
(
acl
,
value
,
size
);
posix_acl_release
(
acl
);
return
ret
;
}
/*
* Needs to be called with fs_mutex held
*/
static
int
btrfs_set_acl
(
struct
inode
*
inode
,
struct
posix_acl
*
acl
,
int
type
)
{
int
ret
,
name_index
=
0
,
size
=
0
;
struct
posix_acl
**
p_acl
;
char
*
value
=
NULL
;
mode_t
mode
;
if
(
acl
)
{
ret
=
posix_acl_valid
(
acl
);
if
(
ret
<
0
)
return
ret
;
ret
=
0
;
}
switch
(
type
)
{
case
ACL_TYPE_ACCESS
:
mode
=
inode
->
i_mode
;
ret
=
posix_acl_equiv_mode
(
acl
,
&
mode
);
if
(
ret
<
0
)
return
ret
;
ret
=
0
;
inode
->
i_mode
=
mode
;
name_index
=
BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS
;
p_acl
=
&
BTRFS_I
(
inode
)
->
i_acl
;
break
;
case
ACL_TYPE_DEFAULT
:
if
(
!
S_ISDIR
(
inode
->
i_mode
))
return
acl
?
-
EINVAL
:
0
;
name_index
=
BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT
;
p_acl
=
&
BTRFS_I
(
inode
)
->
i_default_acl
;
break
;
default:
return
-
EINVAL
;
}
if
(
acl
)
{
size
=
posix_acl_xattr_size
(
acl
->
a_count
);
value
=
kmalloc
(
size
,
GFP_NOFS
);
if
(
!
value
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
ret
=
posix_acl_to_xattr
(
acl
,
value
,
size
);
if
(
ret
<
0
)
goto
out
;
}
ret
=
btrfs_xattr_set
(
inode
,
name_index
,
""
,
value
,
size
,
0
);
out:
if
(
value
)
kfree
(
value
);
if
(
!
ret
)
btrfs_update_cached_acl
(
inode
,
p_acl
,
acl
);
return
ret
;
}
static
int
btrfs_xattr_set_acl
(
struct
inode
*
inode
,
int
type
,
const
void
*
value
,
size_t
size
)
{
int
ret
=
0
;
struct
posix_acl
*
acl
;
struct
posix_acl
*
acl
=
NULL
;
if
(
!
is_owner_or_cap
(
inode
))
return
-
EPERM
;
if
(
value
)
{
acl
=
posix_acl_from_xattr
(
value
,
size
);
if
(
acl
==
NULL
)
{
value
=
NULL
;
size
=
0
;
}
else
if
(
IS_ERR
(
acl
))
{
ret
=
PTR_ERR
(
acl
);
}
else
{
ret
=
posix_acl_valid
(
acl
);
posix_acl_release
(
acl
);
return
PTR_ERR
(
acl
);
}
if
(
ret
)
return
ret
;
}
return
btrfs_xattr_set
(
inode
,
type
,
""
,
value
,
size
,
0
);
}
static
int
btrfs_xattr_get_acl
(
struct
inode
*
inode
,
int
type
,
void
*
value
,
size_t
size
)
{
return
btrfs_xattr_get
(
inode
,
type
,
""
,
value
,
size
);
ret
=
btrfs_set_acl
(
inode
,
acl
,
type
);
posix_acl_release
(
acl
);
return
ret
;
}
static
int
btrfs_xattr_acl_access_get
(
struct
inode
*
inode
,
const
char
*
name
,
void
*
value
,
size_t
size
)
{
if
(
*
name
!=
'\0'
)
return
-
EINVAL
;
return
btrfs_xattr_get_acl
(
inode
,
BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS
,
value
,
size
);
return
btrfs_xattr_get_acl
(
inode
,
ACL_TYPE_ACCESS
,
value
,
size
);
}
static
int
btrfs_xattr_acl_access_set
(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
)
{
if
(
*
name
!=
'\0'
)
return
-
EINVAL
;
return
btrfs_xattr_set_acl
(
inode
,
BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS
,
value
,
size
);
return
btrfs_xattr_set_acl
(
inode
,
ACL_TYPE_ACCESS
,
value
,
size
);
}
static
int
btrfs_xattr_acl_default_get
(
struct
inode
*
inode
,
const
char
*
name
,
void
*
value
,
size_t
size
)
{
if
(
*
name
!=
'\0'
)
return
-
EINVAL
;
return
btrfs_xattr_get_acl
(
inode
,
BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT
,
value
,
size
);
return
btrfs_xattr_get_acl
(
inode
,
ACL_TYPE_DEFAULT
,
value
,
size
);
}
static
int
btrfs_xattr_acl_default_set
(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
value
,
size_t
size
,
int
flags
)
{
if
(
*
name
!=
'\0'
)
return
-
EINVAL
;
return
btrfs_xattr_set_acl
(
inode
,
BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT
,
value
,
size
);
return
btrfs_xattr_set_acl
(
inode
,
ACL_TYPE_DEFAULT
,
value
,
size
);
}
int
btrfs_check_acl
(
struct
inode
*
inode
,
int
mask
)
{
struct
posix_acl
*
acl
;
int
error
=
-
EAGAIN
;
acl
=
btrfs_get_acl
(
inode
,
ACL_TYPE_ACCESS
);
if
(
IS_ERR
(
acl
))
return
PTR_ERR
(
acl
);
if
(
acl
)
{
error
=
posix_acl_permission
(
inode
,
acl
,
mask
);
posix_acl_release
(
acl
);
}
return
error
;
}
/*
* btrfs_init_acl is already generally called under fs_mutex, so the locking
* stuff has been fixed to work with that. If the locking stuff changes, we
* need to re-evaluate the acl locking stuff.
*/
int
btrfs_init_acl
(
struct
inode
*
inode
,
struct
inode
*
dir
)
{
struct
posix_acl
*
acl
=
NULL
;
int
ret
=
0
;
/* this happens with subvols */
if
(
!
dir
)
return
0
;
if
(
!
S_ISLNK
(
inode
->
i_mode
))
{
if
(
IS_POSIXACL
(
dir
))
{
acl
=
btrfs_get_acl
(
dir
,
ACL_TYPE_DEFAULT
);
if
(
IS_ERR
(
acl
))
return
PTR_ERR
(
acl
);
}
if
(
!
acl
)
inode
->
i_mode
&=
~
current
->
fs
->
umask
;
}
if
(
IS_POSIXACL
(
dir
)
&&
acl
)
{
struct
posix_acl
*
clone
;
mode_t
mode
;
if
(
S_ISDIR
(
inode
->
i_mode
))
{
ret
=
btrfs_set_acl
(
inode
,
acl
,
ACL_TYPE_DEFAULT
);
if
(
ret
)
goto
failed
;
}
clone
=
posix_acl_clone
(
acl
,
GFP_NOFS
);
ret
=
-
ENOMEM
;
if
(
!
clone
)
goto
failed
;
mode
=
inode
->
i_mode
;
ret
=
posix_acl_create_masq
(
clone
,
&
mode
);
if
(
ret
>=
0
)
{
inode
->
i_mode
=
mode
;
if
(
ret
>
0
)
{
/* we need an acl */
ret
=
btrfs_set_acl
(
inode
,
clone
,
ACL_TYPE_ACCESS
);
}
}
}
failed:
posix_acl_release
(
acl
);
return
ret
;
}
int
btrfs_acl_chmod
(
struct
inode
*
inode
)
{
struct
posix_acl
*
acl
,
*
clone
;
int
ret
=
0
;
if
(
S_ISLNK
(
inode
->
i_mode
))
return
-
EOPNOTSUPP
;
if
(
!
IS_POSIXACL
(
inode
))
return
0
;
acl
=
btrfs_get_acl
(
inode
,
ACL_TYPE_ACCESS
);
if
(
IS_ERR
(
acl
)
||
!
acl
)
return
PTR_ERR
(
acl
);
clone
=
posix_acl_clone
(
acl
,
GFP_KERNEL
);
posix_acl_release
(
acl
);
if
(
!
clone
)
return
-
ENOMEM
;
ret
=
posix_acl_chmod_masq
(
clone
,
inode
->
i_mode
);
if
(
!
ret
)
ret
=
btrfs_set_acl
(
inode
,
clone
,
ACL_TYPE_ACCESS
);
posix_acl_release
(
clone
);
return
ret
;
}
struct
xattr_handler
btrfs_xattr_acl_default_handler
=
{
.
prefix
=
POSIX_ACL_XATTR_DEFAULT
,
.
list
=
btrfs_xattr_generic_list
,
...
...
fs/btrfs/btrfs_inode.h
浏览文件 @
33268eaf
...
...
@@ -36,6 +36,9 @@ struct btrfs_inode {
struct
inode
vfs_inode
;
struct
btrfs_ordered_inode_tree
ordered_tree
;
struct
posix_acl
*
i_acl
;
struct
posix_acl
*
i_default_acl
;
/*
* transid of the trans_handle that last modified this inode
*/
...
...
fs/btrfs/ctree.h
浏览文件 @
33268eaf
...
...
@@ -42,6 +42,8 @@ struct btrfs_ordered_sum;
#define BTRFS_MAGIC "_B5RfS_M"
#define BTRFS_ACL_NOT_CACHED ((void *)-1)
#ifdef CONFIG_LOCKDEP
# define BTRFS_MAX_LEVEL 7
#else
...
...
@@ -1694,4 +1696,9 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
u64
btrfs_parse_size
(
char
*
str
);
int
btrfs_parse_options
(
struct
btrfs_root
*
root
,
char
*
options
);
int
btrfs_sync_fs
(
struct
super_block
*
sb
,
int
wait
);
/* acl.c */
int
btrfs_check_acl
(
struct
inode
*
inode
,
int
mask
);
int
btrfs_init_acl
(
struct
inode
*
inode
,
struct
inode
*
dir
);
int
btrfs_acl_chmod
(
struct
inode
*
inode
);
#endif
fs/btrfs/inode.c
浏览文件 @
33268eaf
...
...
@@ -36,6 +36,7 @@
#include <linux/bit_spinlock.h>
#include <linux/version.h>
#include <linux/xattr.h>
#include <linux/posix_acl.h>
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
...
...
@@ -1478,6 +1479,9 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
}
out:
err
=
inode_setattr
(
inode
,
attr
);
if
(
!
err
&&
((
attr
->
ia_valid
&
ATTR_MODE
)))
err
=
btrfs_acl_chmod
(
inode
);
fail:
return
err
;
}
...
...
@@ -2184,6 +2188,12 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
if
(
IS_ERR
(
inode
))
goto
out_unlock
;
err
=
btrfs_init_acl
(
inode
,
dir
);
if
(
err
)
{
drop_inode
=
1
;
goto
out_unlock
;
}
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
,
0
);
if
(
err
)
...
...
@@ -2239,6 +2249,12 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
if
(
IS_ERR
(
inode
))
goto
out_unlock
;
err
=
btrfs_init_acl
(
inode
,
dir
);
if
(
err
)
{
drop_inode
=
1
;
goto
out_unlock
;
}
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
,
0
);
if
(
err
)
...
...
@@ -2366,6 +2382,11 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
}
drop_on_err
=
1
;
err
=
btrfs_init_acl
(
inode
,
dir
);
if
(
err
)
goto
out_fail
;
inode
->
i_op
=
&
btrfs_dir_inode_operations
;
inode
->
i_fop
=
&
btrfs_dir_file_operations
;
btrfs_set_trans_block_group
(
trans
,
inode
);
...
...
@@ -3023,6 +3044,8 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
return
NULL
;
ei
->
last_trans
=
0
;
btrfs_ordered_inode_tree_init
(
&
ei
->
ordered_tree
);
ei
->
i_acl
=
BTRFS_ACL_NOT_CACHED
;
ei
->
i_default_acl
=
BTRFS_ACL_NOT_CACHED
;
return
&
ei
->
vfs_inode
;
}
...
...
@@ -3032,6 +3055,13 @@ void btrfs_destroy_inode(struct inode *inode)
WARN_ON
(
!
list_empty
(
&
inode
->
i_dentry
));
WARN_ON
(
inode
->
i_data
.
nrpages
);
if
(
BTRFS_I
(
inode
)
->
i_acl
&&
BTRFS_I
(
inode
)
->
i_acl
!=
BTRFS_ACL_NOT_CACHED
)
posix_acl_release
(
BTRFS_I
(
inode
)
->
i_acl
);
if
(
BTRFS_I
(
inode
)
->
i_default_acl
&&
BTRFS_I
(
inode
)
->
i_default_acl
!=
BTRFS_ACL_NOT_CACHED
)
posix_acl_release
(
BTRFS_I
(
inode
)
->
i_default_acl
);
while
(
1
)
{
ordered
=
btrfs_lookup_first_ordered_extent
(
inode
,
(
u64
)
-
1
);
if
(
!
ordered
)
...
...
@@ -3230,6 +3260,12 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
if
(
IS_ERR
(
inode
))
goto
out_unlock
;
err
=
btrfs_init_acl
(
inode
,
dir
);
if
(
err
)
{
drop_inode
=
1
;
goto
out_unlock
;
}
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_add_nondir
(
trans
,
dentry
,
inode
,
0
);
if
(
err
)
...
...
@@ -3310,7 +3346,7 @@ static int btrfs_permission(struct inode *inode, int mask,
{
if
(
btrfs_test_flag
(
inode
,
READONLY
)
&&
(
mask
&
MAY_WRITE
))
return
-
EACCES
;
return
generic_permission
(
inode
,
mask
,
NULL
);
return
generic_permission
(
inode
,
mask
,
btrfs_check_acl
);
}
static
struct
inode_operations
btrfs_dir_inode_operations
=
{
...
...
@@ -3392,6 +3428,10 @@ static struct inode_operations btrfs_special_inode_operations = {
.
getattr
=
btrfs_getattr
,
.
setattr
=
btrfs_setattr
,
.
permission
=
btrfs_permission
,
.
setxattr
=
generic_setxattr
,
.
getxattr
=
generic_getxattr
,
.
listxattr
=
btrfs_listxattr
,
.
removexattr
=
generic_removexattr
,
};
static
struct
inode_operations
btrfs_symlink_inode_operations
=
{
.
readlink
=
generic_readlink
,
...
...
fs/btrfs/super.c
浏览文件 @
33268eaf
...
...
@@ -68,7 +68,7 @@ static void btrfs_put_super (struct super_block * sb)
enum
{
Opt_degraded
,
Opt_subvol
,
Opt_device
,
Opt_nodatasum
,
Opt_nodatacow
,
Opt_max_extent
,
Opt_max_inline
,
Opt_alloc_start
,
Opt_nobarrier
,
Opt_ssd
,
Opt_thread_pool
,
Opt_err
,
Opt_ssd
,
Opt_thread_pool
,
Opt_
noacl
,
Opt_
err
,
};
static
match_table_t
tokens
=
{
...
...
@@ -83,7 +83,8 @@ static match_table_t tokens = {
{
Opt_alloc_start
,
"alloc_start=%s"
},
{
Opt_thread_pool
,
"thread_pool=%d"
},
{
Opt_ssd
,
"ssd"
},
{
Opt_err
,
NULL
}
{
Opt_noacl
,
"noacl"
},
{
Opt_err
,
NULL
},
};
u64
btrfs_parse_size
(
char
*
str
)
...
...
@@ -215,6 +216,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
info
->
alloc_start
);
}
break
;
case
Opt_noacl
:
root
->
fs_info
->
sb
->
s_flags
&=
~
MS_POSIXACL
;
break
;
default:
break
;
}
...
...
@@ -301,6 +305,7 @@ static int btrfs_fill_super(struct super_block * sb,
sb
->
s_op
=
&
btrfs_super_ops
;
sb
->
s_xattr
=
btrfs_xattr_handlers
;
sb
->
s_time_gran
=
1
;
sb
->
s_flags
|=
MS_POSIXACL
;
tree_root
=
open_ctree
(
sb
,
fs_devices
,
(
char
*
)
data
);
...
...
fs/btrfs/xattr.c
浏览文件 @
33268eaf
...
...
@@ -26,25 +26,27 @@
#include "transaction.h"
#include "xattr.h"
#include "disk-io.h"
static
struct
xattr_handler
*
btrfs_xattr_handler_map
[]
=
{
[
BTRFS_XATTR_INDEX_USER
]
=
&
btrfs_xattr_user_handler
,
#ifdef CONFIG_FS_POSIX_ACL
//
[BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS] = &btrfs_xattr_acl_access_handler,
//
[BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &btrfs_xattr_acl_default_handler,
[
BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS
]
=
&
btrfs_xattr_acl_access_handler
,
[
BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT
]
=
&
btrfs_xattr_acl_default_handler
,
#endif
[
BTRFS_XATTR_INDEX_TRUSTED
]
=
&
btrfs_xattr_trusted_handler
,
[
BTRFS_XATTR_INDEX_SECURITY
]
=
&
btrfs_xattr_security_handler
,
//
[BTRFS_XATTR_INDEX_SYSTEM] = &btrfs_xattr_system_handler,
[
BTRFS_XATTR_INDEX_SYSTEM
]
=
&
btrfs_xattr_system_handler
,
};
struct
xattr_handler
*
btrfs_xattr_handlers
[]
=
{
&
btrfs_xattr_user_handler
,
#ifdef CONFIG_FS_POSIX_ACL
//
&btrfs_xattr_acl_access_handler,
//
&btrfs_xattr_acl_default_handler,
&
btrfs_xattr_acl_access_handler
,
&
btrfs_xattr_acl_default_handler
,
#endif
&
btrfs_xattr_trusted_handler
,
&
btrfs_xattr_security_handler
,
//
&btrfs_xattr_system_handler,
&
btrfs_xattr_system_handler
,
NULL
,
};
...
...
@@ -237,10 +239,14 @@ int btrfs_xattr_set(struct inode *inode, int name_index,
mod
=
1
;
goto
out
;
}
}
else
if
(
flags
&
XATTR_REPLACE
)
{
/* we couldn't find the attr to replace, so error out */
ret
=
-
ENODATA
;
goto
out
;
}
else
{
btrfs_release_path
(
root
,
path
);
if
(
flags
&
XATTR_REPLACE
)
{
/* we couldn't find the attr to replace */
ret
=
-
ENODATA
;
goto
out
;
}
}
/* ok we have to create a completely new xattr */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录