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