@ -319,8 +319,7 @@ static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode,
static int __set_xattr ( struct ceph_inode_info * ci ,
const char * name , int name_len ,
const char * val , int val_len ,
int dirty ,
int should_free_name , int should_free_val ,
int flags , int update_xattr ,
struct ceph_inode_xattr * * newxattr )
{
struct rb_node * * p ;
@ -349,12 +348,25 @@ static int __set_xattr(struct ceph_inode_info *ci,
xattr = NULL ;
}
if ( update_xattr ) {
int err = 0 ;
if ( xattr & & ( flags & XATTR_CREATE ) )
err = - EEXIST ;
else if ( ! xattr & & ( flags & XATTR_REPLACE ) )
err = - ENODATA ;
if ( err ) {
kfree ( name ) ;
kfree ( val ) ;
return err ;
}
}
if ( ! xattr ) {
new = 1 ;
xattr = * newxattr ;
xattr - > name = name ;
xattr - > name_len = name_len ;
xattr - > should_free_name = should_free_name ;
xattr - > should_free_name = update_xattr ;
ci - > i_xattrs . count + + ;
dout ( " __set_xattr count=%d \n " , ci - > i_xattrs . count ) ;
@ -364,7 +376,7 @@ static int __set_xattr(struct ceph_inode_info *ci,
if ( xattr - > should_free_val )
kfree ( ( void * ) xattr - > val ) ;
if ( should_free_name ) {
if ( update_xattr ) {
kfree ( ( void * ) name ) ;
name = xattr - > name ;
}
@ -379,8 +391,8 @@ static int __set_xattr(struct ceph_inode_info *ci,
xattr - > val = " " ;
xattr - > val_len = val_len ;
xattr - > dirty = dirty ;
xattr - > should_free_val = ( val & & should_free_val ) ;
xattr - > dirty = update_xattr ;
xattr - > should_free_val = ( val & & update_xattr ) ;
if ( new ) {
rb_link_node ( & xattr - > node , parent , p ) ;
@ -588,7 +600,7 @@ start:
p + = len ;
err = __set_xattr ( ci , name , namelen , val , len ,
0 , 0 , 0 , & xattrs [ numattr ] ) ;
0 , 0 , & xattrs [ numattr ] ) ;
if ( err < 0 )
goto bad ;
@ -892,7 +904,7 @@ int __ceph_setxattr(struct dentry *dentry, const char *name,
struct ceph_inode_info * ci = ceph_inode ( inode ) ;
int issued ;
int err ;
int dirty ;
int dirty = 0 ;
int name_len = strlen ( name ) ;
int val_len = size ;
char * newname = NULL ;
@ -954,11 +966,13 @@ retry:
}
err = __set_xattr ( ci , newname , name_len , newval ,
val_len , 1 , 1 , 1 , & xattr ) ;
val_len , flags , 1 , & xattr ) ;
dirty = __ceph_mark_dirty_caps ( ci , CEPH_CAP_XATTR_EXCL ) ;
ci - > i_xattrs . dirty = true ;
inode - > i_ctime = CURRENT_TIME ;
if ( ! err ) {
dirty = __ceph_mark_dirty_caps ( ci , CEPH_CAP_XATTR_EXCL ) ;
ci - > i_xattrs . dirty = true ;
inode - > i_ctime = CURRENT_TIME ;
}
spin_unlock ( & ci - > i_ceph_lock ) ;
if ( dirty )