Blame view
fs/hfs/attr.c
3.02 KB
b24413180
|
1 |
// SPDX-License-Identifier: GPL-2.0 |
1da177e4c
|
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* * 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" |
b8020eff7
|
16 17 18 19 20 21 22 |
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) |
1da177e4c
|
23 |
{ |
1da177e4c
|
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
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; |
b8020eff7
|
42 43 |
switch (type) { case HFS_TYPE: |
1da177e4c
|
44 45 46 47 |
if (size == 4) memcpy(&file->UsrWds.fdType, value, 4); else res = -ERANGE; |
b8020eff7
|
48 49 50 |
break; case HFS_CREATOR: |
1da177e4c
|
51 52 53 54 |
if (size == 4) memcpy(&file->UsrWds.fdCreator, value, 4); else res = -ERANGE; |
b8020eff7
|
55 56 |
break; } |
1da177e4c
|
57 58 59 60 61 62 63 |
if (!res) hfs_bnode_write(fd.bnode, &rec, fd.entryoffset, sizeof(struct hfs_cat_file)); out: hfs_find_exit(&fd); return res; } |
b8020eff7
|
64 65 |
static ssize_t __hfs_getxattr(struct inode *inode, enum hfs_xattr_type type, void *value, size_t size) |
1da177e4c
|
66 |
{ |
1da177e4c
|
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
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; |
b8020eff7
|
87 88 |
switch (type) { case HFS_TYPE: |
1da177e4c
|
89 90 91 92 93 |
if (size >= 4) { memcpy(value, &file->UsrWds.fdType, 4); res = 4; } else res = size ? -ERANGE : 4; |
b8020eff7
|
94 95 96 |
break; case HFS_CREATOR: |
1da177e4c
|
97 98 99 100 101 |
if (size >= 4) { memcpy(value, &file->UsrWds.fdCreator, 4); res = 4; } else res = size ? -ERANGE : 4; |
b8020eff7
|
102 103 |
break; } |
1da177e4c
|
104 105 106 107 108 |
out: if (size) hfs_find_exit(&fd); return res; } |
b8020eff7
|
109 110 111 |
static int hfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, void *value, size_t size) |
1da177e4c
|
112 |
{ |
b8020eff7
|
113 114 |
return __hfs_getxattr(inode, handler->flags, value, size); } |
1da177e4c
|
115 |
|
b8020eff7
|
116 117 118 119 120 121 |
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) |
1da177e4c
|
122 |
return -EOPNOTSUPP; |
b8020eff7
|
123 |
return __hfs_setxattr(inode, handler->flags, value, size, flags); |
1da177e4c
|
124 |
} |
b8020eff7
|
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
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 }; |