Whamcloud - gitweb
- fixes in split about using correct byte order;
[fs/lustre-release.git] / lustre / llite / xattr.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (c) 2004 - 2005 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre 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 the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include <linux/fs.h>
23 #include <linux/sched.h>
24 #include <linux/mm.h>
25 #include <linux/smp_lock.h>
26
27 #define DEBUG_SUBSYSTEM S_LLITE
28
29 #include <obd_support.h>
30 #include <lustre_lite.h>
31 #include <lustre_dlm.h>
32 #include <lustre_ver.h>
33 #include <lustre_mdc.h>
34 #include <linux/lustre_acl.h>
35
36 #if 0
37 #ifndef POSIX_ACL_XATTR_ACCESS
38 #ifndef XATTR_NAME_ACL_ACCESS
39 #define XATTR_NAME_ACL_ACCESS   "system.posix_acl_access"
40 #endif
41 #define POSIX_ACL_XATTR_ACCESS XATTR_NAME_ACL_ACCESS
42 #endif
43 #ifndef POSIX_ACL_XATTR_DEFAULT
44 #ifndef XATTR_NAME_ACL_DEFAULT
45 #define XATTR_NAME_ACL_DEFAULT  "system.posix_acl_default"
46 #endif
47 #define POSIX_ACL_XATTR_DEFAULT XATTR_NAME_ACL_DEFAULT
48 #endif
49 #endif
50
51 #include "llite_internal.h"
52
53 #define XATTR_USER_PREFIX       "user."
54 #define XATTR_TRUSTED_PREFIX    "trusted."
55 #define XATTR_SECURITY_PREFIX   "security."
56
57 #define XATTR_USER_T            (1)
58 #define XATTR_TRUSTED_T         (2)
59 #define XATTR_SECURITY_T        (3)
60 #define XATTR_ACL_ACCESS_T      (4)
61 #define XATTR_ACL_DEFAULT_T     (5)
62 #define XATTR_OTHER_T           (6)
63
64 static
65 int get_xattr_type(const char *name)
66 {
67         if (!strcmp(name, POSIX_ACL_XATTR_ACCESS))
68                 return XATTR_ACL_ACCESS_T;
69
70         if (!strcmp(name, POSIX_ACL_XATTR_DEFAULT))
71                 return XATTR_ACL_DEFAULT_T;
72
73         if (!strncmp(name, XATTR_USER_PREFIX,
74                      sizeof(XATTR_USER_PREFIX) - 1))
75                 return XATTR_USER_T;
76
77         if (!strncmp(name, XATTR_TRUSTED_PREFIX,
78                      sizeof(XATTR_TRUSTED_PREFIX) - 1))
79                 return XATTR_TRUSTED_T;
80
81         if (!strncmp(name, XATTR_SECURITY_PREFIX,
82                      sizeof(XATTR_SECURITY_PREFIX) - 1))
83                 return XATTR_SECURITY_T;
84
85         return XATTR_OTHER_T;
86 }
87
88 static
89 int xattr_type_filter(struct ll_sb_info *sbi, int xattr_type)
90 {
91         if (((xattr_type == XATTR_ACL_ACCESS_T) ||
92             (xattr_type == XATTR_ACL_DEFAULT_T)) &&
93             (!(sbi->ll_flags & LL_SBI_ACL) ||
94             (sbi->ll_flags & LL_SBI_RMT_CLIENT)))
95                 return -EOPNOTSUPP;
96
97         if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR))
98                 return -EOPNOTSUPP;
99         if (xattr_type == XATTR_TRUSTED_T && !capable(CAP_SYS_ADMIN))
100                 return -EPERM;
101         if (xattr_type == XATTR_OTHER_T)
102                 return -EOPNOTSUPP;
103
104         return 0;
105 }
106
107 static
108 int ll_setxattr_common(struct inode *inode, const char *name,
109                        const void *value, size_t size,
110                        int flags, __u64 valid)
111 {
112         struct ll_sb_info *sbi = ll_i2sbi(inode);
113         struct ptlrpc_request *req;
114         int xattr_type, rc;
115         struct obd_capa *oc;
116         ENTRY;
117
118         lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_SETXATTR);
119
120         xattr_type = get_xattr_type(name);
121         rc = xattr_type_filter(sbi, xattr_type);
122         if (rc)
123                 RETURN(rc);
124
125         /* b10667: ignore lustre special xattr for now */
126         if (xattr_type == XATTR_TRUSTED_T && strcmp(name, "trusted.lov") == 0)
127                 RETURN(0);
128
129         oc = ll_mdscapa_get(inode);
130         rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, valid, name,
131                          value, size, 0, flags, &req);
132         capa_put(oc);
133         if (rc) {
134                 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
135                         LCONSOLE_INFO("Disabling user_xattr feature because "
136                                       "it is not supported on the server\n"); 
137                         sbi->ll_flags &= ~LL_SBI_USER_XATTR;
138                 }
139                 RETURN(rc);
140         }
141
142         ptlrpc_req_finished(req);
143         RETURN(0);
144 }
145
146 int ll_setxattr(struct dentry *dentry, const char *name,
147                 const void *value, size_t size, int flags)
148 {
149         struct inode *inode = dentry->d_inode;
150
151         LASSERT(inode);
152         LASSERT(name);
153
154         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
155                inode->i_ino, inode->i_generation, inode, name);
156
157         return ll_setxattr_common(inode, name, value, size, flags,
158                                   OBD_MD_FLXATTR);
159 }
160
161 int ll_removexattr(struct dentry *dentry, const char *name)
162 {
163         struct inode *inode = dentry->d_inode;
164
165         LASSERT(inode);
166         LASSERT(name);
167
168         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
169                inode->i_ino, inode->i_generation, inode, name);
170
171         return ll_setxattr_common(inode, name, NULL, 0, 0,
172                                   OBD_MD_FLXATTRRM);
173 }
174
175 static
176 int ll_getxattr_common(struct inode *inode, const char *name,
177                        void *buffer, size_t size, __u64 valid)
178 {
179         struct ll_sb_info *sbi = ll_i2sbi(inode);
180         struct ptlrpc_request *req = NULL;
181         struct mdt_body *body;
182         int xattr_type, rc;
183         void *xdata;
184         struct obd_capa *oc;
185         ENTRY;
186
187         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
188                inode->i_ino, inode->i_generation, inode);
189
190         lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_GETXATTR);
191
192         /* listxattr have slightly different behavior from of ext3:
193          * without 'user_xattr' ext3 will list all xattr names but
194          * filtered out "^user..*"; we list them all for simplicity.
195          */
196         if (!name) {
197                 xattr_type = XATTR_OTHER_T;
198                 goto do_getxattr;
199         }
200
201         xattr_type = get_xattr_type(name);
202         rc = xattr_type_filter(sbi, xattr_type);
203         if (rc)
204                 RETURN(rc);
205
206         /* posix acl is under protection of LOOKUP lock. when calling to this,
207          * we just have path resolution to the target inode, so we have great
208          * chance that cached ACL is uptodate.
209          */
210 #ifdef CONFIG_FS_POSIX_ACL
211         if (xattr_type == XATTR_ACL_ACCESS_T) {
212                 struct ll_inode_info *lli = ll_i2info(inode);
213                 struct posix_acl *acl;
214
215                 spin_lock(&lli->lli_lock);
216                 acl = posix_acl_dup(lli->lli_posix_acl);
217                 spin_unlock(&lli->lli_lock);
218
219                 if (!acl)
220                         RETURN(-ENODATA);
221
222                 rc = posix_acl_to_xattr(acl, buffer, size);
223                 posix_acl_release(acl);
224                 RETURN(rc);
225         }
226 #endif
227
228 do_getxattr:
229         oc = ll_mdscapa_get(inode);
230         rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, valid, name,
231                          NULL, 0, size, 0, &req);
232         capa_put(oc);
233         if (rc) {
234                 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
235                         LCONSOLE_INFO("Disabling user_xattr feature because "
236                                       "it is not supported on the server\n"); 
237                         sbi->ll_flags &= ~LL_SBI_USER_XATTR;
238                 }
239                 RETURN(rc);
240         }
241
242         body = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*body));
243         LASSERT(body);
244         LASSERT_REPSWABBED(req, REPLY_REC_OFF);
245
246         /* only detect the xattr size */
247         if (size == 0)
248                 GOTO(out, rc = body->eadatasize);
249
250         if (size < body->eadatasize) {
251                 CERROR("server bug: replied size %u > %u\n",
252                        body->eadatasize, (int)size);
253                 GOTO(out, rc = -ERANGE);
254         }
255
256         if (lustre_msg_bufcount(req->rq_repmsg) < 3) {
257                 CERROR("reply bufcount %u\n",
258                        lustre_msg_bufcount(req->rq_repmsg));
259                 GOTO(out, rc = -EFAULT);
260         }
261
262         /* do not need swab xattr data */
263         LASSERT_REPSWAB(req, REPLY_REC_OFF + 1);
264         xdata = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF + 1,
265                                body->eadatasize);
266         if (!xdata) {
267                 CERROR("can't extract: %u : %u\n", body->eadatasize,
268                        lustre_msg_buflen(req->rq_repmsg, REPLY_REC_OFF + 1));
269                 GOTO(out, rc = -EFAULT);
270         }
271
272         LASSERT(buffer);
273         memcpy(buffer, xdata, body->eadatasize);
274         rc = body->eadatasize;
275 out:
276         ptlrpc_req_finished(req);
277         RETURN(rc);
278 }
279
280 ssize_t ll_getxattr(struct dentry *dentry, const char *name,
281                     void *buffer, size_t size)
282 {
283         struct inode *inode = dentry->d_inode;
284
285         LASSERT(inode);
286         LASSERT(name);
287
288         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
289                inode->i_ino, inode->i_generation, inode, name);
290
291         return ll_getxattr_common(inode, name, buffer, size, OBD_MD_FLXATTR);
292 }
293
294 ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
295 {
296         struct inode *inode = dentry->d_inode;
297
298         LASSERT(inode);
299
300         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
301                inode->i_ino, inode->i_generation, inode);
302
303         return ll_getxattr_common(inode, NULL, buffer, size, OBD_MD_FLXATTRLS);
304 }
305