xref: /openbmc/linux/fs/hfs/attr.c (revision 3ca9760fdfa411f7e5db54b3437fbb858d2ec825)
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