Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / fs / hfs / attr.c
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 }