2005-04-17 02:20:36 +04:00
/*
* linux / fs / hfs / attr . c
*
* ( C ) 2003 Ardis Technologies < roman @ ardistech . com >
*
* Export hfs data via xattr
*/
# include <linux/fs.h>
# include <linux/xattr.h>
# include "hfs_fs.h"
# include "btree.h"
int hfs_setxattr ( struct dentry * dentry , const char * name ,
const void * value , size_t size , int flags )
{
2015-03-18 01:25:59 +03:00
struct inode * inode = d_inode ( dentry ) ;
2005-04-17 02:20:36 +04:00
struct hfs_find_data fd ;
hfs_cat_rec rec ;
struct hfs_cat_file * file ;
int res ;
if ( ! S_ISREG ( inode - > i_mode ) | | HFS_IS_RSRC ( inode ) )
return - EOPNOTSUPP ;
res = hfs_find_init ( HFS_SB ( inode - > i_sb ) - > cat_tree , & fd ) ;
if ( res )
return res ;
fd . search_key - > cat = HFS_I ( inode ) - > cat_key ;
res = hfs_brec_find ( & fd ) ;
if ( res )
goto out ;
hfs_bnode_read ( fd . bnode , & rec , fd . entryoffset ,
sizeof ( struct hfs_cat_file ) ) ;
file = & rec . file ;
if ( ! strcmp ( name , " hfs.type " ) ) {
if ( size = = 4 )
memcpy ( & file - > UsrWds . fdType , value , 4 ) ;
else
res = - ERANGE ;
} else if ( ! strcmp ( name , " hfs.creator " ) ) {
if ( size = = 4 )
memcpy ( & file - > UsrWds . fdCreator , value , 4 ) ;
else
res = - ERANGE ;
} else
res = - EOPNOTSUPP ;
if ( ! res )
hfs_bnode_write ( fd . bnode , & rec , fd . entryoffset ,
sizeof ( struct hfs_cat_file ) ) ;
out :
hfs_find_exit ( & fd ) ;
return res ;
}
ssize_t hfs_getxattr ( struct dentry * dentry , const char * name ,
void * value , size_t size )
{
2015-03-18 01:25:59 +03:00
struct inode * inode = d_inode ( dentry ) ;
2005-04-17 02:20:36 +04:00
struct hfs_find_data fd ;
hfs_cat_rec rec ;
struct hfs_cat_file * file ;
ssize_t res = 0 ;
if ( ! S_ISREG ( inode - > i_mode ) | | HFS_IS_RSRC ( inode ) )
return - EOPNOTSUPP ;
if ( size ) {
res = hfs_find_init ( HFS_SB ( inode - > i_sb ) - > cat_tree , & fd ) ;
if ( res )
return res ;
fd . search_key - > cat = HFS_I ( inode ) - > cat_key ;
res = hfs_brec_find ( & fd ) ;
if ( res )
goto out ;
hfs_bnode_read ( fd . bnode , & rec , fd . entryoffset ,
sizeof ( struct hfs_cat_file ) ) ;
}
file = & rec . file ;
if ( ! strcmp ( name , " hfs.type " ) ) {
if ( size > = 4 ) {
memcpy ( value , & file - > UsrWds . fdType , 4 ) ;
res = 4 ;
} else
res = size ? - ERANGE : 4 ;
} else if ( ! strcmp ( name , " hfs.creator " ) ) {
if ( size > = 4 ) {
memcpy ( value , & file - > UsrWds . fdCreator , 4 ) ;
res = 4 ;
} else
res = size ? - ERANGE : 4 ;
} else
res = - ENODATA ;
out :
if ( size )
hfs_find_exit ( & fd ) ;
return res ;
}
# define HFS_ATTRLIST_SIZE (sizeof("hfs.creator")+sizeof("hfs.type"))
ssize_t hfs_listxattr ( struct dentry * dentry , char * buffer , size_t size )
{
2015-03-18 01:25:59 +03:00
struct inode * inode = d_inode ( dentry ) ;
2005-04-17 02:20:36 +04:00
if ( ! S_ISREG ( inode - > i_mode ) | | HFS_IS_RSRC ( inode ) )
return - EOPNOTSUPP ;
if ( ! buffer | | ! size )
return HFS_ATTRLIST_SIZE ;
if ( size < HFS_ATTRLIST_SIZE )
return - ERANGE ;
strcpy ( buffer , " hfs.type " ) ;
strcpy ( buffer + sizeof ( " hfs.type " ) , " hfs.creator " ) ;
return HFS_ATTRLIST_SIZE ;
}