Merge branch 'asoc-5.4' into asoc-5.5
[linux-2.6-microblaze.git] / fs / xfs / xfs_attr_list.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4  * Copyright (c) 2013 Red Hat, Inc.
5  * All Rights Reserved.
6  */
7 #include "xfs.h"
8 #include "xfs_fs.h"
9 #include "xfs_shared.h"
10 #include "xfs_format.h"
11 #include "xfs_log_format.h"
12 #include "xfs_trans_resv.h"
13 #include "xfs_mount.h"
14 #include "xfs_da_format.h"
15 #include "xfs_inode.h"
16 #include "xfs_trans.h"
17 #include "xfs_bmap.h"
18 #include "xfs_attr.h"
19 #include "xfs_attr_sf.h"
20 #include "xfs_attr_leaf.h"
21 #include "xfs_error.h"
22 #include "xfs_trace.h"
23 #include "xfs_dir2.h"
24
25 STATIC int
26 xfs_attr_shortform_compare(const void *a, const void *b)
27 {
28         xfs_attr_sf_sort_t *sa, *sb;
29
30         sa = (xfs_attr_sf_sort_t *)a;
31         sb = (xfs_attr_sf_sort_t *)b;
32         if (sa->hash < sb->hash) {
33                 return -1;
34         } else if (sa->hash > sb->hash) {
35                 return 1;
36         } else {
37                 return sa->entno - sb->entno;
38         }
39 }
40
41 #define XFS_ISRESET_CURSOR(cursor) \
42         (!((cursor)->initted) && !((cursor)->hashval) && \
43          !((cursor)->blkno) && !((cursor)->offset))
44 /*
45  * Copy out entries of shortform attribute lists for attr_list().
46  * Shortform attribute lists are not stored in hashval sorted order.
47  * If the output buffer is not large enough to hold them all, then we
48  * we have to calculate each entries' hashvalue and sort them before
49  * we can begin returning them to the user.
50  */
51 static int
52 xfs_attr_shortform_list(xfs_attr_list_context_t *context)
53 {
54         attrlist_cursor_kern_t *cursor;
55         xfs_attr_sf_sort_t *sbuf, *sbp;
56         xfs_attr_shortform_t *sf;
57         xfs_attr_sf_entry_t *sfe;
58         xfs_inode_t *dp;
59         int sbsize, nsbuf, count, i;
60
61         ASSERT(context != NULL);
62         dp = context->dp;
63         ASSERT(dp != NULL);
64         ASSERT(dp->i_afp != NULL);
65         sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
66         ASSERT(sf != NULL);
67         if (!sf->hdr.count)
68                 return 0;
69         cursor = context->cursor;
70         ASSERT(cursor != NULL);
71
72         trace_xfs_attr_list_sf(context);
73
74         /*
75          * If the buffer is large enough and the cursor is at the start,
76          * do not bother with sorting since we will return everything in
77          * one buffer and another call using the cursor won't need to be
78          * made.
79          * Note the generous fudge factor of 16 overhead bytes per entry.
80          * If bufsize is zero then put_listent must be a search function
81          * and can just scan through what we have.
82          */
83         if (context->bufsize == 0 ||
84             (XFS_ISRESET_CURSOR(cursor) &&
85              (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
86                 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
87                         context->put_listent(context,
88                                              sfe->flags,
89                                              sfe->nameval,
90                                              (int)sfe->namelen,
91                                              (int)sfe->valuelen);
92                         /*
93                          * Either search callback finished early or
94                          * didn't fit it all in the buffer after all.
95                          */
96                         if (context->seen_enough)
97                                 break;
98                         sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
99                 }
100                 trace_xfs_attr_list_sf_all(context);
101                 return 0;
102         }
103
104         /* do no more for a search callback */
105         if (context->bufsize == 0)
106                 return 0;
107
108         /*
109          * It didn't all fit, so we have to sort everything on hashval.
110          */
111         sbsize = sf->hdr.count * sizeof(*sbuf);
112         sbp = sbuf = kmem_alloc(sbsize, KM_NOFS);
113
114         /*
115          * Scan the attribute list for the rest of the entries, storing
116          * the relevant info from only those that match into a buffer.
117          */
118         nsbuf = 0;
119         for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
120                 if (unlikely(
121                     ((char *)sfe < (char *)sf) ||
122                     ((char *)sfe >= ((char *)sf + dp->i_afp->if_bytes)))) {
123                         XFS_CORRUPTION_ERROR("xfs_attr_shortform_list",
124                                              XFS_ERRLEVEL_LOW,
125                                              context->dp->i_mount, sfe,
126                                              sizeof(*sfe));
127                         kmem_free(sbuf);
128                         return -EFSCORRUPTED;
129                 }
130
131                 sbp->entno = i;
132                 sbp->hash = xfs_da_hashname(sfe->nameval, sfe->namelen);
133                 sbp->name = sfe->nameval;
134                 sbp->namelen = sfe->namelen;
135                 /* These are bytes, and both on-disk, don't endian-flip */
136                 sbp->valuelen = sfe->valuelen;
137                 sbp->flags = sfe->flags;
138                 sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
139                 sbp++;
140                 nsbuf++;
141         }
142
143         /*
144          * Sort the entries on hash then entno.
145          */
146         xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare);
147
148         /*
149          * Re-find our place IN THE SORTED LIST.
150          */
151         count = 0;
152         cursor->initted = 1;
153         cursor->blkno = 0;
154         for (sbp = sbuf, i = 0; i < nsbuf; i++, sbp++) {
155                 if (sbp->hash == cursor->hashval) {
156                         if (cursor->offset == count) {
157                                 break;
158                         }
159                         count++;
160                 } else if (sbp->hash > cursor->hashval) {
161                         break;
162                 }
163         }
164         if (i == nsbuf) {
165                 kmem_free(sbuf);
166                 return 0;
167         }
168
169         /*
170          * Loop putting entries into the user buffer.
171          */
172         for ( ; i < nsbuf; i++, sbp++) {
173                 if (cursor->hashval != sbp->hash) {
174                         cursor->hashval = sbp->hash;
175                         cursor->offset = 0;
176                 }
177                 context->put_listent(context,
178                                      sbp->flags,
179                                      sbp->name,
180                                      sbp->namelen,
181                                      sbp->valuelen);
182                 if (context->seen_enough)
183                         break;
184                 cursor->offset++;
185         }
186
187         kmem_free(sbuf);
188         return 0;
189 }
190
191 /*
192  * We didn't find the block & hash mentioned in the cursor state, so
193  * walk down the attr btree looking for the hash.
194  */
195 STATIC int
196 xfs_attr_node_list_lookup(
197         struct xfs_attr_list_context    *context,
198         struct attrlist_cursor_kern     *cursor,
199         struct xfs_buf                  **pbp)
200 {
201         struct xfs_da3_icnode_hdr       nodehdr;
202         struct xfs_da_intnode           *node;
203         struct xfs_da_node_entry        *btree;
204         struct xfs_inode                *dp = context->dp;
205         struct xfs_mount                *mp = dp->i_mount;
206         struct xfs_trans                *tp = context->tp;
207         struct xfs_buf                  *bp;
208         int                             i;
209         int                             error = 0;
210         unsigned int                    expected_level = 0;
211         uint16_t                        magic;
212
213         ASSERT(*pbp == NULL);
214         cursor->blkno = 0;
215         for (;;) {
216                 error = xfs_da3_node_read(tp, dp, cursor->blkno, -1, &bp,
217                                 XFS_ATTR_FORK);
218                 if (error)
219                         return error;
220                 node = bp->b_addr;
221                 magic = be16_to_cpu(node->hdr.info.magic);
222                 if (magic == XFS_ATTR_LEAF_MAGIC ||
223                     magic == XFS_ATTR3_LEAF_MAGIC)
224                         break;
225                 if (magic != XFS_DA_NODE_MAGIC &&
226                     magic != XFS_DA3_NODE_MAGIC) {
227                         XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
228                                         node, sizeof(*node));
229                         goto out_corruptbuf;
230                 }
231
232                 dp->d_ops->node_hdr_from_disk(&nodehdr, node);
233
234                 /* Tree taller than we can handle; bail out! */
235                 if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH)
236                         goto out_corruptbuf;
237
238                 /* Check the level from the root node. */
239                 if (cursor->blkno == 0)
240                         expected_level = nodehdr.level - 1;
241                 else if (expected_level != nodehdr.level)
242                         goto out_corruptbuf;
243                 else
244                         expected_level--;
245
246                 btree = dp->d_ops->node_tree_p(node);
247                 for (i = 0; i < nodehdr.count; btree++, i++) {
248                         if (cursor->hashval <= be32_to_cpu(btree->hashval)) {
249                                 cursor->blkno = be32_to_cpu(btree->before);
250                                 trace_xfs_attr_list_node_descend(context,
251                                                 btree);
252                                 break;
253                         }
254                 }
255                 xfs_trans_brelse(tp, bp);
256
257                 if (i == nodehdr.count)
258                         return 0;
259
260                 /* We can't point back to the root. */
261                 if (cursor->blkno == 0)
262                         return -EFSCORRUPTED;
263         }
264
265         if (expected_level != 0)
266                 goto out_corruptbuf;
267
268         *pbp = bp;
269         return 0;
270
271 out_corruptbuf:
272         xfs_trans_brelse(tp, bp);
273         return -EFSCORRUPTED;
274 }
275
276 STATIC int
277 xfs_attr_node_list(
278         struct xfs_attr_list_context    *context)
279 {
280         struct xfs_attr3_icleaf_hdr     leafhdr;
281         struct attrlist_cursor_kern     *cursor;
282         struct xfs_attr_leafblock       *leaf;
283         struct xfs_da_intnode           *node;
284         struct xfs_buf                  *bp;
285         struct xfs_inode                *dp = context->dp;
286         struct xfs_mount                *mp = dp->i_mount;
287         int                             error;
288
289         trace_xfs_attr_node_list(context);
290
291         cursor = context->cursor;
292         cursor->initted = 1;
293
294         /*
295          * Do all sorts of validation on the passed-in cursor structure.
296          * If anything is amiss, ignore the cursor and look up the hashval
297          * starting from the btree root.
298          */
299         bp = NULL;
300         if (cursor->blkno > 0) {
301                 error = xfs_da3_node_read(context->tp, dp, cursor->blkno, -1,
302                                               &bp, XFS_ATTR_FORK);
303                 if ((error != 0) && (error != -EFSCORRUPTED))
304                         return error;
305                 if (bp) {
306                         struct xfs_attr_leaf_entry *entries;
307
308                         node = bp->b_addr;
309                         switch (be16_to_cpu(node->hdr.info.magic)) {
310                         case XFS_DA_NODE_MAGIC:
311                         case XFS_DA3_NODE_MAGIC:
312                                 trace_xfs_attr_list_wrong_blk(context);
313                                 xfs_trans_brelse(context->tp, bp);
314                                 bp = NULL;
315                                 break;
316                         case XFS_ATTR_LEAF_MAGIC:
317                         case XFS_ATTR3_LEAF_MAGIC:
318                                 leaf = bp->b_addr;
319                                 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo,
320                                                              &leafhdr, leaf);
321                                 entries = xfs_attr3_leaf_entryp(leaf);
322                                 if (cursor->hashval > be32_to_cpu(
323                                                 entries[leafhdr.count - 1].hashval)) {
324                                         trace_xfs_attr_list_wrong_blk(context);
325                                         xfs_trans_brelse(context->tp, bp);
326                                         bp = NULL;
327                                 } else if (cursor->hashval <= be32_to_cpu(
328                                                 entries[0].hashval)) {
329                                         trace_xfs_attr_list_wrong_blk(context);
330                                         xfs_trans_brelse(context->tp, bp);
331                                         bp = NULL;
332                                 }
333                                 break;
334                         default:
335                                 trace_xfs_attr_list_wrong_blk(context);
336                                 xfs_trans_brelse(context->tp, bp);
337                                 bp = NULL;
338                         }
339                 }
340         }
341
342         /*
343          * We did not find what we expected given the cursor's contents,
344          * so we start from the top and work down based on the hash value.
345          * Note that start of node block is same as start of leaf block.
346          */
347         if (bp == NULL) {
348                 error = xfs_attr_node_list_lookup(context, cursor, &bp);
349                 if (error || !bp)
350                         return error;
351         }
352         ASSERT(bp != NULL);
353
354         /*
355          * Roll upward through the blocks, processing each leaf block in
356          * order.  As long as there is space in the result buffer, keep
357          * adding the information.
358          */
359         for (;;) {
360                 leaf = bp->b_addr;
361                 xfs_attr3_leaf_list_int(bp, context);
362                 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
363                 if (context->seen_enough || leafhdr.forw == 0)
364                         break;
365                 cursor->blkno = leafhdr.forw;
366                 xfs_trans_brelse(context->tp, bp);
367                 error = xfs_attr3_leaf_read(context->tp, dp, cursor->blkno, -1, &bp);
368                 if (error)
369                         return error;
370         }
371         xfs_trans_brelse(context->tp, bp);
372         return 0;
373 }
374
375 /*
376  * Copy out attribute list entries for attr_list(), for leaf attribute lists.
377  */
378 void
379 xfs_attr3_leaf_list_int(
380         struct xfs_buf                  *bp,
381         struct xfs_attr_list_context    *context)
382 {
383         struct attrlist_cursor_kern     *cursor;
384         struct xfs_attr_leafblock       *leaf;
385         struct xfs_attr3_icleaf_hdr     ichdr;
386         struct xfs_attr_leaf_entry      *entries;
387         struct xfs_attr_leaf_entry      *entry;
388         int                             i;
389         struct xfs_mount                *mp = context->dp->i_mount;
390
391         trace_xfs_attr_list_leaf(context);
392
393         leaf = bp->b_addr;
394         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
395         entries = xfs_attr3_leaf_entryp(leaf);
396
397         cursor = context->cursor;
398         cursor->initted = 1;
399
400         /*
401          * Re-find our place in the leaf block if this is a new syscall.
402          */
403         if (context->resynch) {
404                 entry = &entries[0];
405                 for (i = 0; i < ichdr.count; entry++, i++) {
406                         if (be32_to_cpu(entry->hashval) == cursor->hashval) {
407                                 if (cursor->offset == context->dupcnt) {
408                                         context->dupcnt = 0;
409                                         break;
410                                 }
411                                 context->dupcnt++;
412                         } else if (be32_to_cpu(entry->hashval) >
413                                         cursor->hashval) {
414                                 context->dupcnt = 0;
415                                 break;
416                         }
417                 }
418                 if (i == ichdr.count) {
419                         trace_xfs_attr_list_notfound(context);
420                         return;
421                 }
422         } else {
423                 entry = &entries[0];
424                 i = 0;
425         }
426         context->resynch = 0;
427
428         /*
429          * We have found our place, start copying out the new attributes.
430          */
431         for (; i < ichdr.count; entry++, i++) {
432                 char *name;
433                 int namelen, valuelen;
434
435                 if (be32_to_cpu(entry->hashval) != cursor->hashval) {
436                         cursor->hashval = be32_to_cpu(entry->hashval);
437                         cursor->offset = 0;
438                 }
439
440                 if ((entry->flags & XFS_ATTR_INCOMPLETE) &&
441                     !(context->flags & ATTR_INCOMPLETE))
442                         continue;               /* skip incomplete entries */
443
444                 if (entry->flags & XFS_ATTR_LOCAL) {
445                         xfs_attr_leaf_name_local_t *name_loc;
446
447                         name_loc = xfs_attr3_leaf_name_local(leaf, i);
448                         name = name_loc->nameval;
449                         namelen = name_loc->namelen;
450                         valuelen = be16_to_cpu(name_loc->valuelen);
451                 } else {
452                         xfs_attr_leaf_name_remote_t *name_rmt;
453
454                         name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
455                         name = name_rmt->name;
456                         namelen = name_rmt->namelen;
457                         valuelen = be32_to_cpu(name_rmt->valuelen);
458                 }
459
460                 context->put_listent(context, entry->flags,
461                                               name, namelen, valuelen);
462                 if (context->seen_enough)
463                         break;
464                 cursor->offset++;
465         }
466         trace_xfs_attr_list_leaf_end(context);
467         return;
468 }
469
470 /*
471  * Copy out attribute entries for attr_list(), for leaf attribute lists.
472  */
473 STATIC int
474 xfs_attr_leaf_list(xfs_attr_list_context_t *context)
475 {
476         int error;
477         struct xfs_buf *bp;
478
479         trace_xfs_attr_leaf_list(context);
480
481         context->cursor->blkno = 0;
482         error = xfs_attr3_leaf_read(context->tp, context->dp, 0, -1, &bp);
483         if (error)
484                 return error;
485
486         xfs_attr3_leaf_list_int(bp, context);
487         xfs_trans_brelse(context->tp, bp);
488         return 0;
489 }
490
491 int
492 xfs_attr_list_int_ilocked(
493         struct xfs_attr_list_context    *context)
494 {
495         struct xfs_inode                *dp = context->dp;
496
497         ASSERT(xfs_isilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
498
499         /*
500          * Decide on what work routines to call based on the inode size.
501          */
502         if (!xfs_inode_hasattr(dp))
503                 return 0;
504         else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
505                 return xfs_attr_shortform_list(context);
506         else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK))
507                 return xfs_attr_leaf_list(context);
508         return xfs_attr_node_list(context);
509 }
510
511 int
512 xfs_attr_list_int(
513         xfs_attr_list_context_t *context)
514 {
515         int error;
516         xfs_inode_t *dp = context->dp;
517         uint            lock_mode;
518
519         XFS_STATS_INC(dp->i_mount, xs_attr_list);
520
521         if (XFS_FORCED_SHUTDOWN(dp->i_mount))
522                 return -EIO;
523
524         lock_mode = xfs_ilock_attr_map_shared(dp);
525         error = xfs_attr_list_int_ilocked(context);
526         xfs_iunlock(dp, lock_mode);
527         return error;
528 }
529
530 #define ATTR_ENTBASESIZE                /* minimum bytes used by an attr */ \
531         (((struct attrlist_ent *) 0)->a_name - (char *) 0)
532 #define ATTR_ENTSIZE(namelen)           /* actual bytes used by an attr */ \
533         ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(uint32_t)-1) \
534          & ~(sizeof(uint32_t)-1))
535
536 /*
537  * Format an attribute and copy it out to the user's buffer.
538  * Take care to check values and protect against them changing later,
539  * we may be reading them directly out of a user buffer.
540  */
541 STATIC void
542 xfs_attr_put_listent(
543         xfs_attr_list_context_t *context,
544         int             flags,
545         unsigned char   *name,
546         int             namelen,
547         int             valuelen)
548 {
549         struct attrlist *alist = (struct attrlist *)context->alist;
550         attrlist_ent_t *aep;
551         int arraytop;
552
553         ASSERT(!context->seen_enough);
554         ASSERT(!(context->flags & ATTR_KERNOVAL));
555         ASSERT(context->count >= 0);
556         ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
557         ASSERT(context->firstu >= sizeof(*alist));
558         ASSERT(context->firstu <= context->bufsize);
559
560         /*
561          * Only list entries in the right namespace.
562          */
563         if (((context->flags & ATTR_SECURE) == 0) !=
564             ((flags & XFS_ATTR_SECURE) == 0))
565                 return;
566         if (((context->flags & ATTR_ROOT) == 0) !=
567             ((flags & XFS_ATTR_ROOT) == 0))
568                 return;
569
570         arraytop = sizeof(*alist) +
571                         context->count * sizeof(alist->al_offset[0]);
572         context->firstu -= ATTR_ENTSIZE(namelen);
573         if (context->firstu < arraytop) {
574                 trace_xfs_attr_list_full(context);
575                 alist->al_more = 1;
576                 context->seen_enough = 1;
577                 return;
578         }
579
580         aep = (attrlist_ent_t *)&context->alist[context->firstu];
581         aep->a_valuelen = valuelen;
582         memcpy(aep->a_name, name, namelen);
583         aep->a_name[namelen] = 0;
584         alist->al_offset[context->count++] = context->firstu;
585         alist->al_count = context->count;
586         trace_xfs_attr_list_add(context);
587         return;
588 }
589
590 /*
591  * Generate a list of extended attribute names and optionally
592  * also value lengths.  Positive return value follows the XFS
593  * convention of being an error, zero or negative return code
594  * is the length of the buffer returned (negated), indicating
595  * success.
596  */
597 int
598 xfs_attr_list(
599         xfs_inode_t     *dp,
600         char            *buffer,
601         int             bufsize,
602         int             flags,
603         attrlist_cursor_kern_t *cursor)
604 {
605         xfs_attr_list_context_t context;
606         struct attrlist *alist;
607         int error;
608
609         /*
610          * Validate the cursor.
611          */
612         if (cursor->pad1 || cursor->pad2)
613                 return -EINVAL;
614         if ((cursor->initted == 0) &&
615             (cursor->hashval || cursor->blkno || cursor->offset))
616                 return -EINVAL;
617
618         /* Only internal consumers can retrieve incomplete attrs. */
619         if (flags & ATTR_INCOMPLETE)
620                 return -EINVAL;
621
622         /*
623          * Check for a properly aligned buffer.
624          */
625         if (((long)buffer) & (sizeof(int)-1))
626                 return -EFAULT;
627         if (flags & ATTR_KERNOVAL)
628                 bufsize = 0;
629
630         /*
631          * Initialize the output buffer.
632          */
633         memset(&context, 0, sizeof(context));
634         context.dp = dp;
635         context.cursor = cursor;
636         context.resynch = 1;
637         context.flags = flags;
638         context.alist = buffer;
639         context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
640         context.firstu = context.bufsize;
641         context.put_listent = xfs_attr_put_listent;
642
643         alist = (struct attrlist *)context.alist;
644         alist->al_count = 0;
645         alist->al_more = 0;
646         alist->al_offset[0] = context.bufsize;
647
648         error = xfs_attr_list_int(&context);
649         ASSERT(error <= 0);
650         return error;
651 }