4 * Copyright (c) International Business Machines Corp., 2003
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/posix_acl_xattr.h>
27 #include "cifsproto.h"
28 #include "cifs_debug.h"
30 #define MAX_EA_VALUE_SIZE 65535
31 #define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
32 #define CIFS_XATTR_USER_PREFIX "user."
33 #define CIFS_XATTR_SYSTEM_PREFIX "system."
34 #define CIFS_XATTR_OS2_PREFIX "os2."
35 #define CIFS_XATTR_SECURITY_PREFIX ".security"
36 #define CIFS_XATTR_TRUSTED_PREFIX "trusted."
37 #define XATTR_TRUSTED_PREFIX_LEN 8
38 #define XATTR_SECURITY_PREFIX_LEN 9
39 /* BB need to add server (Samba e.g) support for security and trusted prefix */
43 int cifs_removexattr(struct dentry * direntry, const char * ea_name)
46 #ifdef CONFIG_CIFS_XATTR
48 struct cifs_sb_info *cifs_sb;
49 struct cifsTconInfo *pTcon;
50 struct super_block * sb;
55 if(direntry->d_inode == NULL)
57 sb = direntry->d_inode->i_sb;
62 cifs_sb = CIFS_SB(sb);
63 pTcon = cifs_sb->tcon;
65 down(&sb->s_vfs_rename_sem);
66 full_path = build_path_from_dentry(direntry);
67 up(&sb->s_vfs_rename_sem);
68 if(full_path == NULL) {
73 cFYI(1,("Null xattr names not supported"));
74 } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5)) {
75 cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name));
76 /* BB what if no namespace prefix? */
77 /* Should we just pass them to server, except for
78 system and perhaps security prefixes? */
80 ea_name+=5; /* skip past user. prefix */
81 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,NULL,
82 (__u16)0, cifs_sb->local_nls);
91 int cifs_setxattr(struct dentry * direntry, const char * ea_name,
92 const void * ea_value, size_t value_size, int flags)
95 #ifdef CONFIG_CIFS_XATTR
97 struct cifs_sb_info *cifs_sb;
98 struct cifsTconInfo *pTcon;
99 struct super_block * sb;
104 if(direntry->d_inode == NULL)
106 sb = direntry->d_inode->i_sb;
111 cifs_sb = CIFS_SB(sb);
112 pTcon = cifs_sb->tcon;
114 down(&sb->s_vfs_rename_sem);
115 full_path = build_path_from_dentry(direntry);
116 up(&sb->s_vfs_rename_sem);
117 if(full_path == NULL) {
121 /* return dos attributes as pseudo xattr */
122 /* return alt name if available as pseudo attr */
124 /* if proc/fs/cifs/streamstoxattr is set then
125 search server for EAs or streams to
127 if(value_size > MAX_EA_VALUE_SIZE) {
128 cFYI(1,("size of EA value too large"));
135 if(ea_name == NULL) {
136 cFYI(1,("Null xattr names not supported"));
137 } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) {
138 if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) {
139 cFYI(1,("attempt to set cifs inode metadata"));
141 ea_name += 5; /* skip past user. prefix */
142 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
143 (__u16)value_size, cifs_sb->local_nls);
144 } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) {
145 ea_name += 4; /* skip past os2. prefix */
146 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
147 (__u16)value_size, cifs_sb->local_nls);
150 temp = strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,
151 strlen(POSIX_ACL_XATTR_ACCESS));
153 #ifdef CONFIG_CIFS_POSIX
154 rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,ea_value,
155 (const int)value_size, ACL_TYPE_ACCESS,
157 cFYI(1,("set POSIX ACL rc %d",rc));
159 cFYI(1,("set POSIX ACL not supported"));
161 } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
162 #ifdef CONFIG_CIFS_POSIX
163 rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,ea_value,
164 (const int)value_size, ACL_TYPE_DEFAULT,
166 cFYI(1,("set POSIX default ACL rc %d",rc));
168 cFYI(1,("set default POSIX ACL not supported"));
171 cFYI(1,("illegal xattr request %s (only user namespace supported)",ea_name));
172 /* BB what if no namespace prefix? */
173 /* Should we just pass them to server, except for
174 system and perhaps security prefixes? */
185 ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
186 void * ea_value, size_t buf_size)
188 ssize_t rc = -EOPNOTSUPP;
189 #ifdef CONFIG_CIFS_XATTR
191 struct cifs_sb_info *cifs_sb;
192 struct cifsTconInfo *pTcon;
193 struct super_block * sb;
198 if(direntry->d_inode == NULL)
200 sb = direntry->d_inode->i_sb;
206 cifs_sb = CIFS_SB(sb);
207 pTcon = cifs_sb->tcon;
209 down(&sb->s_vfs_rename_sem);
210 full_path = build_path_from_dentry(direntry);
211 up(&sb->s_vfs_rename_sem);
212 if(full_path == NULL) {
216 /* return dos attributes as pseudo xattr */
217 /* return alt name if available as pseudo attr */
218 if(ea_name == NULL) {
219 cFYI(1,("Null xattr names not supported"));
220 } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) {
221 if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) {
222 cFYI(1,("attempt to query cifs inode metadata"));
223 /* revalidate/getattr then populate from inode */
224 } /* BB add else when above is implemented */
225 ea_name += 5; /* skip past user. prefix */
226 rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
227 buf_size, cifs_sb->local_nls);
228 } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) {
229 ea_name += 4; /* skip past os2. prefix */
230 rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
231 buf_size, cifs_sb->local_nls);
232 } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
233 #ifdef CONFIG_CIFS_POSIX
234 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
235 ea_value, buf_size, ACL_TYPE_ACCESS,
238 cFYI(1,("query POSIX ACL not supported yet"));
239 #endif /* CONFIG_CIFS_POSIX */
240 } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
241 #ifdef CONFIG_CIFS_POSIX
242 rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
243 ea_value, buf_size, ACL_TYPE_DEFAULT,
246 cFYI(1,("query POSIX default ACL not supported yet"));
248 } else if(strncmp(ea_name,
249 CIFS_XATTR_TRUSTED_PREFIX,XATTR_TRUSTED_PREFIX_LEN) == 0) {
250 cFYI(1,("Trusted xattr namespace not supported yet"));
251 } else if(strncmp(ea_name,
252 CIFS_XATTR_SECURITY_PREFIX,XATTR_SECURITY_PREFIX_LEN) == 0) {
253 cFYI(1,("Security xattr namespace not supported yet"));
255 cFYI(1,("illegal xattr name request %s (only user namespace supported)",ea_name));
258 /* We could add an additional check for streams ie
259 if proc/fs/cifs/streamstoxattr is set then
260 search server for EAs or streams to
273 ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
275 ssize_t rc = -EOPNOTSUPP;
276 #ifdef CONFIG_CIFS_XATTR
278 struct cifs_sb_info *cifs_sb;
279 struct cifsTconInfo *pTcon;
280 struct super_block * sb;
285 if(direntry->d_inode == NULL)
287 sb = direntry->d_inode->i_sb;
292 cifs_sb = CIFS_SB(sb);
293 pTcon = cifs_sb->tcon;
295 down(&sb->s_vfs_rename_sem);
296 full_path = build_path_from_dentry(direntry);
297 up(&sb->s_vfs_rename_sem);
298 if(full_path == NULL) {
302 /* return dos attributes as pseudo xattr */
303 /* return alt name if available as pseudo attr */
305 /* if proc/fs/cifs/streamstoxattr is set then
306 search server for EAs or streams to
308 rc = CIFSSMBQAllEAs(xid,pTcon,full_path,data,buf_size,