Linux Audio

Check our new training course

Loading...
  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}