Whamcloud - gitweb
LU-932 llite: cleanup ll_inode_info to reduce inode size
[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  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #include <linux/fs.h>
38 #include <linux/sched.h>
39 #include <linux/mm.h>
40 #include <linux/smp_lock.h>
41
42 #define DEBUG_SUBSYSTEM S_LLITE
43
44 #include <obd_support.h>
45 #include <lustre_lite.h>
46 #include <lustre_dlm.h>
47 #include <lustre_ver.h>
48 #include <lustre_acl.h>
49
50 #include "llite_internal.h"
51
52 #define XATTR_USER_T            (1)
53 #define XATTR_TRUSTED_T         (2)
54 #define XATTR_SECURITY_T        (3)
55 #define XATTR_ACL_ACCESS_T      (4)
56 #define XATTR_ACL_DEFAULT_T     (5)
57 #define XATTR_LUSTRE_T          (6)
58 #define XATTR_OTHER_T           (7)
59
60 static
61 int get_xattr_type(const char *name)
62 {
63         if (!strcmp(name, POSIX_ACL_XATTR_ACCESS))
64                 return XATTR_ACL_ACCESS_T;
65
66         if (!strcmp(name, POSIX_ACL_XATTR_DEFAULT))
67                 return XATTR_ACL_DEFAULT_T;
68
69         if (!strncmp(name, XATTR_USER_PREFIX,
70                      sizeof(XATTR_USER_PREFIX) - 1))
71                 return XATTR_USER_T;
72
73         if (!strncmp(name, XATTR_TRUSTED_PREFIX,
74                      sizeof(XATTR_TRUSTED_PREFIX) - 1))
75                 return XATTR_TRUSTED_T;
76
77         if (!strncmp(name, XATTR_SECURITY_PREFIX,
78                      sizeof(XATTR_SECURITY_PREFIX) - 1))
79                 return XATTR_SECURITY_T;
80
81         if (!strncmp(name, XATTR_LUSTRE_PREFIX,
82                      sizeof(XATTR_LUSTRE_PREFIX) - 1))
83                 return XATTR_LUSTRE_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                 return -EOPNOTSUPP;
95
96         if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR))
97                 return -EOPNOTSUPP;
98         if (xattr_type == XATTR_TRUSTED_T && !cfs_capable(CFS_CAP_SYS_ADMIN))
99                 return -EPERM;
100         if (xattr_type == XATTR_OTHER_T)
101                 return -EOPNOTSUPP;
102
103         return 0;
104 }
105
106 static
107 int ll_setxattr_common(struct inode *inode, const char *name,
108                        const void *value, size_t size,
109                        int flags, __u64 valid)
110 {
111         struct ll_sb_info *sbi = ll_i2sbi(inode);
112         struct ptlrpc_request *req;
113         int xattr_type, rc;
114         struct obd_capa *oc;
115         posix_acl_xattr_header *new_value = NULL;
116         struct rmtacl_ctl_entry *rce = NULL;
117         ext_acl_xattr_header *acl = NULL;
118         const char *pv = value;
119         ENTRY;
120
121         xattr_type = get_xattr_type(name);
122         rc = xattr_type_filter(sbi, xattr_type);
123         if (rc)
124                 RETURN(rc);
125
126         /* b10667: ignore lustre special xattr for now */
127         if ((xattr_type == XATTR_TRUSTED_T && strcmp(name, "trusted.lov") == 0) ||
128             (xattr_type == XATTR_LUSTRE_T && strcmp(name, "lustre.lov") == 0))
129                 RETURN(0);
130
131         /* b15587: ignore security.capability xattr for now */
132         if ((xattr_type == XATTR_SECURITY_T &&
133             strcmp(name, "security.capability") == 0))
134                 RETURN(0);
135
136 #ifdef CONFIG_FS_POSIX_ACL
137         if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
138             (xattr_type == XATTR_ACL_ACCESS_T ||
139             xattr_type == XATTR_ACL_DEFAULT_T)) {
140                 rce = rct_search(&sbi->ll_rct, cfs_curproc_pid());
141                 if (rce == NULL ||
142                     (rce->rce_ops != RMT_LSETFACL &&
143                     rce->rce_ops != RMT_RSETFACL))
144                         RETURN(-EOPNOTSUPP);
145
146                 if (rce->rce_ops == RMT_LSETFACL) {
147                         struct eacl_entry *ee;
148
149                         ee = et_search_del(&sbi->ll_et, cfs_curproc_pid(),
150                                            ll_inode2fid(inode), xattr_type);
151                         LASSERT(ee != NULL);
152                         if (valid & OBD_MD_FLXATTR) {
153                                 acl = lustre_acl_xattr_merge2ext(
154                                                 (posix_acl_xattr_header *)value,
155                                                 size, ee->ee_acl);
156                                 if (IS_ERR(acl)) {
157                                         ee_free(ee);
158                                         RETURN(PTR_ERR(acl));
159                                 }
160                                 size =  CFS_ACL_XATTR_SIZE(\
161                                                 le32_to_cpu(acl->a_count), \
162                                                 ext_acl_xattr);
163                                 pv = (const char *)acl;
164                         }
165                         ee_free(ee);
166                 } else if (rce->rce_ops == RMT_RSETFACL) {
167                         size = lustre_posix_acl_xattr_filter(
168                                                 (posix_acl_xattr_header *)value,
169                                                 size, &new_value);
170                         if (unlikely(size < 0))
171                                 RETURN(size);
172
173                         pv = (const char *)new_value;
174                 } else
175                         RETURN(-EOPNOTSUPP);
176
177                 valid |= rce_ops2valid(rce->rce_ops);
178         }
179 #endif
180         oc = ll_mdscapa_get(inode);
181         rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
182                          valid, name, pv, size, 0, flags, ll_i2suppgid(inode),
183                          &req);
184         capa_put(oc);
185 #ifdef CONFIG_FS_POSIX_ACL
186         if (new_value != NULL)
187                 lustre_posix_acl_xattr_free(new_value, size);
188         if (acl != NULL)
189                 lustre_ext_acl_xattr_free(acl);
190 #endif
191         if (rc) {
192                 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
193                         LCONSOLE_INFO("Disabling user_xattr feature because "
194                                       "it is not supported on the server\n");
195                         sbi->ll_flags &= ~LL_SBI_USER_XATTR;
196                 }
197                 RETURN(rc);
198         }
199
200         ptlrpc_req_finished(req);
201         RETURN(0);
202 }
203
204 int ll_setxattr(struct dentry *dentry, const char *name,
205                 const void *value, size_t size, int flags)
206 {
207         struct inode *inode = dentry->d_inode;
208
209         LASSERT(inode);
210         LASSERT(name);
211
212         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
213                inode->i_ino, inode->i_generation, inode, name);
214
215         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
216
217         if ((strncmp(name, XATTR_TRUSTED_PREFIX,
218                      sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
219              strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
220             (strncmp(name, XATTR_LUSTRE_PREFIX,
221                      sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
222              strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
223                 struct lov_user_md *lump = (struct lov_user_md *)value;
224                 int rc = 0;
225
226                 /* Attributes that are saved via getxattr will always have
227                  * the stripe_offset as 0.  Instead, the MDS should be
228                  * allowed to pick the starting OST index.   b=17846 */
229                 if (lump != NULL && lump->lmm_stripe_offset == 0)
230                         lump->lmm_stripe_offset = -1;
231
232                 if (lump != NULL && S_ISREG(inode->i_mode)) {
233                         struct file f;
234                         int flags = FMODE_WRITE;
235
236                         f.f_dentry = dentry;
237                         rc = ll_lov_setstripe_ea_info(inode, &f, flags,
238                                                       lump, sizeof(*lump));
239                         /* b10667: rc always be 0 here for now */
240                         rc = 0;
241                 } else if (S_ISDIR(inode->i_mode)) {
242                         rc = ll_dir_setstripe(inode, lump, 0);
243                 }
244
245                 return rc;
246
247         } else if (strcmp(name, XATTR_NAME_LMA) == 0 ||
248                    strcmp(name, XATTR_NAME_LINK) == 0)
249                 return 0;
250
251         return ll_setxattr_common(inode, name, value, size, flags,
252                                   OBD_MD_FLXATTR);
253 }
254
255 int ll_removexattr(struct dentry *dentry, const char *name)
256 {
257         struct inode *inode = dentry->d_inode;
258
259         LASSERT(inode);
260         LASSERT(name);
261
262         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
263                inode->i_ino, inode->i_generation, inode, name);
264
265         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
266         return ll_setxattr_common(inode, name, NULL, 0, 0,
267                                   OBD_MD_FLXATTRRM);
268 }
269
270 static
271 int ll_getxattr_common(struct inode *inode, const char *name,
272                        void *buffer, size_t size, __u64 valid)
273 {
274         struct ll_sb_info *sbi = ll_i2sbi(inode);
275         struct ptlrpc_request *req = NULL;
276         struct mdt_body *body;
277         int xattr_type, rc;
278         void *xdata;
279         struct obd_capa *oc;
280         struct rmtacl_ctl_entry *rce = NULL;
281         ENTRY;
282
283         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
284                inode->i_ino, inode->i_generation, inode);
285
286         /* listxattr have slightly different behavior from of ext3:
287          * without 'user_xattr' ext3 will list all xattr names but
288          * filtered out "^user..*"; we list them all for simplicity.
289          */
290         if (!name) {
291                 xattr_type = XATTR_OTHER_T;
292                 goto do_getxattr;
293         }
294
295         xattr_type = get_xattr_type(name);
296         rc = xattr_type_filter(sbi, xattr_type);
297         if (rc)
298                 RETURN(rc);
299
300         /* b15587: ignore security.capability xattr for now */
301         if ((xattr_type == XATTR_SECURITY_T &&
302             strcmp(name, "security.capability") == 0))
303                 RETURN(-ENODATA);
304
305 #ifdef CONFIG_FS_POSIX_ACL
306         if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
307             (xattr_type == XATTR_ACL_ACCESS_T ||
308             xattr_type == XATTR_ACL_DEFAULT_T)) {
309                 rce = rct_search(&sbi->ll_rct, cfs_curproc_pid());
310                 if (rce == NULL ||
311                     (rce->rce_ops != RMT_LSETFACL &&
312                     rce->rce_ops != RMT_LGETFACL &&
313                     rce->rce_ops != RMT_RSETFACL &&
314                     rce->rce_ops != RMT_RGETFACL))
315                         RETURN(-EOPNOTSUPP);
316         }
317
318         /* posix acl is under protection of LOOKUP lock. when calling to this,
319          * we just have path resolution to the target inode, so we have great
320          * chance that cached ACL is uptodate.
321          */
322         if (xattr_type == XATTR_ACL_ACCESS_T &&
323             !(sbi->ll_flags & LL_SBI_RMT_CLIENT)) {
324                 struct ll_inode_info *lli = ll_i2info(inode);
325                 struct posix_acl *acl;
326
327                 cfs_spin_lock(&lli->lli_lock);
328                 acl = posix_acl_dup(lli->lli_posix_acl);
329                 cfs_spin_unlock(&lli->lli_lock);
330
331                 if (!acl)
332                         RETURN(-ENODATA);
333
334                 rc = posix_acl_to_xattr(acl, buffer, size);
335                 posix_acl_release(acl);
336                 RETURN(rc);
337         }
338         if (xattr_type == XATTR_ACL_DEFAULT_T && !S_ISDIR(inode->i_mode))
339                 RETURN(-ENODATA);
340 #endif
341
342 do_getxattr:
343         oc = ll_mdscapa_get(inode);
344         rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
345                          valid | (rce ? rce_ops2valid(rce->rce_ops) : 0),
346                          name, NULL, 0, size, 0, &req);
347         capa_put(oc);
348         if (rc) {
349                 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
350                         LCONSOLE_INFO("Disabling user_xattr feature because "
351                                       "it is not supported on the server\n");
352                         sbi->ll_flags &= ~LL_SBI_USER_XATTR;
353                 }
354                 RETURN(rc);
355         }
356
357         body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
358         LASSERT(body);
359
360         /* only detect the xattr size */
361         if (size == 0)
362                 GOTO(out, rc = body->eadatasize);
363
364         if (size < body->eadatasize) {
365                 CERROR("server bug: replied size %u > %u\n",
366                        body->eadatasize, (int)size);
367                 GOTO(out, rc = -ERANGE);
368         }
369
370         if (body->eadatasize == 0)
371                 GOTO(out, rc = -ENODATA);
372
373         /* do not need swab xattr data */
374         xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA,
375                                              body->eadatasize);
376         if (!xdata)
377                 GOTO(out, rc = -EFAULT);
378
379 #ifdef CONFIG_FS_POSIX_ACL
380         if (body->eadatasize >= 0 && rce && rce->rce_ops == RMT_LSETFACL) {
381                 ext_acl_xattr_header *acl;
382
383                 acl = lustre_posix_acl_xattr_2ext((posix_acl_xattr_header *)xdata,
384                                                   body->eadatasize);
385                 if (IS_ERR(acl))
386                         GOTO(out, rc = PTR_ERR(acl));
387
388                 rc = ee_add(&sbi->ll_et, cfs_curproc_pid(), ll_inode2fid(inode),
389                             xattr_type, acl);
390                 if (unlikely(rc < 0)) {
391                         lustre_ext_acl_xattr_free(acl);
392                         GOTO(out, rc);
393                 }
394         }
395 #endif
396
397         if (body->eadatasize == 0) {
398                 rc = -ENODATA;
399         } else {
400                 LASSERT(buffer);
401                 memcpy(buffer, xdata, body->eadatasize);
402                 rc = body->eadatasize;
403         }
404         EXIT;
405 out:
406         ptlrpc_req_finished(req);
407         return rc;
408 }
409
410 ssize_t ll_getxattr(struct dentry *dentry, const char *name,
411                     void *buffer, size_t size)
412 {
413         struct inode *inode = dentry->d_inode;
414
415         LASSERT(inode);
416         LASSERT(name);
417
418         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
419                inode->i_ino, inode->i_generation, inode, name);
420
421         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
422
423         if ((strncmp(name, XATTR_TRUSTED_PREFIX,
424                      sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
425              strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
426             (strncmp(name, XATTR_LUSTRE_PREFIX,
427                      sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
428              strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
429                 struct lov_user_md *lump;
430                 struct lov_mds_md *lmm = NULL;
431                 struct ptlrpc_request *request = NULL;
432                 int rc = 0, lmmsize = 0;
433
434                 if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
435                         return -ENODATA;
436
437                 if (size == 0 && S_ISDIR(inode->i_mode)) {
438                         /* XXX directory EA is fix for now, optimize to save
439                          * RPC transfer */
440                         GOTO(out, rc = sizeof(struct lov_user_md));
441                 }
442
443                 if (!ll_i2info(inode)->lli_smd) {
444                         if (S_ISDIR(inode->i_mode)) {
445                                 rc = ll_dir_getstripe(inode, &lmm,
446                                                       &lmmsize, &request);
447                         } else {
448                                 rc = -ENODATA;
449                         }
450                 } else {
451                         /* LSM is present already after lookup/getattr call.
452                          * we need to grab layout lock once it is implemented */
453                         rc = obd_packmd(ll_i2dtexp(inode), &lmm,
454                                         ll_i2info(inode)->lli_smd);
455                         lmmsize = rc;
456                 }
457
458                 if (rc < 0)
459                        GOTO(out, rc);
460
461                 if (size == 0) {
462                         /* used to call ll_get_max_mdsize() forward to get
463                          * the maximum buffer size, while some apps (such as
464                          * rsync 3.0.x) care much about the exact xattr value
465                          * size */
466                         rc = lmmsize;
467                         GOTO(out, rc);
468                 }
469
470                 if (size < lmmsize) {
471                         CERROR("server bug: replied size %d > %d for %s (%s)\n",
472                                lmmsize, (int)size, dentry->d_name.name, name);
473                         GOTO(out, rc = -ERANGE);
474                 }
475
476                 lump = (struct lov_user_md *)buffer;
477                 memcpy(lump, lmm, lmmsize);
478
479                 rc = lmmsize;
480 out:
481                 if (request)
482                         ptlrpc_req_finished(request);
483                 else if (lmm)
484                         obd_free_diskmd(ll_i2dtexp(inode), &lmm);
485                 return(rc);
486         }
487
488         return ll_getxattr_common(inode, name, buffer, size, OBD_MD_FLXATTR);
489 }
490
491 ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
492 {
493         struct inode *inode = dentry->d_inode;
494         int rc = 0, rc2 = 0;
495         struct lov_mds_md *lmm = NULL;
496         struct ptlrpc_request *request = NULL;
497         int lmmsize;
498
499         LASSERT(inode);
500
501         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
502                inode->i_ino, inode->i_generation, inode);
503
504         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LISTXATTR, 1);
505
506         rc = ll_getxattr_common(inode, NULL, buffer, size, OBD_MD_FLXATTRLS);
507         if (rc < 0)
508                 GOTO(out, rc);
509
510         if (S_ISREG(inode->i_mode)) {
511                 if (ll_i2info(inode)->lli_smd == NULL)
512                         rc2 = -1;
513         } else if (S_ISDIR(inode->i_mode)) {
514                 rc2 = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
515         }
516
517         if (rc2 < 0) {
518                 GOTO(out, rc2 = 0);
519         } else if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) {
520                 const int prefix_len = sizeof(XATTR_LUSTRE_PREFIX) - 1;
521                 const size_t name_len   = sizeof("lov") - 1;
522                 const size_t total_len  = prefix_len + name_len + 1;
523
524                 if (buffer && (rc + total_len) <= size) {
525                         buffer += rc;
526                         memcpy(buffer,XATTR_LUSTRE_PREFIX, prefix_len);
527                         memcpy(buffer+prefix_len, "lov", name_len);
528                         buffer[prefix_len + name_len] = '\0';
529                 }
530                 rc2 = total_len;
531         }
532 out:
533         ptlrpc_req_finished(request);
534         rc = rc + rc2;
535
536         return rc;
537 }