Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
attr.c
Go to the documentation of this file.
1 /*
2  * linux/fs/hfs/attr.c
3  *
4  * (C) 2003 Ardis Technologies <[email protected]>
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 *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));
54 out:
55  hfs_find_exit(&fd);
56  return res;
57 }
58 
59 ssize_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;
98 out:
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 
106 ssize_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 }