Whamcloud - gitweb
LU-12678 lnet: discard LNET_MD_PHYS
[fs/lustre-release.git] / lustre / osd-zfs / osd_xattr.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  *
32  * lustre/osd-zfs/osd_xattr.c
33  * functions to manipulate extended attributes and system attributes
34  *
35  * Author: Alex Zhuravlev <bzzz@whamcloud.com>
36  * Author: Mike Pershin <tappro@whamcloud.com>
37  */
38
39 #define DEBUG_SUBSYSTEM S_OSD
40
41 #include <libcfs/libcfs.h>
42 #include <obd_support.h>
43 #include <lustre_net.h>
44 #include <obd.h>
45 #include <obd_class.h>
46 #include <lustre_disk.h>
47 #include <lustre_fid.h>
48 #include <lustre_linkea.h>
49
50 #include "osd_internal.h"
51
52 #include <sys/dnode.h>
53 #include <sys/dbuf.h>
54 #include <sys/spa.h>
55 #include <sys/stat.h>
56 #include <sys/zap.h>
57 #include <sys/spa_impl.h>
58 #include <sys/zfs_znode.h>
59 #include <sys/dmu_tx.h>
60 #include <sys/dmu_objset.h>
61 #include <sys/dsl_prop.h>
62 #include <sys/sa_impl.h>
63 #include <sys/txg.h>
64
65 #include <linux/posix_acl_xattr.h>
66 #include <lustre_scrub.h>
67
68 int __osd_xattr_load(struct osd_device *osd, sa_handle_t *hdl, nvlist_t **sa)
69 {
70         char        *buf;
71         int          rc, size;
72
73         rc = -sa_size(hdl, SA_ZPL_DXATTR(osd), &size);
74         if (rc) {
75                 if (rc == -ENOENT)
76                         rc = -nvlist_alloc(sa, NV_UNIQUE_NAME, KM_SLEEP);
77                 goto out_sa;
78         }
79
80         buf = osd_zio_buf_alloc(size);
81         if (buf == NULL) {
82                 rc = -ENOMEM;
83                 goto out_sa;
84         }
85         rc = -sa_lookup(hdl, SA_ZPL_DXATTR(osd), buf, size);
86         if (rc == 0)
87                 rc = -nvlist_unpack(buf, size, sa, KM_SLEEP);
88         osd_zio_buf_free(buf, size);
89 out_sa:
90
91         return rc;
92 }
93
94 static inline int __osd_xattr_cache(struct osd_object *obj)
95 {
96         LASSERT(obj->oo_sa_hdl);
97         if (obj->oo_sa_xattr != NULL)
98                 return 0;
99         return __osd_xattr_load(osd_obj2dev(obj),
100                                 obj->oo_sa_hdl, &obj->oo_sa_xattr);
101 }
102
103 static int
104 __osd_sa_xattr_get(const struct lu_env *env, struct osd_object *obj,
105                    const struct lu_buf *buf, const char *name, int *sizep)
106 {
107         uchar_t *nv_value;
108         int      rc = 0;
109
110         rc = __osd_xattr_cache(obj);
111         if (rc)
112                 return rc;
113
114         LASSERT(obj->oo_sa_xattr);
115         rc = -nvlist_lookup_byte_array(obj->oo_sa_xattr, name,
116                                        &nv_value, sizep);
117         if (rc)
118                 return rc;
119
120         if (buf == NULL || buf->lb_buf == NULL) {
121                 /* return the required size by *sizep */
122                 return 0;
123         }
124
125         if (*sizep > buf->lb_len)
126                 return -ERANGE; /* match ldiskfs error */
127
128         memcpy(buf->lb_buf, nv_value, *sizep);
129         return 0;
130 }
131
132 int __osd_xattr_get_large(const struct lu_env *env, struct osd_device *osd,
133                           uint64_t xattr, struct lu_buf *buf,
134                           const char *name, int *sizep)
135 {
136         dnode_t         *xa_data_dn;
137         sa_handle_t *sa_hdl = NULL;
138         uint64_t         xa_data_obj, size;
139         int              rc;
140
141         /* are there any extended attributes? */
142         if (xattr == ZFS_NO_OBJECT)
143                 return -ENOENT;
144
145         /* Lookup the object number containing the xattr data */
146         rc = -zap_lookup(osd->od_os, xattr, name, sizeof(uint64_t), 1,
147                         &xa_data_obj);
148         if (rc)
149                 return rc;
150
151         rc = __osd_obj2dnode(osd->od_os, xa_data_obj, &xa_data_dn);
152         if (rc)
153                 return rc;
154
155         rc = -sa_handle_get(osd->od_os, xa_data_obj, NULL, SA_HDL_PRIVATE,
156                         &sa_hdl);
157         if (rc)
158                 goto out_rele;
159
160         /* Get the xattr value length / object size */
161         rc = -sa_lookup(sa_hdl, SA_ZPL_SIZE(osd), &size, 8);
162         if (rc)
163                 goto out;
164
165         if (size > INT_MAX) {
166                 rc = -EOVERFLOW;
167                 goto out;
168         }
169
170         *sizep = (int)size;
171
172         if (buf == NULL || buf->lb_buf == NULL) {
173                 /* We only need to return the required size */
174                 goto out;
175         }
176         if (*sizep > buf->lb_len) {
177                 rc = -ERANGE; /* match ldiskfs error */
178                 goto out;
179         }
180
181         rc = -dmu_read(osd->od_os, xa_data_dn->dn_object, 0,
182                         size, buf->lb_buf, DMU_READ_PREFETCH);
183
184 out:
185         sa_handle_destroy(sa_hdl);
186 out_rele:
187         osd_dnode_rele(xa_data_dn);
188
189         return rc;
190 }
191
192 /**
193  * Copy an extended attribute into the buffer provided, or compute
194  * the required buffer size if \a buf is NULL.
195  *
196  * On success, the number of bytes used or required is stored in \a sizep.
197  *
198  * Note that no locking is done here.
199  *
200  * \param[in] env      execution environment
201  * \param[in] obj      object for which to retrieve xattr
202  * \param[out] buf     buffer to store xattr value in
203  * \param[in] name     name of xattr to copy
204  * \param[out] sizep   bytes used or required to store xattr
205  *
206  * \retval 0           on success
207  * \retval negative    negated errno on failure
208  */
209 int osd_xattr_get_internal(const struct lu_env *env, struct osd_object *obj,
210                            struct lu_buf *buf, const char *name, int *sizep)
211 {
212         int rc;
213
214         if (unlikely(!dt_object_exists(&obj->oo_dt) || obj->oo_destroyed))
215                 return -ENOENT;
216
217         /* check SA_ZPL_DXATTR first then fallback to directory xattr */
218         rc = __osd_sa_xattr_get(env, obj, buf, name, sizep);
219         if (rc != -ENOENT)
220                 return rc;
221
222         return __osd_xattr_get_large(env, osd_obj2dev(obj), obj->oo_xattr,
223                                      buf, name, sizep);
224 }
225
226 /**
227  * Copy LMA extended attribute into provided buffer
228  *
229  * Note that no locking is done here.
230  *
231  * \param[in] env      execution environment
232  * \param[in] obj      object for which to retrieve xattr
233  * \param[out] buf     buffer to store xattr value in
234  *
235  * \retval 0           on success
236  * \retval negative    negated errno on failure
237  */
238 int osd_xattr_get_lma(const struct lu_env *env, struct osd_object *obj,
239                       struct lu_buf *buf)
240 {
241         int size = 0;
242         int rc = -ENOENT;
243
244         if (!buf)
245                 return 0;
246
247         if (unlikely(obj->oo_destroyed))
248                 goto out_lma;
249
250         /* check SA_ZPL_DXATTR first then fallback to directory xattr */
251         rc = __osd_sa_xattr_get(env, obj, buf, XATTR_NAME_LMA, &size);
252         if (!rc && unlikely(size < sizeof(struct lustre_mdt_attrs)))
253                 rc = -EINVAL;
254         if (rc != -ENOENT)
255                 goto out_lma;
256
257         rc = __osd_xattr_get_large(env, osd_obj2dev(obj), obj->oo_xattr,
258                                      buf, XATTR_NAME_LMA, &size);
259         if (!rc && unlikely(size < sizeof(struct lustre_mdt_attrs)))
260                 rc = -EINVAL;
261
262 out_lma:
263         return rc;
264 }
265
266 static int osd_get_pfid_from_lma(const struct lu_env *env,
267                                  struct osd_object *obj,
268                                  struct lu_buf *buf, int *sizep)
269 {
270         struct osd_thread_info *info = osd_oti_get(env);
271         struct lustre_ost_attrs *loa =
272                 (struct lustre_ost_attrs *)&info->oti_buf;
273         struct lustre_mdt_attrs *lma = &loa->loa_lma;
274         struct filter_fid *ff;
275         struct ost_layout *ol;
276         struct lu_buf tbuf = {
277                 .lb_buf = loa,
278                 .lb_len = sizeof(info->oti_buf),
279         };
280         int rc;
281         ENTRY;
282
283         BUILD_BUG_ON(sizeof(info->oti_buf) < sizeof(*loa));
284         rc = osd_xattr_get_internal(env, obj, &tbuf,
285                                     XATTR_NAME_LMA, sizep);
286         if (rc)
287                 RETURN(rc);
288
289         lustre_loa_swab(loa, true);
290         LASSERT(lma->lma_compat & LMAC_STRIPE_INFO);
291
292         *sizep = sizeof(*ff);
293         if (buf->lb_len == 0 || !buf->lb_buf)
294                 RETURN(0);
295
296         if (buf->lb_len < *sizep)
297                 RETURN(-ERANGE);
298
299         ff = buf->lb_buf;
300         ol = &ff->ff_layout;
301         ol->ol_stripe_count = cpu_to_le32(loa->loa_parent_fid.f_ver >>
302                                           PFID_STRIPE_IDX_BITS);
303         ol->ol_stripe_size = cpu_to_le32(loa->loa_stripe_size);
304         loa->loa_parent_fid.f_ver &= PFID_STRIPE_COUNT_MASK;
305         fid_cpu_to_le(&ff->ff_parent, &loa->loa_parent_fid);
306         if (lma->lma_compat & LMAC_COMP_INFO) {
307                 ol->ol_comp_start = cpu_to_le64(loa->loa_comp_start);
308                 ol->ol_comp_end = cpu_to_le64(loa->loa_comp_end);
309                 ol->ol_comp_id = cpu_to_le32(loa->loa_comp_id);
310         } else {
311                 ol->ol_comp_start = 0;
312                 ol->ol_comp_end = 0;
313                 ol->ol_comp_id = 0;
314         }
315
316         RETURN(0);
317 }
318
319 int osd_xattr_get(const struct lu_env *env, struct dt_object *dt,
320                   struct lu_buf *buf, const char *name)
321 {
322         struct osd_object  *obj  = osd_dt_obj(dt);
323         int                 rc, size = 0;
324         ENTRY;
325
326         LASSERT(obj->oo_dn != NULL);
327         LASSERT(osd_invariant(obj));
328
329         if (!osd_obj2dev(obj)->od_posix_acl &&
330             (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 ||
331              strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
332                 RETURN(-EOPNOTSUPP);
333
334         down_read(&obj->oo_guard);
335         if (unlikely(!dt_object_exists(dt) || obj->oo_destroyed)) {
336                 up_read(&obj->oo_guard);
337                 RETURN(-ENOENT);
338         }
339
340         /* For the OST migrated from ldiskfs, the PFID EA may
341          * be stored in LMA because of ldiskfs inode size. */
342         if (strcmp(name, XATTR_NAME_FID) == 0 && obj->oo_pfid_in_lma)
343                 rc = osd_get_pfid_from_lma(env, obj, buf, &size);
344         else
345                 rc = osd_xattr_get_internal(env, obj, buf, name, &size);
346         up_read(&obj->oo_guard);
347
348         if (rc == -ENOENT)
349                 rc = -ENODATA;
350         else if (rc == 0)
351                 rc = size;
352         RETURN(rc);
353 }
354
355 /* the function is used to declare EAs when SA is not supported */
356 void __osd_xattr_declare_legacy(const struct lu_env *env,
357                                 struct osd_object *obj,
358                                 int vallen, const char *name,
359                                 struct osd_thandle *oh)
360 {
361         struct osd_device *osd = osd_obj2dev(obj);
362         dmu_tx_t *tx = oh->ot_tx;
363         uint64_t xa_data_obj;
364         int rc;
365
366         if (obj->oo_xattr == ZFS_NO_OBJECT) {
367                 /* xattr zap + entry */
368                 dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, TRUE, (char *) name);
369                 /* xattr value obj */
370                 dmu_tx_hold_sa_create(tx, ZFS_SA_BASE_ATTR_SIZE);
371                 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, vallen);
372                 return;
373         }
374
375         rc = -zap_lookup(osd->od_os, obj->oo_xattr, name, sizeof(uint64_t), 1,
376                         &xa_data_obj);
377         if (rc == 0) {
378                 /*
379                  * Entry already exists.
380                  * We'll truncate the existing object.
381                  */
382                 dmu_tx_hold_bonus(tx, xa_data_obj);
383                 dmu_tx_hold_free(tx, xa_data_obj, vallen, DMU_OBJECT_END);
384                 dmu_tx_hold_write(tx, xa_data_obj, 0, vallen);
385         } else if (rc == -ENOENT) {
386                 /*
387                  * Entry doesn't exist, we need to create a new one and a new
388                  * object to store the value.
389                  */
390                 dmu_tx_hold_bonus(tx, obj->oo_xattr);
391                 dmu_tx_hold_zap(tx, obj->oo_xattr, TRUE, (char *) name);
392                 dmu_tx_hold_sa_create(tx, ZFS_SA_BASE_ATTR_SIZE);
393                 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, vallen);
394         }
395 }
396
397 void __osd_xattr_declare_set(const struct lu_env *env, struct osd_object *obj,
398                              int vallen, const char *name,
399                              struct osd_thandle *oh)
400 {
401         struct osd_device *osd = osd_obj2dev(obj);
402         dmu_tx_t *tx = oh->ot_tx;
403         int bonuslen;
404
405         if (unlikely(obj->oo_destroyed))
406                 return;
407
408         if (strcmp(name, XATTR_NAME_LINK) == 0 &&
409             osd->od_remote_parent_dir != ZFS_NO_OBJECT) {
410                 /* If some name entry resides on remote MDT, then will create
411                  * agent entry under remote parent. On the other hand, if the
412                  * remote entry will be removed, then related agent entry may
413                  * need to be removed from the remote parent. So there may be
414                  * kinds of cases, let's declare enough credits. The credits
415                  * for create agent entry is enough for remove case. */
416                 osd_tx_hold_zap(tx, osd->od_remote_parent_dir,
417                                 NULL, TRUE, NULL);
418         }
419
420         if (unlikely(!osd_obj2dev(obj)->od_xattr_in_sa)) {
421                 __osd_xattr_declare_legacy(env, obj, vallen, name, oh);
422                 return;
423         }
424
425         /* declare EA in SA */
426         if (dt_object_exists(&obj->oo_dt)) {
427                 LASSERT(obj->oo_sa_hdl);
428                 /* XXX: it should be possible to skip spill
429                  * declaration if specific EA is part of
430                  * bonus and doesn't grow */
431                 dmu_tx_hold_spill(tx, obj->oo_dn->dn_object);
432                 return;
433         }
434
435         bonuslen = osd_obj_bonuslen(obj);
436
437         /* the object doesn't exist, but we've declared bonus
438          * in osd_declare_object_create() yet */
439         if (obj->oo_ea_in_bonus > bonuslen) {
440                 /* spill has been declared already */
441         } else if (obj->oo_ea_in_bonus + vallen > bonuslen) {
442                 /* we're about to exceed bonus, let's declare spill */
443                 dmu_tx_hold_spill(tx, DMU_NEW_OBJECT);
444         }
445         obj->oo_ea_in_bonus += vallen;
446 }
447
448 int osd_declare_xattr_set(const struct lu_env *env, struct dt_object *dt,
449                           const struct lu_buf *buf, const char *name,
450                           int fl, struct thandle *handle)
451 {
452         struct osd_object  *obj = osd_dt_obj(dt);
453         struct osd_thandle *oh;
454         ENTRY;
455
456         LASSERT(handle != NULL);
457         oh = container_of(handle, struct osd_thandle, ot_super);
458
459         down_read(&obj->oo_guard);
460         __osd_xattr_declare_set(env, obj, buf->lb_len, name, oh);
461         up_read(&obj->oo_guard);
462
463         RETURN(0);
464 }
465
466 int __osd_sa_attr_init(const struct lu_env *env, struct osd_object *obj,
467                        struct osd_thandle *oh)
468 {
469         sa_bulk_attr_t *bulk = osd_oti_get(env)->oti_attr_bulk;
470         struct osa_attr *osa = &osd_oti_get(env)->oti_osa;
471         struct lu_buf *lb = &osd_oti_get(env)->oti_xattr_lbuf;
472         struct osd_device *osd = osd_obj2dev(obj);
473         uint64_t gen;
474         inode_timespec_t now;
475         size_t size;
476         int rc, cnt;
477
478         obj->oo_late_xattr = 0;
479         obj->oo_late_attr_set = 0;
480
481         gen = dmu_tx_get_txg(oh->ot_tx);
482         gethrestime(&now);
483         ZFS_TIME_ENCODE(&now, osa->btime);
484
485         obj->oo_attr.la_valid |= LA_BTIME;
486         obj->oo_attr.la_btime = osa->btime[0];
487         osa->atime[0] = obj->oo_attr.la_atime;
488         osa->ctime[0] = obj->oo_attr.la_ctime;
489         osa->mtime[0] = obj->oo_attr.la_mtime;
490         osa->mode = obj->oo_attr.la_mode;
491         osa->uid = obj->oo_attr.la_uid;
492         osa->gid = obj->oo_attr.la_gid;
493         osa->rdev = obj->oo_attr.la_rdev;
494         osa->nlink = obj->oo_attr.la_nlink;
495         osa->flags = attrs_fs2zfs(obj->oo_attr.la_flags);
496         osa->size  = obj->oo_attr.la_size;
497 #ifdef ZFS_PROJINHERIT
498         if (osd->od_projectused_dn) {
499                 if (obj->oo_attr.la_valid & LA_PROJID)
500                         osa->projid = obj->oo_attr.la_projid;
501                 else
502                         osa->projid = ZFS_DEFAULT_PROJID;
503                 osa->flags |= ZFS_PROJID;
504                 obj->oo_with_projid = 1;
505         }
506 #endif
507
508         cnt = 0;
509         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MODE(osd), NULL, &osa->mode, 8);
510         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_SIZE(osd), NULL, &osa->size, 8);
511         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_GEN(osd), NULL, &gen, 8);
512         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_UID(osd), NULL, &osa->uid, 8);
513         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_GID(osd), NULL, &osa->gid, 8);
514         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_PARENT(osd), NULL,
515                          &obj->oo_parent, 8);
516         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_FLAGS(osd), NULL, &osa->flags, 8);
517         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_ATIME(osd), NULL, osa->atime, 16);
518         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(osd), NULL, osa->mtime, 16);
519         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(osd), NULL, osa->ctime, 16);
520         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CRTIME(osd), NULL, osa->btime, 16);
521         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_LINKS(osd), NULL, &osa->nlink, 8);
522 #ifdef ZFS_PROJINHERIT
523         if (osd->od_projectused_dn)
524                 SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_PROJID(osd), NULL,
525                                  &osa->projid, 8);
526 #endif
527         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_RDEV(osd), NULL, &osa->rdev, 8);
528         LASSERT(cnt <= ARRAY_SIZE(osd_oti_get(env)->oti_attr_bulk));
529
530         /* Update the SA for additions, modifications, and removals. */
531         rc = -nvlist_size(obj->oo_sa_xattr, &size, NV_ENCODE_XDR);
532         if (rc)
533                 return rc;
534
535         lu_buf_check_and_alloc(lb, size);
536         if (lb->lb_buf == NULL) {
537                 CERROR("%s: can't allocate buffer for xattr update\n",
538                                 osd->od_svname);
539                 return -ENOMEM;
540         }
541
542         rc = -nvlist_pack(obj->oo_sa_xattr, (char **)&lb->lb_buf, &size,
543                           NV_ENCODE_XDR, KM_SLEEP);
544         if (rc)
545                 return rc;
546
547         SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_DXATTR(osd), NULL, lb->lb_buf, size);
548
549         rc = -sa_replace_all_by_template(obj->oo_sa_hdl, bulk, cnt, oh->ot_tx);
550
551         return rc;
552 }
553
554 int __osd_sa_xattr_update(const struct lu_env *env, struct osd_object *obj,
555                            struct osd_thandle *oh)
556 {
557         struct lu_buf     *lb = &osd_oti_get(env)->oti_xattr_lbuf;
558         struct osd_device *osd = osd_obj2dev(obj);
559         char              *dxattr;
560         size_t             size;
561         int                rc;
562
563         obj->oo_late_xattr = 0;
564
565         /* Update the SA for additions, modifications, and removals. */
566         rc = -nvlist_size(obj->oo_sa_xattr, &size, NV_ENCODE_XDR);
567         if (rc)
568                 return rc;
569
570         lu_buf_check_and_alloc(lb, size);
571         if (lb->lb_buf == NULL) {
572                 CERROR("%s: can't allocate buffer for xattr update\n",
573                                 osd->od_svname);
574                 return -ENOMEM;
575         }
576
577         dxattr = lb->lb_buf;
578         rc = -nvlist_pack(obj->oo_sa_xattr, &dxattr, &size,
579                         NV_ENCODE_XDR, KM_SLEEP);
580         if (rc)
581                 return rc;
582         LASSERT(dxattr == lb->lb_buf);
583
584         sa_update(obj->oo_sa_hdl, SA_ZPL_DXATTR(osd), dxattr, size, oh->ot_tx);
585
586         return 0;
587 }
588
589 /*
590  * Set an extended attribute.
591  * This transaction must have called udmu_xattr_declare_set() first.
592  *
593  * Returns 0 on success or a negative error number on failure.
594  *
595  * No locking is done here.
596  */
597 int __osd_sa_xattr_schedule_update(const struct lu_env *env,
598                                    struct osd_object *obj,
599                                    struct osd_thandle *oh)
600 {
601         ENTRY;
602         LASSERT(obj->oo_sa_hdl);
603         LASSERT(obj->oo_sa_xattr);
604
605         /* schedule batched SA update in osd_object_sa_dirty_rele() */
606         obj->oo_late_xattr = 1;
607         osd_object_sa_dirty_add(obj, oh);
608
609         RETURN(0);
610
611 }
612
613 int __osd_sa_xattr_set(const struct lu_env *env, struct osd_object *obj,
614                        const struct lu_buf *buf, const char *name, int fl,
615                        struct osd_thandle *oh)
616 {
617         uchar_t *nv_value;
618         size_t  size;
619         int     nv_size;
620         int     rc;
621         int     too_big = 0;
622
623         rc = __osd_xattr_cache(obj);
624         if (rc)
625                 return rc;
626
627         LASSERT(obj->oo_sa_xattr);
628         if (buf->lb_len > OBD_MAX_EA_SIZE) {
629                 too_big = 1;
630         } else {
631                 /* Prevent the DXATTR SA from consuming the entire SA
632                  * region */
633                 rc = -nvlist_size(obj->oo_sa_xattr, &size, NV_ENCODE_XDR);
634                 if (rc)
635                         return rc;
636
637                 if (size + buf->lb_len > DXATTR_MAX_SA_SIZE)
638                         too_big = 1;
639         }
640
641         /* even in case of -EFBIG we must lookup xattr and check can we
642          * rewrite it then delete from SA */
643         rc = -nvlist_lookup_byte_array(obj->oo_sa_xattr, name, &nv_value,
644                                         &nv_size);
645         if (rc == 0) {
646                 if (fl & LU_XATTR_CREATE) {
647                         return -EEXIST;
648                 } else if (too_big) {
649                         rc = -nvlist_remove(obj->oo_sa_xattr, name,
650                                                 DATA_TYPE_BYTE_ARRAY);
651                         if (rc < 0)
652                                 return rc;
653                         rc = __osd_sa_xattr_schedule_update(env, obj, oh);
654                         return rc == 0 ? -EFBIG : rc;
655                 }
656         } else if (rc == -ENOENT) {
657                 if (fl & LU_XATTR_REPLACE)
658                         return -ENODATA;
659                 else if (too_big)
660                         return -EFBIG;
661         } else {
662                 return rc;
663         }
664
665         /* Ensure xattr doesn't exist in ZAP */
666         if (obj->oo_xattr != ZFS_NO_OBJECT) {
667                 struct osd_device *osd = osd_obj2dev(obj);
668                 uint64_t           objid;
669                 rc = -zap_lookup(osd->od_os, obj->oo_xattr,
670                                  name, 8, 1, &objid);
671                 if (rc == 0) {
672                         rc = -dmu_object_free(osd->od_os, objid, oh->ot_tx);
673                         if (rc == 0)
674                                 zap_remove(osd->od_os, obj->oo_xattr,
675                                            name, oh->ot_tx);
676                 }
677         }
678
679         rc = -nvlist_add_byte_array(obj->oo_sa_xattr, name,
680                                     (uchar_t *)buf->lb_buf, buf->lb_len);
681         if (rc)
682                 return rc;
683
684         /* batch updates only for just created dnodes where we
685          * used to set number of EAs in a single transaction */
686         if (obj->oo_dn->dn_allocated_txg == oh->ot_tx->tx_txg)
687                 rc = __osd_sa_xattr_schedule_update(env, obj, oh);
688         else
689                 rc = __osd_sa_xattr_update(env, obj, oh);
690
691         return rc;
692 }
693
694 int
695 __osd_xattr_set(const struct lu_env *env, struct osd_object *obj,
696                 const struct lu_buf *buf, const char *name, int fl,
697                 struct osd_thandle *oh)
698 {
699         struct osd_device *osd = osd_obj2dev(obj);
700         dnode_t *xa_zap_dn = NULL;
701         dnode_t *xa_data_dn = NULL;
702         uint64_t           xa_data_obj;
703         sa_handle_t       *sa_hdl = NULL;
704         dmu_tx_t          *tx = oh->ot_tx;
705         uint64_t           size;
706         int                rc;
707
708         LASSERT(obj->oo_sa_hdl);
709
710         if (obj->oo_xattr == ZFS_NO_OBJECT) {
711                 struct lu_attr *la = &osd_oti_get(env)->oti_la;
712
713                 la->la_valid = LA_MODE;
714                 la->la_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;
715                 rc = __osd_zap_create(env, osd, &xa_zap_dn, tx, la, 0, 0);
716                 if (rc)
717                         return rc;
718
719                 obj->oo_xattr = xa_zap_dn->dn_object;
720                 rc = osd_object_sa_update(obj, SA_ZPL_XATTR(osd),
721                                 &obj->oo_xattr, 8, oh);
722                 if (rc)
723                         goto out;
724         }
725
726         rc = -zap_lookup(osd->od_os, obj->oo_xattr, name, sizeof(uint64_t), 1,
727                          &xa_data_obj);
728         if (rc == 0) {
729                 if (fl & LU_XATTR_CREATE) {
730                         rc = -EEXIST;
731                         goto out;
732                 }
733                 /*
734                  * Entry already exists.
735                  * We'll truncate the existing object.
736                  */
737                 rc = __osd_obj2dnode(osd->od_os, xa_data_obj, &xa_data_dn);
738                 if (rc)
739                         goto out;
740
741                 rc = -sa_handle_get(osd->od_os, xa_data_obj, NULL,
742                                         SA_HDL_PRIVATE, &sa_hdl);
743                 if (rc)
744                         goto out;
745
746                 rc = -sa_lookup(sa_hdl, SA_ZPL_SIZE(osd), &size, 8);
747                 if (rc)
748                         goto out_sa;
749
750                 rc = -dmu_free_range(osd->od_os, xa_data_dn->dn_object,
751                                      0, DMU_OBJECT_END, tx);
752                 if (rc)
753                         goto out_sa;
754         } else if (rc == -ENOENT) {
755                 struct lu_attr *la = &osd_oti_get(env)->oti_la;
756                 /*
757                  * Entry doesn't exist, we need to create a new one and a new
758                  * object to store the value.
759                  */
760                 if (fl & LU_XATTR_REPLACE) {
761                         /* should be ENOATTR according to the
762                          * man, but that is undefined here */
763                         rc = -ENODATA;
764                         goto out;
765                 }
766
767                 la->la_valid = LA_MODE;
768                 la->la_mode = S_IFREG | S_IRUGO | S_IWUSR;
769                 rc = __osd_object_create(env, osd, obj,
770                                          lu_object_fid(&obj->oo_dt.do_lu),
771                                          &xa_data_dn, tx, la);
772                 if (rc)
773                         goto out;
774                 xa_data_obj = xa_data_dn->dn_object;
775
776                 rc = -sa_handle_get(osd->od_os, xa_data_obj, NULL,
777                                         SA_HDL_PRIVATE, &sa_hdl);
778                 if (rc)
779                         goto out;
780
781                 rc = -zap_add(osd->od_os, obj->oo_xattr, name, sizeof(uint64_t),
782                                 1, &xa_data_obj, tx);
783                 if (rc)
784                         goto out_sa;
785         } else {
786                 /* There was an error looking up the xattr name */
787                 goto out;
788         }
789
790         /* Finally write the xattr value */
791         dmu_write(osd->od_os, xa_data_obj, 0, buf->lb_len, buf->lb_buf, tx);
792
793         size = buf->lb_len;
794         rc = -sa_update(sa_hdl, SA_ZPL_SIZE(osd), &size, 8, tx);
795
796 out_sa:
797         sa_handle_destroy(sa_hdl);
798 out:
799         if (xa_data_dn != NULL)
800                 osd_dnode_rele(xa_data_dn);
801         if (xa_zap_dn != NULL)
802                 osd_dnode_rele(xa_zap_dn);
803
804         return rc;
805 }
806
807 static int osd_xattr_split_pfid(const struct lu_env *env,
808                                 struct osd_object *obj, struct osd_thandle *oh)
809 {
810         struct osd_thread_info *info = osd_oti_get(env);
811         struct lustre_ost_attrs *loa =
812                 (struct lustre_ost_attrs *)&info->oti_buf;
813         struct lustre_mdt_attrs *lma = &loa->loa_lma;
814         struct lu_buf buf = {
815                 .lb_buf = loa,
816                 .lb_len = sizeof(info->oti_buf),
817         };
818         int size;
819         int rc;
820         ENTRY;
821
822         BUILD_BUG_ON(sizeof(info->oti_buf) < sizeof(*loa));
823         rc = osd_xattr_get_internal(env, obj, &buf, XATTR_NAME_LMA, &size);
824         if (rc)
825                 RETURN(rc);
826
827         lustre_loa_swab(loa, true);
828         LASSERT(lma->lma_compat & LMAC_STRIPE_INFO);
829
830         lma->lma_compat &= ~(LMAC_STRIPE_INFO | LMAC_COMP_INFO);
831         lustre_lma_swab(lma);
832         buf.lb_buf = lma;
833         buf.lb_len = sizeof(*lma);
834         rc = osd_xattr_set_internal(env, obj, &buf, XATTR_NAME_LMA,
835                                     LU_XATTR_REPLACE, oh);
836         if (!rc)
837                 obj->oo_pfid_in_lma = 0;
838
839         RETURN(rc);
840 }
841
842 /*
843  * In DNE environment, the object (in spite of regular file or directory)
844  * and its name entry may reside on different MDTs. Under such case, we will
845  * create an agent entry on the MDT where the object resides. The agent entry
846  * references the object locally, that makes the object to be visible to the
847  * userspace when mounted as 'zfs' directly. Then the userspace tools, such
848  * as 'tar' can handle the object properly.
849  *
850  * We handle the agent entry during set linkEA that is the common interface
851  * for both regular file and directroy, can handle kinds of cases, such as
852  * create/link/unlink/rename, and so on.
853  *
854  * NOTE: we need to do that for both directory and regular file, so we can NOT
855  *       do that when ea_{insert,delete} that are directory based operations.
856  */
857 static int osd_xattr_handle_linkea(const struct lu_env *env,
858                                    struct osd_device *osd,
859                                    struct osd_object *obj,
860                                    const struct lu_buf *buf,
861                                    struct osd_thandle *oh)
862 {
863         const struct lu_fid *fid = lu_object_fid(&obj->oo_dt.do_lu);
864         struct lu_fid *tfid = &osd_oti_get(env)->oti_fid;
865         struct linkea_data ldata = { .ld_buf = (struct lu_buf *)buf };
866         struct lu_name tmpname;
867         int rc;
868         bool remote = false;
869         ENTRY;
870
871         rc = linkea_init_with_rec(&ldata);
872         if (!rc) {
873                 linkea_first_entry(&ldata);
874                 while (ldata.ld_lee != NULL && !remote) {
875                         linkea_entry_unpack(ldata.ld_lee, &ldata.ld_reclen,
876                                             &tmpname, tfid);
877                         if (osd_remote_fid(env, osd, tfid) > 0)
878                                 remote = true;
879                         else
880                                 linkea_next_entry(&ldata);
881                 }
882         } else if (rc == -ENODATA) {
883                 rc = 0;
884         } else {
885                 RETURN(rc);
886         }
887
888         if (lu_object_has_agent_entry(&obj->oo_dt.do_lu) && !remote) {
889                 rc = osd_delete_from_remote_parent(env, osd, obj, oh, false);
890                 if (rc)
891                         CERROR("%s: failed to remove agent entry for "DFID
892                                ": rc = %d\n", osd_name(osd), PFID(fid), rc);
893         } else if (!lu_object_has_agent_entry(&obj->oo_dt.do_lu) && remote) {
894                 rc = osd_add_to_remote_parent(env, osd, obj, oh);
895                 if (rc)
896                         CWARN("%s: failed to create agent entry for "DFID
897                               ": rc = %d\n", osd_name(osd), PFID(fid), rc);
898         }
899
900         RETURN(rc);
901 }
902
903 int osd_xattr_set(const struct lu_env *env, struct dt_object *dt,
904                   const struct lu_buf *buf, const char *name, int fl,
905                   struct thandle *handle)
906 {
907         struct osd_object *obj = osd_dt_obj(dt);
908         struct osd_device *osd = osd_obj2dev(obj);
909         struct osd_thandle *oh;
910         int rc = 0;
911         ENTRY;
912
913         LASSERT(handle != NULL);
914         LASSERT(osd_invariant(obj));
915
916         if (!osd_obj2dev(obj)->od_posix_acl &&
917             (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 ||
918              strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
919                 RETURN(-EOPNOTSUPP);
920
921         oh = container_of(handle, struct osd_thandle, ot_super);
922
923         down_write(&obj->oo_guard);
924         CDEBUG(D_INODE, "Setting xattr %s with size %d\n",
925                 name, (int)buf->lb_len);
926         /* For the OST migrated from ldiskfs, the PFID EA may
927          * be stored in LMA because of ldiskfs inode size. */
928         if (unlikely(strcmp(name, XATTR_NAME_FID) == 0 &&
929                      obj->oo_pfid_in_lma)) {
930                 rc = osd_xattr_split_pfid(env, obj, oh);
931                 if (!rc)
932                         fl = LU_XATTR_CREATE;
933         } else if (strcmp(name, XATTR_NAME_LINK) == 0 &&
934                    osd->od_remote_parent_dir != ZFS_NO_OBJECT) {
935                 rc = osd_xattr_handle_linkea(env, osd, obj, buf, oh);
936         }
937
938         if (!rc)
939                 rc = osd_xattr_set_internal(env, obj, buf, name, fl, oh);
940         up_write(&obj->oo_guard);
941
942         RETURN(rc);
943 }
944
945 static void
946 __osd_xattr_declare_del(const struct lu_env *env, struct osd_object *obj,
947                         const char *name, struct osd_thandle *oh)
948 {
949         struct osd_device *osd = osd_obj2dev(obj);
950         dmu_tx_t          *tx = oh->ot_tx;
951         uint64_t           xa_data_obj;
952         int                rc;
953
954         /* update SA_ZPL_DXATTR if xattr was in SA */
955         dmu_tx_hold_sa(tx, obj->oo_sa_hdl, 0);
956
957         if (obj->oo_xattr == ZFS_NO_OBJECT)
958                 return;
959
960         rc = -zap_lookup(osd->od_os, obj->oo_xattr, name, 8, 1, &xa_data_obj);
961         if (rc == 0) {
962                 /*
963                  * Entry exists.
964                  * We'll delete the existing object and ZAP entry.
965                  */
966                 dmu_tx_hold_bonus(tx, xa_data_obj);
967                 dmu_tx_hold_free(tx, xa_data_obj, 0, DMU_OBJECT_END);
968                 dmu_tx_hold_zap(tx, obj->oo_xattr, FALSE, (char *) name);
969                 return;
970         } else if (rc == -ENOENT) {
971                 /*
972                  * Entry doesn't exist, nothing to be changed.
973                  */
974                 return;
975         }
976
977         /* An error happened */
978         tx->tx_err = -rc;
979 }
980
981 int osd_declare_xattr_del(const struct lu_env *env, struct dt_object *dt,
982                           const char *name, struct thandle *handle)
983 {
984         struct osd_object  *obj = osd_dt_obj(dt);
985         struct osd_thandle *oh;
986         ENTRY;
987
988         LASSERT(handle != NULL);
989         LASSERT(osd_invariant(obj));
990
991         oh = container_of(handle, struct osd_thandle, ot_super);
992         LASSERT(oh->ot_tx != NULL);
993         LASSERT(obj->oo_dn != NULL);
994
995         down_read(&obj->oo_guard);
996         if (likely(dt_object_exists(&obj->oo_dt) && !obj->oo_destroyed))
997                 __osd_xattr_declare_del(env, obj, name, oh);
998         up_read(&obj->oo_guard);
999
1000         RETURN(0);
1001 }
1002
1003 static int __osd_sa_xattr_del(const struct lu_env *env, struct osd_object *obj,
1004                               const char *name, struct osd_thandle *oh)
1005 {
1006         int rc;
1007
1008         rc = __osd_xattr_cache(obj);
1009         if (rc)
1010                 return rc;
1011
1012         rc = -nvlist_remove(obj->oo_sa_xattr, name, DATA_TYPE_BYTE_ARRAY);
1013         if (rc)
1014                 return rc;
1015
1016         /*
1017          * only migrate delete LMV, and it needs to be done immediately, because
1018          * it's used in deleting sub stripes, and if this is delayed, later when
1019          * destroying the master object, it will delete sub stripes again.
1020          */
1021         if (!strcmp(name, XATTR_NAME_LMV))
1022                 rc = __osd_sa_xattr_update(env, obj, oh);
1023         else
1024                 rc = __osd_sa_xattr_schedule_update(env, obj, oh);
1025         return rc;
1026 }
1027
1028 static int __osd_xattr_del(const struct lu_env *env, struct osd_object *obj,
1029                            const char *name, struct osd_thandle *oh)
1030 {
1031         struct osd_device *osd = osd_obj2dev(obj);
1032         uint64_t           xa_data_obj;
1033         int                rc;
1034
1035         if (unlikely(!dt_object_exists(&obj->oo_dt) || obj->oo_destroyed))
1036                 return -ENOENT;
1037
1038         /* try remove xattr from SA at first */
1039         rc = __osd_sa_xattr_del(env, obj, name, oh);
1040         if (rc != -ENOENT)
1041                 return rc;
1042
1043         if (obj->oo_xattr == ZFS_NO_OBJECT)
1044                 return 0;
1045
1046         rc = -zap_lookup(osd->od_os, obj->oo_xattr, name, sizeof(uint64_t), 1,
1047                         &xa_data_obj);
1048         if (rc == -ENOENT) {
1049                 rc = 0;
1050         } else if (rc == 0) {
1051                 /*
1052                  * Entry exists.
1053                  * We'll delete the existing object and ZAP entry.
1054                  */
1055                 rc = -dmu_object_free(osd->od_os, xa_data_obj, oh->ot_tx);
1056                 if (rc)
1057                         return rc;
1058
1059                 rc = -zap_remove(osd->od_os, obj->oo_xattr, name, oh->ot_tx);
1060         }
1061
1062         return rc;
1063 }
1064
1065 int osd_xattr_del(const struct lu_env *env, struct dt_object *dt,
1066                   const char *name, struct thandle *handle)
1067 {
1068         struct osd_object  *obj = osd_dt_obj(dt);
1069         struct osd_thandle *oh;
1070         int                 rc;
1071         ENTRY;
1072
1073         LASSERT(handle != NULL);
1074         LASSERT(obj->oo_dn != NULL);
1075         LASSERT(osd_invariant(obj));
1076         LASSERT(dt_object_exists(dt));
1077         oh = container_of(handle, struct osd_thandle, ot_super);
1078         LASSERT(oh->ot_tx != NULL);
1079
1080         if (!osd_obj2dev(obj)->od_posix_acl &&
1081             (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 ||
1082              strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
1083                 RETURN(-EOPNOTSUPP);
1084
1085         down_write(&obj->oo_guard);
1086         /* For the OST migrated from ldiskfs, the PFID EA may
1087          * be stored in LMA because of ldiskfs inode size. */
1088         if (unlikely(strcmp(name, XATTR_NAME_FID) == 0 && obj->oo_pfid_in_lma))
1089                 rc = osd_xattr_split_pfid(env, obj, oh);
1090         else
1091                 rc = __osd_xattr_del(env, obj, name, oh);
1092         up_write(&obj->oo_guard);
1093
1094         RETURN(rc);
1095 }
1096
1097 void osd_declare_xattrs_destroy(const struct lu_env *env,
1098                                 struct osd_object *obj, struct osd_thandle *oh)
1099 {
1100         struct osd_device *osd = osd_obj2dev(obj);
1101         zap_attribute_t   *za = &osd_oti_get(env)->oti_za;
1102         uint64_t           oid = obj->oo_xattr, xid;
1103         dmu_tx_t          *tx = oh->ot_tx;
1104         zap_cursor_t      *zc;
1105         int                rc;
1106
1107         if (oid == ZFS_NO_OBJECT)
1108                 return; /* Nothing to do for SA xattrs */
1109
1110         /* Declare to free the ZAP holding xattrs */
1111         dmu_tx_hold_free(tx, oid, 0, DMU_OBJECT_END);
1112
1113         rc = osd_zap_cursor_init(&zc, osd->od_os, oid, 0);
1114         if (rc)
1115                 goto out;
1116
1117         while (zap_cursor_retrieve(zc, za) == 0) {
1118                 LASSERT(za->za_num_integers == 1);
1119                 LASSERT(za->za_integer_length == sizeof(uint64_t));
1120
1121                 rc = -zap_lookup(osd->od_os, oid, za->za_name,
1122                                  sizeof(uint64_t), 1, &xid);
1123                 if (rc) {
1124                         CERROR("%s: xattr %s lookup failed: rc = %d\n",
1125                                osd->od_svname, za->za_name, rc);
1126                         break;
1127                 }
1128                 dmu_tx_hold_free(tx, xid, 0, DMU_OBJECT_END);
1129
1130                 zap_cursor_advance(zc);
1131         }
1132
1133         osd_zap_cursor_fini(zc);
1134 out:
1135         if (rc && tx->tx_err == 0)
1136                 tx->tx_err = -rc;
1137 }
1138
1139 int osd_xattrs_destroy(const struct lu_env *env,
1140                        struct osd_object *obj, struct osd_thandle *oh)
1141 {
1142         struct osd_device *osd = osd_obj2dev(obj);
1143         dmu_tx_t          *tx = oh->ot_tx;
1144         zap_attribute_t   *za = &osd_oti_get(env)->oti_za;
1145         zap_cursor_t      *zc;
1146         uint64_t           xid;
1147         int                rc;
1148
1149         /* The transaction must have been assigned to a transaction group. */
1150         LASSERT(tx->tx_txg != 0);
1151
1152         if (obj->oo_xattr == ZFS_NO_OBJECT)
1153                 return 0; /* Nothing to do for SA xattrs */
1154
1155         /* Free the ZAP holding the xattrs */
1156         rc = osd_zap_cursor_init(&zc, osd->od_os, obj->oo_xattr, 0);
1157         if (rc)
1158                 return rc;
1159
1160         while (zap_cursor_retrieve(zc, za) == 0) {
1161                 LASSERT(za->za_num_integers == 1);
1162                 LASSERT(za->za_integer_length == sizeof(uint64_t));
1163
1164                 rc = -zap_lookup(osd->od_os, obj->oo_xattr, za->za_name,
1165                                  sizeof(uint64_t), 1, &xid);
1166                 if (rc) {
1167                         CERROR("%s: lookup xattr %s failed: rc = %d\n",
1168                                osd->od_svname, za->za_name, rc);
1169                 } else {
1170                         rc = -dmu_object_free(osd->od_os, xid, tx);
1171                         if (rc)
1172                                 CERROR("%s: free xattr %s failed: rc = %d\n",
1173                                        osd->od_svname, za->za_name, rc);
1174                 }
1175                 zap_cursor_advance(zc);
1176         }
1177         osd_zap_cursor_fini(zc);
1178
1179         rc = -dmu_object_free(osd->od_os, obj->oo_xattr, tx);
1180         if (rc)
1181                 CERROR("%s: free xattr %llu failed: rc = %d\n",
1182                        osd->od_svname, obj->oo_xattr, rc);
1183
1184         return rc;
1185 }
1186
1187 static int
1188 osd_sa_xattr_list(const struct lu_env *env, struct osd_object *obj,
1189                   const struct lu_buf *lb)
1190 {
1191         nvpair_t *nvp = NULL;
1192         int       len, counted = 0;
1193         int       rc = 0;
1194
1195         rc = __osd_xattr_cache(obj);
1196         if (rc)
1197                 return rc;
1198
1199         while ((nvp = nvlist_next_nvpair(obj->oo_sa_xattr, nvp)) != NULL) {
1200                 const char *name = nvpair_name(nvp);
1201
1202                 if (!osd_obj2dev(obj)->od_posix_acl &&
1203                     (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 ||
1204                      strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
1205                         continue;
1206
1207                 len = strlen(name);
1208                 if (lb->lb_buf != NULL) {
1209                         if (counted + len + 1 > lb->lb_len)
1210                                 return -ERANGE;
1211
1212                         memcpy(lb->lb_buf + counted, name, len + 1);
1213                 }
1214                 counted += len + 1;
1215         }
1216         return counted;
1217 }
1218
1219 int osd_xattr_list(const struct lu_env *env, struct dt_object *dt,
1220                    const struct lu_buf *lb)
1221 {
1222         struct osd_object      *obj = osd_dt_obj(dt);
1223         struct osd_device      *osd = osd_obj2dev(obj);
1224         zap_attribute_t        *za = &osd_oti_get(env)->oti_za;
1225         zap_cursor_t           *zc;
1226         int                    rc, counted;
1227         ENTRY;
1228
1229         LASSERT(obj->oo_dn != NULL);
1230         LASSERT(osd_invariant(obj));
1231         LASSERT(dt_object_exists(dt));
1232
1233         down_read(&obj->oo_guard);
1234
1235         rc = osd_sa_xattr_list(env, obj, lb);
1236         if (rc < 0)
1237                 GOTO(out, rc);
1238
1239         counted = rc;
1240
1241         /* continue with dnode xattr if any */
1242         if (obj->oo_xattr == ZFS_NO_OBJECT)
1243                 GOTO(out, rc = counted);
1244
1245         rc = osd_zap_cursor_init(&zc, osd->od_os, obj->oo_xattr, 0);
1246         if (rc)
1247                 GOTO(out, rc);
1248
1249         while ((rc = -zap_cursor_retrieve(zc, za)) == 0) {
1250                 if (!osd_obj2dev(obj)->od_posix_acl &&
1251                     (strcmp(za->za_name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 ||
1252                      strcmp(za->za_name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) {
1253                         zap_cursor_advance(zc);
1254                         continue;
1255                 }
1256
1257                 rc = strlen(za->za_name);
1258                 if (lb->lb_buf != NULL) {
1259                         if (counted + rc + 1 > lb->lb_len)
1260                                 GOTO(out_fini, rc = -ERANGE);
1261
1262                         memcpy(lb->lb_buf + counted, za->za_name, rc + 1);
1263                 }
1264                 counted += rc + 1;
1265
1266                 zap_cursor_advance(zc);
1267         }
1268         if (rc == -ENOENT) /* no more kes in the index */
1269                 rc = 0;
1270         else if (unlikely(rc < 0))
1271                 GOTO(out_fini, rc);
1272         rc = counted;
1273
1274 out_fini:
1275         osd_zap_cursor_fini(zc);
1276 out:
1277         up_read(&obj->oo_guard);
1278         RETURN(rc);
1279
1280 }