aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_attr_leaf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_attr_leaf.c')
-rw-r--r--fs/xfs/xfs_attr_leaf.c351
1 files changed, 155 insertions, 196 deletions
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 9455051f0120..9719bbef122c 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -89,9 +89,46 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
89 int dst_start, int move_count, 89 int dst_start, int move_count,
90 xfs_mount_t *mp); 90 xfs_mount_t *mp);
91STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); 91STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
92STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context, 92
93 attrnames_t *, char *name, int namelen, 93/*========================================================================
94 int valuelen); 94 * Namespace helper routines
95 *========================================================================*/
96
97STATIC inline attrnames_t *
98xfs_attr_flags_namesp(int flags)
99{
100 return ((flags & XFS_ATTR_SECURE) ? &attr_secure:
101 ((flags & XFS_ATTR_ROOT) ? &attr_trusted : &attr_user));
102}
103
104/*
105 * If namespace bits don't match return 0.
106 * If all match then return 1.
107 */
108STATIC inline int
109xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
110{
111 return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
112}
113
114/*
115 * If namespace bits don't match and we don't have an override for it
116 * then return 0.
117 * If all match or are overridable then return 1.
118 */
119STATIC inline int
120xfs_attr_namesp_match_overrides(int arg_flags, int ondisk_flags)
121{
122 if (((arg_flags & ATTR_SECURE) == 0) !=
123 ((ondisk_flags & XFS_ATTR_SECURE) == 0) &&
124 !(arg_flags & ATTR_KERNORMALS))
125 return 0;
126 if (((arg_flags & ATTR_ROOT) == 0) !=
127 ((ondisk_flags & XFS_ATTR_ROOT) == 0) &&
128 !(arg_flags & ATTR_KERNROOTLS))
129 return 0;
130 return 1;
131}
95 132
96 133
97/*======================================================================== 134/*========================================================================
@@ -228,11 +265,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
228 continue; 265 continue;
229 if (memcmp(args->name, sfe->nameval, args->namelen) != 0) 266 if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
230 continue; 267 continue;
231 if (((args->flags & ATTR_SECURE) != 0) != 268 if (!xfs_attr_namesp_match(args->flags, sfe->flags))
232 ((sfe->flags & XFS_ATTR_SECURE) != 0))
233 continue;
234 if (((args->flags & ATTR_ROOT) != 0) !=
235 ((sfe->flags & XFS_ATTR_ROOT) != 0))
236 continue; 269 continue;
237 ASSERT(0); 270 ASSERT(0);
238#endif 271#endif
@@ -246,8 +279,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
246 279
247 sfe->namelen = args->namelen; 280 sfe->namelen = args->namelen;
248 sfe->valuelen = args->valuelen; 281 sfe->valuelen = args->valuelen;
249 sfe->flags = (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE : 282 sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
250 ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
251 memcpy(sfe->nameval, args->name, args->namelen); 283 memcpy(sfe->nameval, args->name, args->namelen);
252 memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); 284 memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
253 sf->hdr.count++; 285 sf->hdr.count++;
@@ -282,11 +314,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
282 continue; 314 continue;
283 if (memcmp(sfe->nameval, args->name, args->namelen) != 0) 315 if (memcmp(sfe->nameval, args->name, args->namelen) != 0)
284 continue; 316 continue;
285 if (((args->flags & ATTR_SECURE) != 0) != 317 if (!xfs_attr_namesp_match(args->flags, sfe->flags))
286 ((sfe->flags & XFS_ATTR_SECURE) != 0))
287 continue;
288 if (((args->flags & ATTR_ROOT) != 0) !=
289 ((sfe->flags & XFS_ATTR_ROOT) != 0))
290 continue; 318 continue;
291 break; 319 break;
292 } 320 }
@@ -363,11 +391,7 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
363 continue; 391 continue;
364 if (memcmp(args->name, sfe->nameval, args->namelen) != 0) 392 if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
365 continue; 393 continue;
366 if (((args->flags & ATTR_SECURE) != 0) != 394 if (!xfs_attr_namesp_match(args->flags, sfe->flags))
367 ((sfe->flags & XFS_ATTR_SECURE) != 0))
368 continue;
369 if (((args->flags & ATTR_ROOT) != 0) !=
370 ((sfe->flags & XFS_ATTR_ROOT) != 0))
371 continue; 395 continue;
372 return(XFS_ERROR(EEXIST)); 396 return(XFS_ERROR(EEXIST));
373 } 397 }
@@ -394,11 +418,7 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args)
394 continue; 418 continue;
395 if (memcmp(args->name, sfe->nameval, args->namelen) != 0) 419 if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
396 continue; 420 continue;
397 if (((args->flags & ATTR_SECURE) != 0) != 421 if (!xfs_attr_namesp_match(args->flags, sfe->flags))
398 ((sfe->flags & XFS_ATTR_SECURE) != 0))
399 continue;
400 if (((args->flags & ATTR_ROOT) != 0) !=
401 ((sfe->flags & XFS_ATTR_ROOT) != 0))
402 continue; 422 continue;
403 if (args->flags & ATTR_KERNOVAL) { 423 if (args->flags & ATTR_KERNOVAL) {
404 args->valuelen = sfe->valuelen; 424 args->valuelen = sfe->valuelen;
@@ -485,8 +505,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
485 nargs.valuelen = sfe->valuelen; 505 nargs.valuelen = sfe->valuelen;
486 nargs.hashval = xfs_da_hashname((char *)sfe->nameval, 506 nargs.hashval = xfs_da_hashname((char *)sfe->nameval,
487 sfe->namelen); 507 sfe->namelen);
488 nargs.flags = (sfe->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : 508 nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags);
489 ((sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
490 error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */ 509 error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */
491 ASSERT(error == ENOATTR); 510 ASSERT(error == ENOATTR);
492 error = xfs_attr_leaf_add(bp, &nargs); 511 error = xfs_attr_leaf_add(bp, &nargs);
@@ -520,6 +539,10 @@ xfs_attr_shortform_compare(const void *a, const void *b)
520 } 539 }
521} 540}
522 541
542
543#define XFS_ISRESET_CURSOR(cursor) \
544 (!((cursor)->initted) && !((cursor)->hashval) && \
545 !((cursor)->blkno) && !((cursor)->offset))
523/* 546/*
524 * Copy out entries of shortform attribute lists for attr_list(). 547 * Copy out entries of shortform attribute lists for attr_list().
525 * Shortform attribute lists are not stored in hashval sorted order. 548 * Shortform attribute lists are not stored in hashval sorted order.
@@ -537,6 +560,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
537 xfs_attr_sf_entry_t *sfe; 560 xfs_attr_sf_entry_t *sfe;
538 xfs_inode_t *dp; 561 xfs_inode_t *dp;
539 int sbsize, nsbuf, count, i; 562 int sbsize, nsbuf, count, i;
563 int error;
540 564
541 ASSERT(context != NULL); 565 ASSERT(context != NULL);
542 dp = context->dp; 566 dp = context->dp;
@@ -552,46 +576,51 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
552 xfs_attr_trace_l_c("sf start", context); 576 xfs_attr_trace_l_c("sf start", context);
553 577
554 /* 578 /*
555 * If the buffer is large enough, do not bother with sorting. 579 * If the buffer is large enough and the cursor is at the start,
580 * do not bother with sorting since we will return everything in
581 * one buffer and another call using the cursor won't need to be
582 * made.
556 * Note the generous fudge factor of 16 overhead bytes per entry. 583 * Note the generous fudge factor of 16 overhead bytes per entry.
584 * If bufsize is zero then put_listent must be a search function
585 * and can just scan through what we have.
557 */ 586 */
558 if ((dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize) { 587 if (context->bufsize == 0 ||
588 (XFS_ISRESET_CURSOR(cursor) &&
589 (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
559 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { 590 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
560 attrnames_t *namesp; 591 attrnames_t *namesp;
561 592
562 if (((context->flags & ATTR_SECURE) != 0) != 593 if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
563 ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
564 !(context->flags & ATTR_KERNORMALS)) {
565 sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
566 continue;
567 }
568 if (((context->flags & ATTR_ROOT) != 0) !=
569 ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
570 !(context->flags & ATTR_KERNROOTLS)) {
571 sfe = XFS_ATTR_SF_NEXTENTRY(sfe); 594 sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
572 continue; 595 continue;
573 } 596 }
574 namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure: 597 namesp = xfs_attr_flags_namesp(sfe->flags);
575 ((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : 598 error = context->put_listent(context,
576 &attr_user); 599 namesp,
577 if (context->flags & ATTR_KERNOVAL) { 600 (char *)sfe->nameval,
578 ASSERT(context->flags & ATTR_KERNAMELS); 601 (int)sfe->namelen,
579 context->count += namesp->attr_namelen + 602 (int)sfe->valuelen,
580 sfe->namelen + 1; 603 (char*)&sfe->nameval[sfe->namelen]);
581 } 604
582 else { 605 /*
583 if (xfs_attr_put_listent(context, namesp, 606 * Either search callback finished early or
584 (char *)sfe->nameval, 607 * didn't fit it all in the buffer after all.
585 (int)sfe->namelen, 608 */
586 (int)sfe->valuelen)) 609 if (context->seen_enough)
587 break; 610 break;
588 } 611
612 if (error)
613 return error;
589 sfe = XFS_ATTR_SF_NEXTENTRY(sfe); 614 sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
590 } 615 }
591 xfs_attr_trace_l_c("sf big-gulp", context); 616 xfs_attr_trace_l_c("sf big-gulp", context);
592 return(0); 617 return(0);
593 } 618 }
594 619
620 /* do no more for a search callback */
621 if (context->bufsize == 0)
622 return 0;
623
595 /* 624 /*
596 * It didn't all fit, so we have to sort everything on hashval. 625 * It didn't all fit, so we have to sort everything on hashval.
597 */ 626 */
@@ -614,15 +643,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
614 kmem_free(sbuf, sbsize); 643 kmem_free(sbuf, sbsize);
615 return XFS_ERROR(EFSCORRUPTED); 644 return XFS_ERROR(EFSCORRUPTED);
616 } 645 }
617 if (((context->flags & ATTR_SECURE) != 0) != 646 if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
618 ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
619 !(context->flags & ATTR_KERNORMALS)) {
620 sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
621 continue;
622 }
623 if (((context->flags & ATTR_ROOT) != 0) !=
624 ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
625 !(context->flags & ATTR_KERNROOTLS)) {
626 sfe = XFS_ATTR_SF_NEXTENTRY(sfe); 647 sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
627 continue; 648 continue;
628 } 649 }
@@ -671,24 +692,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
671 for ( ; i < nsbuf; i++, sbp++) { 692 for ( ; i < nsbuf; i++, sbp++) {
672 attrnames_t *namesp; 693 attrnames_t *namesp;
673 694
674 namesp = (sbp->flags & XFS_ATTR_SECURE) ? &attr_secure : 695 namesp = xfs_attr_flags_namesp(sbp->flags);
675 ((sbp->flags & XFS_ATTR_ROOT) ? &attr_trusted :
676 &attr_user);
677 696
678 if (cursor->hashval != sbp->hash) { 697 if (cursor->hashval != sbp->hash) {
679 cursor->hashval = sbp->hash; 698 cursor->hashval = sbp->hash;
680 cursor->offset = 0; 699 cursor->offset = 0;
681 } 700 }
682 if (context->flags & ATTR_KERNOVAL) { 701 error = context->put_listent(context,
683 ASSERT(context->flags & ATTR_KERNAMELS); 702 namesp,
684 context->count += namesp->attr_namelen + 703 sbp->name,
685 sbp->namelen + 1; 704 sbp->namelen,
686 } else { 705 sbp->valuelen,
687 if (xfs_attr_put_listent(context, namesp, 706 &sbp->name[sbp->namelen]);
688 sbp->name, sbp->namelen, 707 if (error)
689 sbp->valuelen)) 708 return error;
690 break; 709 if (context->seen_enough)
691 } 710 break;
692 cursor->offset++; 711 cursor->offset++;
693 } 712 }
694 713
@@ -810,8 +829,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
810 nargs.value = (char *)&name_loc->nameval[nargs.namelen]; 829 nargs.value = (char *)&name_loc->nameval[nargs.namelen];
811 nargs.valuelen = be16_to_cpu(name_loc->valuelen); 830 nargs.valuelen = be16_to_cpu(name_loc->valuelen);
812 nargs.hashval = be32_to_cpu(entry->hashval); 831 nargs.hashval = be32_to_cpu(entry->hashval);
813 nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : 832 nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags);
814 ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
815 xfs_attr_shortform_add(&nargs, forkoff); 833 xfs_attr_shortform_add(&nargs, forkoff);
816 } 834 }
817 error = 0; 835 error = 0;
@@ -1098,8 +1116,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
1098 be16_to_cpu(map->size)); 1116 be16_to_cpu(map->size));
1099 entry->hashval = cpu_to_be32(args->hashval); 1117 entry->hashval = cpu_to_be32(args->hashval);
1100 entry->flags = tmp ? XFS_ATTR_LOCAL : 0; 1118 entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
1101 entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE : 1119 entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
1102 ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
1103 if (args->rename) { 1120 if (args->rename) {
1104 entry->flags |= XFS_ATTR_INCOMPLETE; 1121 entry->flags |= XFS_ATTR_INCOMPLETE;
1105 if ((args->blkno2 == args->blkno) && 1122 if ((args->blkno2 == args->blkno) &&
@@ -1926,7 +1943,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
1926 else 1943 else
1927 break; 1944 break;
1928 } 1945 }
1929 ASSERT((probe >= 0) && 1946 ASSERT((probe >= 0) &&
1930 (!leaf->hdr.count 1947 (!leaf->hdr.count
1931 || (probe < be16_to_cpu(leaf->hdr.count)))); 1948 || (probe < be16_to_cpu(leaf->hdr.count))));
1932 ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval)); 1949 ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval));
@@ -1971,14 +1988,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
1971 name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe); 1988 name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe);
1972 if (name_loc->namelen != args->namelen) 1989 if (name_loc->namelen != args->namelen)
1973 continue; 1990 continue;
1974 if (memcmp(args->name, (char *)name_loc->nameval, 1991 if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0)
1975 args->namelen) != 0)
1976 continue; 1992 continue;
1977 if (((args->flags & ATTR_SECURE) != 0) != 1993 if (!xfs_attr_namesp_match(args->flags, entry->flags))
1978 ((entry->flags & XFS_ATTR_SECURE) != 0))
1979 continue;
1980 if (((args->flags & ATTR_ROOT) != 0) !=
1981 ((entry->flags & XFS_ATTR_ROOT) != 0))
1982 continue; 1994 continue;
1983 args->index = probe; 1995 args->index = probe;
1984 return(XFS_ERROR(EEXIST)); 1996 return(XFS_ERROR(EEXIST));
@@ -1989,11 +2001,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
1989 if (memcmp(args->name, (char *)name_rmt->name, 2001 if (memcmp(args->name, (char *)name_rmt->name,
1990 args->namelen) != 0) 2002 args->namelen) != 0)
1991 continue; 2003 continue;
1992 if (((args->flags & ATTR_SECURE) != 0) != 2004 if (!xfs_attr_namesp_match(args->flags, entry->flags))
1993 ((entry->flags & XFS_ATTR_SECURE) != 0))
1994 continue;
1995 if (((args->flags & ATTR_ROOT) != 0) !=
1996 ((entry->flags & XFS_ATTR_ROOT) != 0))
1997 continue; 2005 continue;
1998 args->index = probe; 2006 args->index = probe;
1999 args->rmtblkno = be32_to_cpu(name_rmt->valueblk); 2007 args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
@@ -2312,8 +2320,6 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
2312 attrlist_cursor_kern_t *cursor; 2320 attrlist_cursor_kern_t *cursor;
2313 xfs_attr_leafblock_t *leaf; 2321 xfs_attr_leafblock_t *leaf;
2314 xfs_attr_leaf_entry_t *entry; 2322 xfs_attr_leaf_entry_t *entry;
2315 xfs_attr_leaf_name_local_t *name_loc;
2316 xfs_attr_leaf_name_remote_t *name_rmt;
2317 int retval, i; 2323 int retval, i;
2318 2324
2319 ASSERT(bp != NULL); 2325 ASSERT(bp != NULL);
@@ -2355,9 +2361,8 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
2355 * We have found our place, start copying out the new attributes. 2361 * We have found our place, start copying out the new attributes.
2356 */ 2362 */
2357 retval = 0; 2363 retval = 0;
2358 for ( ; (i < be16_to_cpu(leaf->hdr.count)) 2364 for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) {
2359 && (retval == 0); entry++, i++) { 2365 attrnames_t *namesp;
2360 attrnames_t *namesp;
2361 2366
2362 if (be32_to_cpu(entry->hashval) != cursor->hashval) { 2367 if (be32_to_cpu(entry->hashval) != cursor->hashval) {
2363 cursor->hashval = be32_to_cpu(entry->hashval); 2368 cursor->hashval = be32_to_cpu(entry->hashval);
@@ -2366,115 +2371,69 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
2366 2371
2367 if (entry->flags & XFS_ATTR_INCOMPLETE) 2372 if (entry->flags & XFS_ATTR_INCOMPLETE)
2368 continue; /* skip incomplete entries */ 2373 continue; /* skip incomplete entries */
2369 if (((context->flags & ATTR_SECURE) != 0) != 2374 if (!xfs_attr_namesp_match_overrides(context->flags, entry->flags))
2370 ((entry->flags & XFS_ATTR_SECURE) != 0) && 2375 continue;
2371 !(context->flags & ATTR_KERNORMALS)) 2376
2372 continue; /* skip non-matching entries */ 2377 namesp = xfs_attr_flags_namesp(entry->flags);
2373 if (((context->flags & ATTR_ROOT) != 0) !=
2374 ((entry->flags & XFS_ATTR_ROOT) != 0) &&
2375 !(context->flags & ATTR_KERNROOTLS))
2376 continue; /* skip non-matching entries */
2377
2378 namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure :
2379 ((entry->flags & XFS_ATTR_ROOT) ? &attr_trusted :
2380 &attr_user);
2381 2378
2382 if (entry->flags & XFS_ATTR_LOCAL) { 2379 if (entry->flags & XFS_ATTR_LOCAL) {
2383 name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); 2380 xfs_attr_leaf_name_local_t *name_loc =
2384 if (context->flags & ATTR_KERNOVAL) { 2381 XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
2385 ASSERT(context->flags & ATTR_KERNAMELS); 2382
2386 context->count += namesp->attr_namelen + 2383 retval = context->put_listent(context,
2387 (int)name_loc->namelen + 1; 2384 namesp,
2388 } else { 2385 (char *)name_loc->nameval,
2389 retval = xfs_attr_put_listent(context, namesp, 2386 (int)name_loc->namelen,
2390 (char *)name_loc->nameval, 2387 be16_to_cpu(name_loc->valuelen),
2391 (int)name_loc->namelen, 2388 (char *)&name_loc->nameval[name_loc->namelen]);
2392 be16_to_cpu(name_loc->valuelen)); 2389 if (retval)
2393 } 2390 return retval;
2394 } else { 2391 } else {
2395 name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); 2392 xfs_attr_leaf_name_remote_t *name_rmt =
2396 if (context->flags & ATTR_KERNOVAL) { 2393 XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
2397 ASSERT(context->flags & ATTR_KERNAMELS); 2394
2398 context->count += namesp->attr_namelen + 2395 int valuelen = be32_to_cpu(name_rmt->valuelen);
2399 (int)name_rmt->namelen + 1; 2396
2400 } else { 2397 if (context->put_value) {
2401 retval = xfs_attr_put_listent(context, namesp, 2398 xfs_da_args_t args;
2402 (char *)name_rmt->name, 2399
2403 (int)name_rmt->namelen, 2400 memset((char *)&args, 0, sizeof(args));
2404 be32_to_cpu(name_rmt->valuelen)); 2401 args.dp = context->dp;
2402 args.whichfork = XFS_ATTR_FORK;
2403 args.valuelen = valuelen;
2404 args.value = kmem_alloc(valuelen, KM_SLEEP);
2405 args.rmtblkno = be32_to_cpu(name_rmt->valueblk);
2406 args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen);
2407 retval = xfs_attr_rmtval_get(&args);
2408 if (retval)
2409 return retval;
2410 retval = context->put_listent(context,
2411 namesp,
2412 (char *)name_rmt->name,
2413 (int)name_rmt->namelen,
2414 valuelen,
2415 (char*)args.value);
2416 kmem_free(args.value, valuelen);
2405 } 2417 }
2418 else {
2419 retval = context->put_listent(context,
2420 namesp,
2421 (char *)name_rmt->name,
2422 (int)name_rmt->namelen,
2423 valuelen,
2424 NULL);
2425 }
2426 if (retval)
2427 return retval;
2406 } 2428 }
2407 if (retval == 0) { 2429 if (context->seen_enough)
2408 cursor->offset++; 2430 break;
2409 } 2431 cursor->offset++;
2410 } 2432 }
2411 xfs_attr_trace_l_cl("blk end", context, leaf); 2433 xfs_attr_trace_l_cl("blk end", context, leaf);
2412 return(retval); 2434 return(retval);
2413} 2435}
2414 2436
2415#define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \
2416 (((struct attrlist_ent *) 0)->a_name - (char *) 0)
2417#define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \
2418 ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
2419 & ~(sizeof(u_int32_t)-1))
2420
2421/*
2422 * Format an attribute and copy it out to the user's buffer.
2423 * Take care to check values and protect against them changing later,
2424 * we may be reading them directly out of a user buffer.
2425 */
2426/*ARGSUSED*/
2427STATIC int
2428xfs_attr_put_listent(xfs_attr_list_context_t *context,
2429 attrnames_t *namesp, char *name, int namelen, int valuelen)
2430{
2431 attrlist_ent_t *aep;
2432 int arraytop;
2433
2434 ASSERT(!(context->flags & ATTR_KERNOVAL));
2435 if (context->flags & ATTR_KERNAMELS) {
2436 char *offset;
2437
2438 ASSERT(context->count >= 0);
2439
2440 arraytop = context->count + namesp->attr_namelen + namelen + 1;
2441 if (arraytop > context->firstu) {
2442 context->count = -1; /* insufficient space */
2443 return(1);
2444 }
2445 offset = (char *)context->alist + context->count;
2446 strncpy(offset, namesp->attr_name, namesp->attr_namelen);
2447 offset += namesp->attr_namelen;
2448 strncpy(offset, name, namelen); /* real name */
2449 offset += namelen;
2450 *offset = '\0';
2451 context->count += namesp->attr_namelen + namelen + 1;
2452 return(0);
2453 }
2454
2455 ASSERT(context->count >= 0);
2456 ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
2457 ASSERT(context->firstu >= sizeof(*context->alist));
2458 ASSERT(context->firstu <= context->bufsize);
2459
2460 arraytop = sizeof(*context->alist) +
2461 context->count * sizeof(context->alist->al_offset[0]);
2462 context->firstu -= ATTR_ENTSIZE(namelen);
2463 if (context->firstu < arraytop) {
2464 xfs_attr_trace_l_c("buffer full", context);
2465 context->alist->al_more = 1;
2466 return(1);
2467 }
2468
2469 aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]);
2470 aep->a_valuelen = valuelen;
2471 memcpy(aep->a_name, name, namelen);
2472 aep->a_name[ namelen ] = 0;
2473 context->alist->al_offset[ context->count++ ] = context->firstu;
2474 context->alist->al_count = context->count;
2475 xfs_attr_trace_l_c("add", context);
2476 return(0);
2477}
2478 2437
2479/*======================================================================== 2438/*========================================================================
2480 * Manage the INCOMPLETE flag in a leaf entry 2439 * Manage the INCOMPLETE flag in a leaf entry