@ -26,6 +26,7 @@ static bool ceph_is_valid_xattr(const char *name)
*/
struct ceph_vxattr {
char * name ;
size_t name_size ; /* strlen(name) + 1 (for '\0') */
size_t ( * getxattr_cb ) ( struct ceph_inode_info * ci , char * val ,
size_t size ) ;
bool readonly ;
@ -87,6 +88,7 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
# define XATTR_NAME_CEPH(_type, _name) \
{ \
. name = CEPH_XATTR_NAME ( _type , _name ) , \
. name_size = sizeof ( CEPH_XATTR_NAME ( _type , _name ) ) , \
. getxattr_cb = ceph_vxattrcb_ # # _type # # _ # # _name , \
. readonly = true , \
}
@ -102,6 +104,7 @@ static struct ceph_vxattr ceph_dir_vxattrs[] = {
XATTR_NAME_CEPH ( dir , rctime ) ,
{ 0 } /* Required table terminator */
} ;
static size_t ceph_dir_vxattrs_name_size ; /* total size of all names */
/* files */
@ -127,11 +130,13 @@ static struct ceph_vxattr ceph_file_vxattrs[] = {
/* The following extended attribute name is deprecated */
{
. name = XATTR_CEPH_PREFIX " layout " ,
. name_size = sizeof ( XATTR_CEPH_PREFIX " layout " ) ,
. getxattr_cb = ceph_vxattrcb_file_layout ,
. readonly = true ,
} ,
{ 0 } /* Required table terminator */
} ;
static size_t ceph_file_vxattrs_name_size ; /* total size of all names */
static struct ceph_vxattr * ceph_inode_vxattrs ( struct inode * inode )
{
@ -142,6 +147,46 @@ static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode)
return NULL ;
}
static size_t ceph_vxattrs_name_size ( struct ceph_vxattr * vxattrs )
{
if ( vxattrs = = ceph_dir_vxattrs )
return ceph_dir_vxattrs_name_size ;
if ( vxattrs = = ceph_file_vxattrs )
return ceph_file_vxattrs_name_size ;
BUG ( ) ;
return 0 ;
}
/*
* Compute the aggregate size ( including terminating ' \0 ' ) of all
* virtual extended attribute names in the given vxattr table .
*/
static size_t __init vxattrs_name_size ( struct ceph_vxattr * vxattrs )
{
struct ceph_vxattr * vxattr ;
size_t size = 0 ;
for ( vxattr = vxattrs ; vxattr - > name ; vxattr + + )
size + = vxattr - > name_size ;
return size ;
}
/* Routines called at initialization and exit time */
void __init ceph_xattr_init ( void )
{
ceph_dir_vxattrs_name_size = vxattrs_name_size ( ceph_dir_vxattrs ) ;
ceph_file_vxattrs_name_size = vxattrs_name_size ( ceph_file_vxattrs ) ;
}
void ceph_xattr_exit ( void )
{
ceph_dir_vxattrs_name_size = 0 ;
ceph_file_vxattrs_name_size = 0 ;
}
static struct ceph_vxattr * ceph_match_vxattr ( struct inode * inode ,
const char * name )
{
@ -615,11 +660,12 @@ ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
goto out ;
list_xattr :
vir_namelen = 0 ;
/* include virtual dir xattrs */
if ( vxattrs )
for ( i = 0 ; vxattrs [ i ] . name ; i + + )
vir_namelen + = strlen ( vxattrs [ i ] . name ) + 1 ;
/*
* Start with virtual dir xattr names ( if any ) ( including
* terminating ' \0 ' characters for each ) .
*/
vir_namelen = ceph_vxattrs_name_size ( vxattrs ) ;
/* adding 1 byte per each variable due to the null termination */
namelen = vir_namelen + ci - > i_xattrs . names_size + ci - > i_xattrs . count ;
err = - ERANGE ;