[funini.com] -> [kei@sodan] -> Kernel Reading

root/fs/hfs/attr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hfs_setxattr
  2. hfs_getxattr
  3. hfs_listxattr

/*
 *  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"

int hfs_setxattr(struct dentry *dentry, const char *name,
                 const void *value, size_t size, int flags)
{
        struct inode *inode = dentry->d_inode;
        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;

        if (!strcmp(name, "hfs.type")) {
                if (size == 4)
                        memcpy(&file->UsrWds.fdType, value, 4);
                else
                        res = -ERANGE;
        } else if (!strcmp(name, "hfs.creator")) {
                if (size == 4)
                        memcpy(&file->UsrWds.fdCreator, value, 4);
                else
                        res = -ERANGE;
        } else
                res = -EOPNOTSUPP;
        if (!res)
                hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
                                sizeof(struct hfs_cat_file));
out:
        hfs_find_exit(&fd);
        return res;
}

ssize_t hfs_getxattr(struct dentry *dentry, const char *name,
                         void *value, size_t size)
{
        struct inode *inode = dentry->d_inode;
        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;

        if (!strcmp(name, "hfs.type")) {
                if (size >= 4) {
                        memcpy(value, &file->UsrWds.fdType, 4);
                        res = 4;
                } else
                        res = size ? -ERANGE : 4;
        } else if (!strcmp(name, "hfs.creator")) {
                if (size >= 4) {
                        memcpy(value, &file->UsrWds.fdCreator, 4);
                        res = 4;
                } else
                        res = size ? -ERANGE : 4;
        } else
                res = -ENODATA;
out:
        if (size)
                hfs_find_exit(&fd);
        return res;
}

#define HFS_ATTRLIST_SIZE (sizeof("hfs.creator")+sizeof("hfs.type"))

ssize_t hfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
        struct inode *inode = dentry->d_inode;

        if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode))
                return -EOPNOTSUPP;

        if (!buffer || !size)
                return HFS_ATTRLIST_SIZE;
        if (size < HFS_ATTRLIST_SIZE)
                return -ERANGE;
        strcpy(buffer, "hfs.type");
        strcpy(buffer + sizeof("hfs.type"), "hfs.creator");

        return HFS_ATTRLIST_SIZE;
}

/* [<][>][^][v][top][bottom][index][help] */

[funini.com] -> [kei@sodan] -> Kernel Reading