linux/fs/hfs/attr.c
<<
>>
Prefs
   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
  16enum hfs_xattr_type {
  17        HFS_TYPE,
  18        HFS_CREATOR,
  19};
  20
  21static int __hfs_setxattr(struct inode *inode, enum hfs_xattr_type type,
  22                          const void *value, size_t size, int flags)
  23{
  24        struct hfs_find_data fd;
  25        hfs_cat_rec rec;
  26        struct hfs_cat_file *file;
  27        int res;
  28
  29        if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
  30                return -EOPNOTSUPP;
  31
  32        res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);
  33        if (res)
  34                return res;
  35        fd.search_key->cat = HFS_I(inode)->cat_key;
  36        res = hfs_brec_find(&fd);
  37        if (res)
  38                goto out;
  39        hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
  40                        sizeof(struct hfs_cat_file));
  41        file = &rec.file;
  42
  43        switch (type) {
  44        case HFS_TYPE:
  45                if (size == 4)
  46                        memcpy(&file->UsrWds.fdType, value, 4);
  47                else
  48                        res = -ERANGE;
  49                break;
  50
  51        case HFS_CREATOR:
  52                if (size == 4)
  53                        memcpy(&file->UsrWds.fdCreator, value, 4);
  54                else
  55                        res = -ERANGE;
  56                break;
  57        }
  58
  59        if (!res)
  60                hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
  61                                sizeof(struct hfs_cat_file));
  62out:
  63        hfs_find_exit(&fd);
  64        return res;
  65}
  66
  67static ssize_t __hfs_getxattr(struct inode *inode, enum hfs_xattr_type type,
  68                              void *value, size_t size)
  69{
  70        struct hfs_find_data fd;
  71        hfs_cat_rec rec;
  72        struct hfs_cat_file *file;
  73        ssize_t res = 0;
  74
  75        if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
  76                return -EOPNOTSUPP;
  77
  78        if (size) {
  79                res = hfs_find_init(HFS_SB(inode->i_sb)->cat_tree, &fd);
  80                if (res)
  81                        return res;
  82                fd.search_key->cat = HFS_I(inode)->cat_key;
  83                res = hfs_brec_find(&fd);
  84                if (res)
  85                        goto out;
  86                hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
  87                                sizeof(struct hfs_cat_file));
  88        }
  89        file = &rec.file;
  90
  91        switch (type) {
  92        case HFS_TYPE:
  93                if (size >= 4) {
  94                        memcpy(value, &file->UsrWds.fdType, 4);
  95                        res = 4;
  96                } else
  97                        res = size ? -ERANGE : 4;
  98                break;
  99
 100        case HFS_CREATOR:
 101                if (size >= 4) {
 102                        memcpy(value, &file->UsrWds.fdCreator, 4);
 103                        res = 4;
 104                } else
 105                        res = size ? -ERANGE : 4;
 106                break;
 107        }
 108
 109out:
 110        if (size)
 111                hfs_find_exit(&fd);
 112        return res;
 113}
 114
 115static int hfs_xattr_get(const struct xattr_handler *handler,
 116                         struct dentry *unused, struct inode *inode,
 117                         const char *name, void *value, size_t size)
 118{
 119        return __hfs_getxattr(inode, handler->flags, value, size);
 120}
 121
 122static int hfs_xattr_set(const struct xattr_handler *handler,
 123                         struct dentry *unused, struct inode *inode,
 124                         const char *name, const void *value, size_t size,
 125                         int flags)
 126{
 127        if (!value)
 128                return -EOPNOTSUPP;
 129
 130        return __hfs_setxattr(inode, handler->flags, value, size, flags);
 131}
 132
 133static const struct xattr_handler hfs_creator_handler = {
 134        .name = "hfs.creator",
 135        .flags = HFS_CREATOR,
 136        .get = hfs_xattr_get,
 137        .set = hfs_xattr_set,
 138};
 139
 140static const struct xattr_handler hfs_type_handler = {
 141        .name = "hfs.type",
 142        .flags = HFS_TYPE,
 143        .get = hfs_xattr_get,
 144        .set = hfs_xattr_set,
 145};
 146
 147const struct xattr_handler *hfs_xattr_handlers[] = {
 148        &hfs_creator_handler,
 149        &hfs_type_handler,
 150        NULL
 151};
 152