1 /* 2 * linux/fs/hfs/attr.c 3 * 4 * (C) 2003 Ardis Technologies <roman@ardistech.com> 5 * 6 * Export hfs data via xattr 7 */ 8 9 10 #include <linux/fs.h> 11 #include <linux/xattr.h> 12 13 #include "hfs_fs.h" 14 #include "btree.h" 15 16 int hfs_setxattr(struct dentry *dentry, const char *name, 17 const void *value, size_t size, int flags) 18 { 19 struct inode *inode = dentry->d_inode; 20 struct hfs_find_data fd; 21 hfs_cat_rec rec; 22 struct hfs_cat_file *file; 23 int res; 24 25 if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode)) 26 return -EOPNOTSUPP; 27 28 res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd); 29 if (res) 30 return res; 31 fd.search_key->cat = HFS_I(inode)->cat_key; 32 res = hfs_brec_find(&fd); 33 if (res) 34 goto out; 35 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, 36 sizeof(struct hfs_cat_file)); 37 file = &rec.file; 38 39 if (!strcmp(name, "hfs.type")) { 40 if (size == 4) 41 memcpy(&file->UsrWds.fdType, value, 4); 42 else 43 res = -ERANGE; 44 } else if (!strcmp(name, "hfs.creator")) { 45 if (size == 4) 46 memcpy(&file->UsrWds.fdCreator, value, 4); 47 else 48 res = -ERANGE; 49 } else 50 res = -EOPNOTSUPP; 51 if (!res) 52 hfs_bnode_write(fd.bnode, &rec, fd.entryoffset, 53 sizeof(struct hfs_cat_file)); 54 out: 55 hfs_find_exit(&fd); 56 return res; 57 } 58 59 ssize_t hfs_getxattr(struct dentry *dentry, const char *name, 60 void *value, size_t size) 61 { 62 struct inode *inode = dentry->d_inode; 63 struct hfs_find_data fd; 64 hfs_cat_rec rec; 65 struct hfs_cat_file *file; 66 ssize_t res = 0; 67 68 if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode)) 69 return -EOPNOTSUPP; 70 71 if (size) { 72 res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd); 73 if (res) 74 return res; 75 fd.search_key->cat = HFS_I(inode)->cat_key; 76 res = hfs_brec_find(&fd); 77 if (res) 78 goto out; 79 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, 80 sizeof(struct hfs_cat_file)); 81 } 82 file = &rec.file; 83 84 if (!strcmp(name, "hfs.type")) { 85 if (size >= 4) { 86 memcpy(value, &file->UsrWds.fdType, 4); 87 res = 4; 88 } else 89 res = size ? -ERANGE : 4; 90 } else if (!strcmp(name, "hfs.creator")) { 91 if (size >= 4) { 92 memcpy(value, &file->UsrWds.fdCreator, 4); 93 res = 4; 94 } else 95 res = size ? -ERANGE : 4; 96 } else 97 res = -ENODATA; 98 out: 99 if (size) 100 hfs_find_exit(&fd); 101 return res; 102 } 103 104 #define HFS_ATTRLIST_SIZE (sizeof("hfs.creator")+sizeof("hfs.type")) 105 106 ssize_t hfs_listxattr(struct dentry *dentry, char *buffer, size_t size) 107 { 108 struct inode *inode = dentry->d_inode; 109 110 if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode)) 111 return -EOPNOTSUPP; 112 113 if (!buffer || !size) 114 return HFS_ATTRLIST_SIZE; 115 if (size < HFS_ATTRLIST_SIZE) 116 return -ERANGE; 117 strcpy(buffer, "hfs.type"); 118 strcpy(buffer + sizeof("hfs.type"), "hfs.creator"); 119 120 return HFS_ATTRLIST_SIZE; 121 } 122