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"
2016-09-29 18:48:32 +03:00
enum hfs_xattr_type {
HFS_TYPE ,
HFS_CREATOR ,
} ;
static int __hfs_setxattr ( struct inode * inode , enum hfs_xattr_type type ,
const void * value , size_t size , int flags )
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 ;
2016-09-29 18:48:32 +03:00
switch ( type ) {
case HFS_TYPE :
2005-04-17 02:20:36 +04:00
if ( size = = 4 )
memcpy ( & file - > UsrWds . fdType , value , 4 ) ;
else
res = - ERANGE ;
2016-09-29 18:48:32 +03:00
break ;
case HFS_CREATOR :
2005-04-17 02:20:36 +04:00
if ( size = = 4 )
memcpy ( & file - > UsrWds . fdCreator , value , 4 ) ;
else
res = - ERANGE ;
2016-09-29 18:48:32 +03:00
break ;
}
2005-04-17 02:20:36 +04:00
if ( ! res )
hfs_bnode_write ( fd . bnode , & rec , fd . entryoffset ,
sizeof ( struct hfs_cat_file ) ) ;
out :
hfs_find_exit ( & fd ) ;
return res ;
}
2016-09-29 18:48:32 +03:00
static ssize_t __hfs_getxattr ( struct inode * inode , enum hfs_xattr_type type ,
void * value , size_t size )
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 ;
2016-09-29 18:48:32 +03:00
switch ( type ) {
case HFS_TYPE :
2005-04-17 02:20:36 +04:00
if ( size > = 4 ) {
memcpy ( value , & file - > UsrWds . fdType , 4 ) ;
res = 4 ;
} else
res = size ? - ERANGE : 4 ;
2016-09-29 18:48:32 +03:00
break ;
case HFS_CREATOR :
2005-04-17 02:20:36 +04:00
if ( size > = 4 ) {
memcpy ( value , & file - > UsrWds . fdCreator , 4 ) ;
res = 4 ;
} else
res = size ? - ERANGE : 4 ;
2016-09-29 18:48:32 +03:00
break ;
}
2005-04-17 02:20:36 +04:00
out :
if ( size )
hfs_find_exit ( & fd ) ;
return res ;
}
2016-09-29 18:48:32 +03:00
static int hfs_xattr_get ( const struct xattr_handler * handler ,
struct dentry * unused , struct inode * inode ,
const char * name , void * value , size_t size )
2005-04-17 02:20:36 +04:00
{
2016-09-29 18:48:32 +03:00
return __hfs_getxattr ( inode , handler - > flags , value , size ) ;
}
2005-04-17 02:20:36 +04:00
2016-09-29 18:48:32 +03:00
static int hfs_xattr_set ( const struct xattr_handler * handler ,
struct dentry * unused , struct inode * inode ,
const char * name , const void * value , size_t size ,
int flags )
{
if ( ! value )
2005-04-17 02:20:36 +04:00
return - EOPNOTSUPP ;
2016-09-29 18:48:32 +03:00
return __hfs_setxattr ( inode , handler - > flags , value , size , flags ) ;
2005-04-17 02:20:36 +04:00
}
2016-09-29 18:48:32 +03:00
static const struct xattr_handler hfs_creator_handler = {
. name = " hfs.creator " ,
. flags = HFS_CREATOR ,
. get = hfs_xattr_get ,
. set = hfs_xattr_set ,
} ;
static const struct xattr_handler hfs_type_handler = {
. name = " hfs.type " ,
. flags = HFS_TYPE ,
. get = hfs_xattr_get ,
. set = hfs_xattr_set ,
} ;
const struct xattr_handler * hfs_xattr_handlers [ ] = {
& hfs_creator_handler ,
& hfs_type_handler ,
NULL
} ;