VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / fs / cifs / xattr.c
1 /*
2  *   fs/cifs/xattr.c
3  *
4  *   Copyright (c) International Business Machines  Corp., 2003
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include <linux/fs.h>
23 #include "cifsfs.h"
24 #include "cifspdu.h"
25 #include "cifsglob.h"
26 #include "cifsproto.h"
27 #include "cifs_debug.h"
28
29 #define MAX_EA_VALUE_SIZE 65535
30 #define CIFS_XATTR_DOS_ATTRIB "user.DOSATTRIB"
31 #define CIFS_XATTR_USER_PREFIX "user."
32 #define CIFS_XATTR_SYSTEM_PREFIX "system."
33 #define CIFS_XATTR_OS2_PREFIX "OS2." /* BB should check for this someday */
34 /* also note could add check for security prefix XATTR_SECURITY_PREFIX */ 
35
36
37 int cifs_removexattr(struct dentry * direntry, const char * ea_name)
38 {
39         int rc = -EOPNOTSUPP;
40 #ifdef CONFIG_CIFS_XATTR
41         int xid;
42         struct cifs_sb_info *cifs_sb;
43         struct cifsTconInfo *pTcon;
44         struct super_block * sb;
45         char * full_path;
46                                                                                      
47         if(direntry == NULL)
48                 return -EIO;
49         if(direntry->d_inode == NULL)
50                 return -EIO;
51         sb = direntry->d_inode->i_sb;
52         if(sb == NULL)
53                 return -EIO;
54         xid = GetXid();
55                                                                                      
56         cifs_sb = CIFS_SB(sb);
57         pTcon = cifs_sb->tcon;
58                                                                                      
59         down(&sb->s_vfs_rename_sem);
60         full_path = build_path_from_dentry(direntry);
61         up(&sb->s_vfs_rename_sem);
62         if(full_path == NULL) {
63                 FreeXid(xid);
64                 return -ENOMEM;
65         }
66         if(ea_name == NULL) {
67                 cFYI(1,("Null xattr names not supported"));
68         } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5)) {
69                 cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name));
70                 /* BB what if no namespace prefix? */
71                 /* Should we just pass them to server, except for
72                 system and perhaps security prefixes? */
73         } else {
74                 ea_name+=5; /* skip past user. prefix */
75                 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,NULL,
76                         (__u16)0, cifs_sb->local_nls);
77         }
78         if (full_path)
79                 kfree(full_path);
80         FreeXid(xid);
81 #endif
82         return rc;
83 }
84
85 int cifs_setxattr(struct dentry * direntry, const char * ea_name,
86         const void * ea_value, size_t value_size, int flags)
87 {
88         int rc = -EOPNOTSUPP;
89 #ifdef CONFIG_CIFS_XATTR
90         int xid;
91         struct cifs_sb_info *cifs_sb;
92         struct cifsTconInfo *pTcon;
93         struct super_block * sb;
94         char * full_path;
95
96         if(direntry == NULL)
97                 return -EIO;
98         if(direntry->d_inode == NULL)
99                 return -EIO;
100         sb = direntry->d_inode->i_sb;
101         if(sb == NULL)
102                 return -EIO;
103         xid = GetXid();
104
105         cifs_sb = CIFS_SB(sb);
106         pTcon = cifs_sb->tcon;
107
108         down(&sb->s_vfs_rename_sem);
109         full_path = build_path_from_dentry(direntry);
110         up(&sb->s_vfs_rename_sem);
111         if(full_path == NULL) {
112                 FreeXid(xid);
113                 return -ENOMEM;
114         }
115         /* return dos attributes as pseudo xattr */
116         /* return alt name if available as pseudo attr */
117
118         /* if proc/fs/cifs/streamstoxattr is set then
119                 search server for EAs or streams to 
120                 returns as xattrs */
121         if(value_size > MAX_EA_VALUE_SIZE) {
122                 cFYI(1,("size of EA value too large"));
123                 if(full_path)
124                         kfree(full_path);
125                 FreeXid(xid);
126                 return -EOPNOTSUPP;
127         }
128
129         if(ea_name == NULL) {
130                 cFYI(1,("Null xattr names not supported"));
131         } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5)) {
132                 cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name));
133                   /* BB what if no namespace prefix? */
134                   /* Should we just pass them to server, except for 
135                   system and perhaps security prefixes? */
136         } else {
137                 ea_name+=5; /* skip past user. prefix */
138                 rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
139                         (__u16)value_size, cifs_sb->local_nls);
140         }
141         if (full_path)
142                 kfree(full_path);
143         FreeXid(xid);
144 #endif
145         return rc;
146 }
147
148 ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
149          void * ea_value, size_t buf_size)
150 {
151         ssize_t rc = -EOPNOTSUPP;
152 #ifdef CONFIG_CIFS_XATTR
153         int xid;
154         struct cifs_sb_info *cifs_sb;
155         struct cifsTconInfo *pTcon;
156         struct super_block * sb;
157         char * full_path;
158
159         if(direntry == NULL)
160                 return -EIO;
161         if(direntry->d_inode == NULL)
162                 return -EIO;
163         sb = direntry->d_inode->i_sb;
164         if(sb == NULL)
165                 return -EIO;
166         xid = GetXid();
167
168         cifs_sb = CIFS_SB(sb);
169         pTcon = cifs_sb->tcon;
170
171         down(&sb->s_vfs_rename_sem);
172         full_path = build_path_from_dentry(direntry);
173         up(&sb->s_vfs_rename_sem);
174         if(full_path == NULL) {
175                 FreeXid(xid);
176                 return -ENOMEM;
177         }
178         /* return dos attributes as pseudo xattr */
179         /* return alt name if available as pseudo attr */
180         if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5)) {
181                 cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name));
182                 /* BB what if no namespace prefix? */
183                 /* Should we just pass them to server, except for system? */
184         } else {
185         /* We could add a check here
186             if proc/fs/cifs/streamstoxattr is set then
187                 search server for EAs or streams to 
188                 returns as xattrs */
189                 ea_name+=5; /* skip past user. */
190                 rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
191                                 buf_size, cifs_sb->local_nls);
192         }
193         if (full_path)
194                 kfree(full_path);
195         FreeXid(xid);
196 #endif
197         return rc;
198 }
199
200 ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
201 {
202         ssize_t rc = -EOPNOTSUPP;
203 #ifdef CONFIG_CIFS_XATTR
204         int xid;
205         struct cifs_sb_info *cifs_sb;
206         struct cifsTconInfo *pTcon;
207         struct super_block * sb;
208         char * full_path;
209
210         if(direntry == NULL)
211                 return -EIO;
212         if(direntry->d_inode == NULL)
213                 return -EIO;
214         sb = direntry->d_inode->i_sb;
215         if(sb == NULL)
216                 return -EIO;
217         xid = GetXid();
218
219         cifs_sb = CIFS_SB(sb);
220         pTcon = cifs_sb->tcon;
221
222         down(&sb->s_vfs_rename_sem);
223         full_path = build_path_from_dentry(direntry);
224         up(&sb->s_vfs_rename_sem);
225         if(full_path == NULL) {
226                 FreeXid(xid);
227                 return -ENOMEM;
228         }
229         /* return dos attributes as pseudo xattr */
230         /* return alt name if available as pseudo attr */
231
232         /* if proc/fs/cifs/streamstoxattr is set then
233                 search server for EAs or streams to 
234                 returns as xattrs */
235         rc = CIFSSMBQAllEAs(xid,pTcon,full_path,data,buf_size,
236                                 cifs_sb->local_nls);
237
238         if (full_path)
239                 kfree(full_path);
240         FreeXid(xid);
241 #endif
242         return rc;
243 }