Root/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
16int 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));
54out:
55    hfs_find_exit(&fd);
56    return res;
57}
58
59ssize_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;
98out:
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
106ssize_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

Archive Download this file



interactive