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 *unused, struct inode *inode, 17 const char *name, const void *value, 18 size_t size, int flags) 19 { 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 *unused, struct inode *inode, 60 const char *name, void *value, size_t size) 61 { 62 struct hfs_find_data fd; 63 hfs_cat_rec rec; 64 struct hfs_cat_file *file; 65 ssize_t res = 0; 66 67 if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode)) 68 return -EOPNOTSUPP; 69 70 if (size) { 71 res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd); 72 if (res) 73 return res; 74 fd.search_key->cat = HFS_I(inode)->cat_key; 75 res = hfs_brec_find(&fd); 76 if (res) 77 goto out; 78 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, 79 sizeof(struct hfs_cat_file)); 80 } 81 file = &rec.file; 82 83 if (!strcmp(name, "hfs.type")) { 84 if (size >= 4) { 85 memcpy(value, &file->UsrWds.fdType, 4); 86 res = 4; 87 } else 88 res = size ? -ERANGE : 4; 89 } else if (!strcmp(name, "hfs.creator")) { 90 if (size >= 4) { 91 memcpy(value, &file->UsrWds.fdCreator, 4); 92 res = 4; 93 } else 94 res = size ? -ERANGE : 4; 95 } else 96 res = -ENODATA; 97 out: 98 if (size) 99 hfs_find_exit(&fd); 100 return res; 101 } 102 103 #define HFS_ATTRLIST_SIZE (sizeof("hfs.creator")+sizeof("hfs.type")) 104 105 ssize_t hfs_listxattr(struct dentry *dentry, char *buffer, size_t size) 106 { 107 struct inode *inode = d_inode(dentry); 108 109 if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode)) 110 return -EOPNOTSUPP; 111 112 if (!buffer || !size) 113 return HFS_ATTRLIST_SIZE; 114 if (size < HFS_ATTRLIST_SIZE) 115 return -ERANGE; 116 strcpy(buffer, "hfs.type"); 117 strcpy(buffer + sizeof("hfs.type"), "hfs.creator"); 118 119 return HFS_ATTRLIST_SIZE; 120 } 121