Blame view

kernel/linux-imx6_3.14.28/fs/hfs/attr.c 2.6 KB
6b13f685e   김민수   BSP 최초 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  /*
   *  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;
  }