Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 : * All Rights Reserved.
5 : */
6 : #include "xfs.h"
7 : #include "xfs_fs.h"
8 : #include "xfs_shared.h"
9 : #include "xfs_format.h"
10 : #include "xfs_log_format.h"
11 : #include "xfs_trans_resv.h"
12 : #include "xfs_mount.h"
13 : #include "xfs_defer.h"
14 : #include "xfs_da_format.h"
15 : #include "xfs_da_btree.h"
16 : #include "xfs_attr_sf.h"
17 : #include "xfs_inode.h"
18 : #include "xfs_trans.h"
19 : #include "xfs_bmap.h"
20 : #include "xfs_bmap_btree.h"
21 : #include "xfs_attr.h"
22 : #include "xfs_attr_leaf.h"
23 : #include "xfs_attr_remote.h"
24 : #include "xfs_quota.h"
25 : #include "xfs_trans_space.h"
26 : #include "xfs_trace.h"
27 : #include "xfs_attr_item.h"
28 : #include "xfs_xattr.h"
29 :
30 : struct kmem_cache *xfs_attr_intent_cache;
31 :
32 : /*
33 : * xfs_attr.c
34 : *
35 : * Provide the external interfaces to manage attribute lists.
36 : */
37 :
38 : /*========================================================================
39 : * Function prototypes for the kernel.
40 : *========================================================================*/
41 :
42 : /*
43 : * Internal routines when attribute list fits inside the inode.
44 : */
45 : STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
46 :
47 : /*
48 : * Internal routines when attribute list is one block.
49 : */
50 : STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
51 : STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
52 : STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
53 : STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args);
54 :
55 : /*
56 : * Internal routines when attribute list is more than one block.
57 : */
58 : STATIC int xfs_attr_node_get(xfs_da_args_t *args);
59 : STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
60 : static int xfs_attr_node_try_addname(struct xfs_attr_intent *attr);
61 : STATIC int xfs_attr_node_addname_find_attr(struct xfs_attr_intent *attr);
62 : STATIC int xfs_attr_node_remove_attr(struct xfs_attr_intent *attr);
63 : STATIC int xfs_attr_node_lookup(struct xfs_da_args *args,
64 : struct xfs_da_state *state);
65 :
66 : int
67 398573590 : xfs_inode_hasattr(
68 : struct xfs_inode *ip)
69 : {
70 443562164 : if (!xfs_inode_has_attr_fork(ip))
71 : return 0;
72 299184395 : if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
73 151453146 : ip->i_af.if_nextents == 0)
74 485618 : return 0;
75 : return 1;
76 : }
77 :
78 : /*
79 : * Returns true if the there is exactly only block in the attr fork, in which
80 : * case the attribute fork consists of a single leaf block entry.
81 : */
82 : bool
83 257182762 : xfs_attr_is_leaf(
84 : struct xfs_inode *ip)
85 : {
86 257182762 : struct xfs_ifork *ifp = &ip->i_af;
87 257182762 : struct xfs_iext_cursor icur;
88 257182762 : struct xfs_bmbt_irec imap;
89 :
90 257182762 : if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
91 : return false;
92 :
93 252210630 : xfs_iext_first(ifp, &icur);
94 252191012 : xfs_iext_get_extent(ifp, &icur, &imap);
95 253022930 : return imap.br_startoff == 0 && imap.br_blockcount == 1;
96 : }
97 :
98 : /*
99 : * XXX (dchinner): name path state saving and refilling is an optimisation to
100 : * avoid needing to look up name entries after rolling transactions removing
101 : * remote xattr blocks between the name entry lookup and name entry removal.
102 : * This optimisation got sidelined when combining the set and remove state
103 : * machines, but the code has been left in place because it is worthwhile to
104 : * restore the optimisation once the combined state machine paths have settled.
105 : *
106 : * This comment is a public service announcement to remind Future Dave that he
107 : * still needs to restore this code to working order.
108 : */
109 : #if 0
110 : /*
111 : * Fill in the disk block numbers in the state structure for the buffers
112 : * that are attached to the state structure.
113 : * This is done so that we can quickly reattach ourselves to those buffers
114 : * after some set of transaction commits have released these buffers.
115 : */
116 : static int
117 : xfs_attr_fillstate(xfs_da_state_t *state)
118 : {
119 : xfs_da_state_path_t *path;
120 : xfs_da_state_blk_t *blk;
121 : int level;
122 :
123 : trace_xfs_attr_fillstate(state->args);
124 :
125 : /*
126 : * Roll down the "path" in the state structure, storing the on-disk
127 : * block number for those buffers in the "path".
128 : */
129 : path = &state->path;
130 : ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
131 : for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
132 : if (blk->bp) {
133 : blk->disk_blkno = xfs_buf_daddr(blk->bp);
134 : blk->bp = NULL;
135 : } else {
136 : blk->disk_blkno = 0;
137 : }
138 : }
139 :
140 : /*
141 : * Roll down the "altpath" in the state structure, storing the on-disk
142 : * block number for those buffers in the "altpath".
143 : */
144 : path = &state->altpath;
145 : ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
146 : for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
147 : if (blk->bp) {
148 : blk->disk_blkno = xfs_buf_daddr(blk->bp);
149 : blk->bp = NULL;
150 : } else {
151 : blk->disk_blkno = 0;
152 : }
153 : }
154 :
155 : return 0;
156 : }
157 :
158 : /*
159 : * Reattach the buffers to the state structure based on the disk block
160 : * numbers stored in the state structure.
161 : * This is done after some set of transaction commits have released those
162 : * buffers from our grip.
163 : */
164 : static int
165 : xfs_attr_refillstate(xfs_da_state_t *state)
166 : {
167 : xfs_da_state_path_t *path;
168 : xfs_da_state_blk_t *blk;
169 : int level, error;
170 :
171 : trace_xfs_attr_refillstate(state->args);
172 :
173 : /*
174 : * Roll down the "path" in the state structure, storing the on-disk
175 : * block number for those buffers in the "path".
176 : */
177 : path = &state->path;
178 : ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
179 : for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
180 : if (blk->disk_blkno) {
181 : error = xfs_da3_node_read_mapped(state->args->trans,
182 : state->args->dp, blk->disk_blkno,
183 : &blk->bp, XFS_ATTR_FORK);
184 : if (error)
185 : return error;
186 : } else {
187 : blk->bp = NULL;
188 : }
189 : }
190 :
191 : /*
192 : * Roll down the "altpath" in the state structure, storing the on-disk
193 : * block number for those buffers in the "altpath".
194 : */
195 : path = &state->altpath;
196 : ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
197 : for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
198 : if (blk->disk_blkno) {
199 : error = xfs_da3_node_read_mapped(state->args->trans,
200 : state->args->dp, blk->disk_blkno,
201 : &blk->bp, XFS_ATTR_FORK);
202 : if (error)
203 : return error;
204 : } else {
205 : blk->bp = NULL;
206 : }
207 : }
208 :
209 : return 0;
210 : }
211 : #else
212 : static int xfs_attr_fillstate(xfs_da_state_t *state) { return 0; }
213 : #endif
214 :
215 : /*========================================================================
216 : * Overall external interface routines.
217 : *========================================================================*/
218 :
219 : /*
220 : * Retrieve an extended attribute and its value. Must have ilock.
221 : * Returns 0 on successful retrieval, otherwise an error.
222 : */
223 : int
224 50595915 : xfs_attr_get_ilocked(
225 : struct xfs_da_args *args)
226 : {
227 50595915 : ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
228 :
229 50550478 : if (!xfs_inode_hasattr(args->dp))
230 : return -ENOATTR;
231 :
232 35286906 : if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
233 25729305 : return xfs_attr_shortform_getvalue(args);
234 9557601 : if (xfs_attr_is_leaf(args->dp))
235 9332536 : return xfs_attr_leaf_get(args);
236 225812 : return xfs_attr_node_get(args);
237 : }
238 :
239 : /*
240 : * Retrieve an extended attribute by name, and its value if requested.
241 : *
242 : * If args->valuelen is zero, then the caller does not want the value, just an
243 : * indication whether the attribute exists and the size of the value if it
244 : * exists. The size is returned in args.valuelen.
245 : *
246 : * If args->value is NULL but args->valuelen is non-zero, allocate the buffer
247 : * for the value after existence of the attribute has been determined. The
248 : * caller always has to free args->value if it is set, no matter if this
249 : * function was successful or not.
250 : *
251 : * If the attribute is found, but exceeds the size limit set by the caller in
252 : * args->valuelen, return -ERANGE with the size of the attribute that was found
253 : * in args->valuelen.
254 : */
255 : int
256 30740815 : xfs_attr_get(
257 : struct xfs_da_args *args)
258 : {
259 30740815 : uint lock_mode;
260 30740815 : int error;
261 :
262 30740815 : XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
263 :
264 61368550 : if (xfs_is_shutdown(args->dp->i_mount))
265 : return -EIO;
266 :
267 30683546 : args->geo = args->dp->i_mount->m_attr_geo;
268 30683546 : args->whichfork = XFS_ATTR_FORK;
269 30683546 : args->hashval = xfs_da_hashname(args->name, args->namelen);
270 :
271 : /* Entirely possible to look up a name which doesn't exist */
272 30676879 : args->op_flags = XFS_DA_OP_OKNOENT;
273 :
274 30676879 : lock_mode = xfs_ilock_attr_map_shared(args->dp);
275 30694752 : error = xfs_attr_get_ilocked(args);
276 30684950 : xfs_iunlock(args->dp, lock_mode);
277 :
278 30684950 : return error;
279 : }
280 :
281 : /*
282 : * Calculate how many blocks we need for the new attribute,
283 : */
284 : int
285 80041989 : xfs_attr_calc_size(
286 : struct xfs_da_args *args,
287 : int *local)
288 : {
289 80041989 : struct xfs_mount *mp = args->dp->i_mount;
290 80041989 : int size;
291 80041989 : int nblks;
292 :
293 : /*
294 : * Determine space new attribute will use, and if it would be
295 : * "local" or "remote" (note: local != inline).
296 : */
297 80041989 : size = xfs_attr_leaf_newentsize(args, local);
298 80033856 : nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
299 80033856 : if (*local) {
300 80030670 : if (size > (args->geo->blksize / 2)) {
301 : /* Double split possible */
302 11 : nblks *= 2;
303 : }
304 : } else {
305 : /*
306 : * Out of line attribute, cannot double split, but
307 : * make room for the attribute value itself.
308 : */
309 3186 : uint dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
310 3186 : nblks += dblocks;
311 3186 : nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
312 : }
313 :
314 80033856 : return nblks;
315 : }
316 :
317 : /* Initialize transaction reservation for attr operations */
318 : void
319 124960773 : xfs_init_attr_trans(
320 : struct xfs_da_args *args,
321 : struct xfs_trans_res *tres,
322 : unsigned int *total)
323 : {
324 124960773 : struct xfs_mount *mp = args->dp->i_mount;
325 :
326 124960773 : if (args->value) {
327 80043313 : tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
328 80043313 : M_RES(mp)->tr_attrsetrt.tr_logres *
329 80043313 : args->total;
330 80043313 : tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
331 80043313 : tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
332 80043313 : *total = args->total;
333 : } else {
334 44917460 : *tres = M_RES(mp)->tr_attrrm;
335 44917460 : *total = XFS_ATTRRM_SPACE_RES(mp);
336 : }
337 124960773 : }
338 :
339 : /*
340 : * Add an attr to a shortform fork. If there is no space,
341 : * xfs_attr_shortform_addname() will convert to leaf format and return -ENOSPC.
342 : * to use.
343 : */
344 : STATIC int
345 24030559 : xfs_attr_try_sf_addname(
346 : struct xfs_inode *dp,
347 : struct xfs_da_args *args)
348 : {
349 :
350 24030559 : int error;
351 :
352 : /*
353 : * Build initial attribute list (if required).
354 : */
355 24030559 : if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
356 4888605 : xfs_attr_shortform_create(args);
357 :
358 24031740 : error = xfs_attr_shortform_addname(args);
359 24052740 : if (error == -ENOSPC)
360 : return error;
361 :
362 : /*
363 : * Commit the shortform mods, and we're done.
364 : * NOTE: this is also the error path (EEXIST, etc).
365 : */
366 21208421 : if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
367 21208048 : xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
368 :
369 21209285 : if (xfs_has_wsync(dp->i_mount))
370 0 : xfs_trans_set_sync(args->trans);
371 :
372 : return error;
373 : }
374 :
375 : static int
376 24034325 : xfs_attr_sf_addname(
377 : struct xfs_attr_intent *attr)
378 : {
379 24034325 : struct xfs_da_args *args = attr->xattri_da_args;
380 24034325 : struct xfs_inode *dp = args->dp;
381 24034325 : int error = 0;
382 :
383 24034325 : error = xfs_attr_try_sf_addname(dp, args);
384 24049403 : if (error != -ENOSPC) {
385 21205150 : ASSERT(!error || error == -EEXIST);
386 21205150 : attr->xattri_dela_state = XFS_DAS_DONE;
387 21205150 : goto out;
388 : }
389 :
390 : /*
391 : * It won't fit in the shortform, transform to a leaf block. GROT:
392 : * another possible req'mt for a double-split btree op.
393 : */
394 2844253 : error = xfs_attr_shortform_to_leaf(args);
395 2844485 : if (error)
396 : return error;
397 :
398 2844478 : attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
399 24049628 : out:
400 24049628 : trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
401 24049628 : return error;
402 : }
403 :
404 : /*
405 : * Handle the state change on completion of a multi-state attr operation.
406 : *
407 : * If the XFS_DA_OP_REPLACE flag is set, this means the operation was the first
408 : * modification in a attr replace operation and we still have to do the second
409 : * state, indicated by @replace_state.
410 : *
411 : * We consume the XFS_DA_OP_REPLACE flag so that when we are called again on
412 : * completion of the second half of the attr replace operation we correctly
413 : * signal that it is done.
414 : */
415 : static enum xfs_delattr_state
416 : xfs_attr_complete_op(
417 : struct xfs_attr_intent *attr,
418 : enum xfs_delattr_state replace_state)
419 : {
420 82818578 : struct xfs_da_args *args = attr->xattri_da_args;
421 82818578 : bool do_replace = args->op_flags & XFS_DA_OP_REPLACE;
422 :
423 82818578 : args->op_flags &= ~XFS_DA_OP_REPLACE;
424 34535359 : if (do_replace) {
425 11491122 : args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
426 11491122 : return replace_state;
427 : }
428 : return XFS_DAS_DONE;
429 : }
430 :
431 : static int
432 46993310 : xfs_attr_leaf_addname(
433 : struct xfs_attr_intent *attr)
434 : {
435 46993310 : struct xfs_da_args *args = attr->xattri_da_args;
436 46993310 : int error;
437 :
438 46993310 : ASSERT(xfs_attr_is_leaf(args->dp));
439 :
440 : /*
441 : * Use the leaf buffer we may already hold locked as a result of
442 : * a sf-to-leaf conversion.
443 : */
444 47036953 : error = xfs_attr_leaf_try_add(args);
445 :
446 47033737 : if (error == -ENOSPC) {
447 24559 : error = xfs_attr3_leaf_to_node(args);
448 24559 : if (error)
449 : return error;
450 :
451 : /*
452 : * We're not in leaf format anymore, so roll the transaction and
453 : * retry the add to the newly allocated node block.
454 : */
455 24548 : attr->xattri_dela_state = XFS_DAS_NODE_ADD;
456 24548 : goto out;
457 : }
458 47009178 : if (error)
459 : return error;
460 :
461 : /*
462 : * We need to commit and roll if we need to allocate remote xattr blocks
463 : * or perform more xattr manipulations. Otherwise there is nothing more
464 : * to do and we can return success.
465 : */
466 47009177 : if (args->rmtblkno)
467 2735 : attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
468 : else
469 58024334 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
470 : XFS_DAS_LEAF_REPLACE);
471 47033725 : out:
472 47033725 : trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
473 47033725 : return error;
474 : }
475 :
476 : /*
477 : * Add an entry to a node format attr tree.
478 : *
479 : * Note that we might still have a leaf here - xfs_attr_is_leaf() cannot tell
480 : * the difference between leaf + remote attr blocks and a node format tree,
481 : * so we may still end up having to convert from leaf to node format here.
482 : */
483 : static int
484 1274110 : xfs_attr_node_addname(
485 : struct xfs_attr_intent *attr)
486 : {
487 1274110 : struct xfs_da_args *args = attr->xattri_da_args;
488 1274110 : int error;
489 :
490 1274110 : error = xfs_attr_node_addname_find_attr(attr);
491 1274133 : if (error)
492 : return error;
493 :
494 1274135 : error = xfs_attr_node_try_addname(attr);
495 1274053 : if (error == -ENOSPC) {
496 0 : error = xfs_attr3_leaf_to_node(args);
497 0 : if (error)
498 : return error;
499 : /*
500 : * No state change, we really are in node form now
501 : * but we need the transaction rolled to continue.
502 : */
503 0 : goto out;
504 : }
505 1274053 : if (error)
506 : return error;
507 :
508 1274042 : if (args->rmtblkno)
509 101 : attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
510 : else
511 1495044 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
512 : XFS_DAS_NODE_REPLACE);
513 1274042 : out:
514 1274042 : trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
515 1274042 : return error;
516 : }
517 :
518 : static int
519 2836 : xfs_attr_rmtval_alloc(
520 : struct xfs_attr_intent *attr)
521 : {
522 2836 : struct xfs_da_args *args = attr->xattri_da_args;
523 2836 : int error = 0;
524 :
525 : /*
526 : * If there was an out-of-line value, allocate the blocks we
527 : * identified for its storage and copy the value. This is done
528 : * after we create the attribute so that we don't overflow the
529 : * maximum size of a transaction and/or hit a deadlock.
530 : */
531 2836 : if (attr->xattri_blkcnt > 0) {
532 2836 : error = xfs_attr_rmtval_set_blk(attr);
533 2836 : if (error)
534 : return error;
535 : /* Roll the transaction only if there is more to allocate. */
536 2836 : if (attr->xattri_blkcnt > 0)
537 0 : goto out;
538 : }
539 :
540 2836 : error = xfs_attr_rmtval_set_value(args);
541 2836 : if (error)
542 : return error;
543 :
544 5672 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
545 2836 : ++attr->xattri_dela_state);
546 : /*
547 : * If we are not doing a rename, we've finished the operation but still
548 : * have to clear the incomplete flag protecting the new attr from
549 : * exposing partially initialised state if we crash during creation.
550 : */
551 2836 : if (attr->xattri_dela_state == XFS_DAS_DONE)
552 2826 : error = xfs_attr3_leaf_clearflag(args);
553 10 : out:
554 2836 : trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
555 2836 : return error;
556 : }
557 :
558 : /*
559 : * Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
560 : * for later deletion of the entry.
561 : */
562 : static int
563 : xfs_attr_leaf_mark_incomplete(
564 : struct xfs_da_args *args,
565 : struct xfs_da_state *state)
566 : {
567 382784 : int error;
568 :
569 : /*
570 : * Fill in disk block numbers in the state structure
571 : * so that we can get the buffers back after we commit
572 : * several transactions in the following calls.
573 : */
574 382784 : error = xfs_attr_fillstate(state);
575 382784 : if (error)
576 : return error;
577 :
578 : /*
579 : * Mark the attribute as INCOMPLETE
580 : */
581 382784 : return xfs_attr3_leaf_setflag(args);
582 : }
583 :
584 : /* Ensure the da state of an xattr deferred work item is ready to go. */
585 : static inline void
586 1656830 : xfs_attr_item_init_da_state(
587 : struct xfs_attr_intent *attr)
588 : {
589 1656830 : struct xfs_da_args *args = attr->xattri_da_args;
590 :
591 1656830 : if (!attr->xattri_da_state)
592 1654691 : attr->xattri_da_state = xfs_da_state_alloc(args);
593 : else
594 2139 : xfs_da_state_reset(attr->xattri_da_state, args);
595 1656894 : }
596 :
597 : /*
598 : * Initial setup for xfs_attr_node_removename. Make sure the attr is there and
599 : * the blocks are valid. Attr keys with remote blocks will be marked
600 : * incomplete.
601 : */
602 : static
603 382807 : int xfs_attr_node_removename_setup(
604 : struct xfs_attr_intent *attr)
605 : {
606 382807 : struct xfs_da_args *args = attr->xattri_da_args;
607 382807 : struct xfs_da_state *state;
608 382807 : int error;
609 :
610 382807 : xfs_attr_item_init_da_state(attr);
611 382808 : error = xfs_attr_node_lookup(args, attr->xattri_da_state);
612 382817 : if (error != -EEXIST)
613 33 : goto out;
614 382784 : error = 0;
615 :
616 382784 : state = attr->xattri_da_state;
617 382784 : ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
618 382784 : ASSERT(state->path.blk[state->path.active - 1].magic ==
619 : XFS_ATTR_LEAF_MAGIC);
620 :
621 382784 : error = xfs_attr_leaf_mark_incomplete(args, state);
622 382777 : if (error)
623 0 : goto out;
624 382777 : if (args->rmtblkno > 0)
625 68 : error = xfs_attr_rmtval_invalidate(args);
626 382709 : out:
627 382810 : if (error) {
628 33 : xfs_da_state_free(attr->xattri_da_state);
629 33 : attr->xattri_da_state = NULL;
630 : }
631 :
632 382810 : return error;
633 : }
634 :
635 : /*
636 : * Remove the original attr we have just replaced. This is dependent on the
637 : * original lookup and insert placing the old attr in args->blkno/args->index
638 : * and the new attr in args->blkno2/args->index2.
639 : */
640 : static int
641 11016222 : xfs_attr_leaf_remove_attr(
642 : struct xfs_attr_intent *attr)
643 : {
644 11016222 : struct xfs_da_args *args = attr->xattri_da_args;
645 11016222 : struct xfs_inode *dp = args->dp;
646 11016222 : struct xfs_buf *bp = NULL;
647 11016222 : int forkoff;
648 11016222 : int error;
649 :
650 11016222 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
651 : &bp);
652 11017958 : if (error)
653 : return error;
654 :
655 11017813 : xfs_attr3_leaf_remove(bp, args);
656 :
657 11021509 : forkoff = xfs_attr_shortform_allfit(bp, dp);
658 11019599 : if (forkoff)
659 258997 : error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
660 : /* bp is gone due to xfs_da_shrink_inode */
661 :
662 : return error;
663 : }
664 :
665 : /*
666 : * Shrink an attribute from leaf to shortform. Used by the node format remove
667 : * path when the node format collapses to a single block and so we have to check
668 : * if it can be collapsed further.
669 : */
670 : static int
671 603876 : xfs_attr_leaf_shrink(
672 : struct xfs_da_args *args)
673 : {
674 603876 : struct xfs_inode *dp = args->dp;
675 603876 : struct xfs_buf *bp;
676 603876 : int forkoff;
677 603876 : int error;
678 :
679 603876 : if (!xfs_attr_is_leaf(dp))
680 : return 0;
681 :
682 85 : error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
683 85 : if (error)
684 : return error;
685 :
686 85 : forkoff = xfs_attr_shortform_allfit(bp, dp);
687 85 : if (forkoff) {
688 56 : error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
689 : /* bp is gone due to xfs_da_shrink_inode */
690 : } else {
691 29 : xfs_trans_brelse(args->trans, bp);
692 : }
693 :
694 : return error;
695 : }
696 :
697 : /*
698 : * Run the attribute operation specified in @attr.
699 : *
700 : * This routine is meant to function as a delayed operation and will set the
701 : * state to XFS_DAS_DONE when the operation is complete. Calling functions will
702 : * need to handle this, and recall the function until either an error or
703 : * XFS_DAS_DONE is detected.
704 : */
705 : int
706 118521376 : xfs_attr_set_iter(
707 : struct xfs_attr_intent *attr)
708 : {
709 118521376 : struct xfs_da_args *args = attr->xattri_da_args;
710 118521376 : int error = 0;
711 :
712 : /* State machine switch */
713 : next_state:
714 129759065 : switch (attr->xattri_dela_state) {
715 0 : case XFS_DAS_UNINIT:
716 0 : ASSERT(0);
717 0 : return -EFSCORRUPTED;
718 24038189 : case XFS_DAS_SF_ADD:
719 24038189 : return xfs_attr_sf_addname(attr);
720 47034933 : case XFS_DAS_LEAF_ADD:
721 47034933 : return xfs_attr_leaf_addname(attr);
722 1274118 : case XFS_DAS_NODE_ADD:
723 1274118 : return xfs_attr_node_addname(attr);
724 :
725 5432690 : case XFS_DAS_SF_REMOVE:
726 5432690 : error = xfs_attr_sf_removename(args);
727 5433282 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
728 : xfs_attr_init_add_state(args));
729 5432055 : break;
730 17494010 : case XFS_DAS_LEAF_REMOVE:
731 17494010 : error = xfs_attr_leaf_removename(args);
732 17494399 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
733 : xfs_attr_init_add_state(args));
734 17481247 : break;
735 382809 : case XFS_DAS_NODE_REMOVE:
736 382809 : error = xfs_attr_node_removename_setup(attr);
737 382798 : if (error == -ENOATTR &&
738 33 : (args->op_flags & XFS_DA_OP_RECOVERY)) {
739 33 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
740 : xfs_attr_init_add_state(args));
741 33 : error = 0;
742 33 : break;
743 : }
744 382765 : if (error)
745 : return error;
746 382765 : attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
747 382765 : if (args->rmtblkno == 0)
748 382697 : attr->xattri_dela_state++;
749 : break;
750 :
751 2836 : case XFS_DAS_LEAF_SET_RMT:
752 : case XFS_DAS_NODE_SET_RMT:
753 2836 : error = xfs_attr_rmtval_find_space(attr);
754 2836 : if (error)
755 0 : return error;
756 2836 : attr->xattri_dela_state++;
757 2836 : fallthrough;
758 :
759 2836 : case XFS_DAS_LEAF_ALLOC_RMT:
760 : case XFS_DAS_NODE_ALLOC_RMT:
761 2836 : error = xfs_attr_rmtval_alloc(attr);
762 2836 : if (error)
763 0 : return error;
764 2836 : if (attr->xattri_dela_state == XFS_DAS_DONE)
765 : break;
766 10 : goto next_state;
767 :
768 11238107 : case XFS_DAS_LEAF_REPLACE:
769 : case XFS_DAS_NODE_REPLACE:
770 : /*
771 : * We must "flip" the incomplete flags on the "new" and "old"
772 : * attribute/value pairs so that one disappears and one appears
773 : * atomically.
774 : */
775 11238107 : error = xfs_attr3_leaf_flipflags(args);
776 11238010 : if (error)
777 : return error;
778 : /*
779 : * We must commit the flag value change now to make it atomic
780 : * and then we can start the next trans in series at REMOVE_OLD.
781 : */
782 11238010 : attr->xattri_dela_state++;
783 11238010 : break;
784 :
785 11240817 : case XFS_DAS_LEAF_REMOVE_OLD:
786 : case XFS_DAS_NODE_REMOVE_OLD:
787 : /*
788 : * If we have a remote attr, start the process of removing it
789 : * by invalidating any cached buffers.
790 : *
791 : * If we don't have a remote attr, we skip the remote block
792 : * removal state altogether with a second state increment.
793 : */
794 11240817 : xfs_attr_restore_rmt_blk(args);
795 11237679 : if (args->rmtblkno) {
796 20 : error = xfs_attr_rmtval_invalidate(args);
797 20 : if (error)
798 0 : return error;
799 : } else {
800 11237659 : attr->xattri_dela_state++;
801 : }
802 :
803 11237679 : attr->xattri_dela_state++;
804 11237679 : goto next_state;
805 :
806 88 : case XFS_DAS_LEAF_REMOVE_RMT:
807 : case XFS_DAS_NODE_REMOVE_RMT:
808 88 : error = xfs_attr_rmtval_remove(attr);
809 88 : if (error == -EAGAIN) {
810 : error = 0;
811 : break;
812 : }
813 88 : if (error)
814 : return error;
815 :
816 : /*
817 : * We've finished removing the remote attr blocks, so commit the
818 : * transaction and move on to removing the attr name from the
819 : * leaf/node block. Removing the attr might require a full
820 : * transaction reservation for btree block freeing, so we
821 : * can't do that in the same transaction where we removed the
822 : * remote attr blocks.
823 : */
824 88 : attr->xattri_dela_state++;
825 88 : break;
826 :
827 11016567 : case XFS_DAS_LEAF_REMOVE_ATTR:
828 11016567 : error = xfs_attr_leaf_remove_attr(attr);
829 11018310 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
830 : xfs_attr_init_add_state(args));
831 11018139 : break;
832 :
833 603901 : case XFS_DAS_NODE_REMOVE_ATTR:
834 603901 : error = xfs_attr_node_remove_attr(attr);
835 603901 : if (!error)
836 603882 : error = xfs_attr_leaf_shrink(args);
837 603888 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
838 : xfs_attr_init_add_state(args));
839 603885 : break;
840 0 : default:
841 0 : ASSERT(0);
842 0 : break;
843 : }
844 :
845 46159048 : trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
846 46159048 : return error;
847 : }
848 :
849 :
850 : /*
851 : * Return EEXIST if attr is found, or ENOATTR if not
852 : */
853 : static int
854 124800974 : xfs_attr_lookup(
855 : struct xfs_da_args *args)
856 : {
857 124800974 : struct xfs_inode *dp = args->dp;
858 124800974 : struct xfs_buf *bp = NULL;
859 124800974 : struct xfs_da_state *state;
860 124800974 : int error;
861 :
862 124800974 : if (!xfs_inode_hasattr(dp))
863 : return -ENOATTR;
864 :
865 107882434 : if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
866 29694406 : return xfs_attr_sf_findname(args, NULL, NULL);
867 :
868 78188028 : if (xfs_attr_is_leaf(dp)) {
869 76334333 : error = xfs_attr_leaf_hasname(args, &bp);
870 :
871 76349107 : if (bp)
872 76349097 : xfs_trans_brelse(args->trans, bp);
873 :
874 76400254 : return error;
875 : }
876 :
877 1934068 : state = xfs_da_state_alloc(args);
878 1934104 : error = xfs_attr_node_lookup(args, state);
879 1934066 : xfs_da_state_free(state);
880 1934066 : return error;
881 : }
882 :
883 : static int
884 : xfs_attr_intent_init(
885 : struct xfs_da_args *args,
886 : unsigned int op_flags, /* op flag (set or remove) */
887 : struct xfs_attr_intent **attr) /* new xfs_attr_intent */
888 : {
889 :
890 92576000 : struct xfs_attr_intent *new;
891 :
892 92576000 : new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
893 92602194 : new->xattri_op_flags = op_flags;
894 92602194 : new->xattri_da_args = args;
895 :
896 92602194 : *attr = new;
897 92602194 : return 0;
898 : }
899 :
900 : /* Sets an attribute for an inode as a deferred operation */
901 : static int
902 52683829 : xfs_attr_defer_add(
903 : struct xfs_da_args *args)
904 : {
905 52683829 : struct xfs_attr_intent *new;
906 52683829 : int error = 0;
907 :
908 52683829 : error = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_SET, &new);
909 52705205 : if (error)
910 : return error;
911 :
912 52705205 : new->xattri_dela_state = xfs_attr_init_add_state(args);
913 52688076 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
914 52670986 : trace_xfs_attr_defer_add(new->xattri_dela_state, args->dp);
915 :
916 52647248 : return 0;
917 : }
918 :
919 : /* Sets an attribute for an inode as a deferred operation */
920 : static int
921 16833910 : xfs_attr_defer_replace(
922 : struct xfs_da_args *args)
923 : {
924 16833910 : struct xfs_attr_intent *new;
925 16833910 : int error = 0;
926 :
927 16833910 : error = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_REPLACE, &new);
928 16834943 : if (error)
929 : return error;
930 :
931 16834943 : new->xattri_dela_state = xfs_attr_init_replace_state(args);
932 16831706 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
933 16831109 : trace_xfs_attr_defer_replace(new->xattri_dela_state, args->dp);
934 :
935 16825855 : return 0;
936 : }
937 :
938 : /* Removes an attribute for an inode as a deferred operation */
939 : static int
940 23058261 : xfs_attr_defer_remove(
941 : struct xfs_da_args *args)
942 : {
943 :
944 23058261 : struct xfs_attr_intent *new;
945 23058261 : int error;
946 :
947 23058261 : error = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_REMOVE, &new);
948 23062046 : if (error)
949 : return error;
950 :
951 23062046 : new->xattri_dela_state = xfs_attr_init_remove_state(args);
952 23055954 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
953 23051785 : trace_xfs_attr_defer_remove(new->xattri_dela_state, args->dp);
954 :
955 23045874 : return 0;
956 : }
957 :
958 : /*
959 : * Note: If args->value is NULL the attribute will be removed, just like the
960 : * Linux ->setattr API.
961 : */
962 : int
963 125001920 : xfs_attr_set(
964 : struct xfs_da_args *args)
965 : {
966 125001920 : struct xfs_inode *dp = args->dp;
967 125001920 : struct xfs_mount *mp = dp->i_mount;
968 125001920 : struct xfs_trans_res tres;
969 125001920 : bool rsvd = (args->attr_filter & XFS_ATTR_ROOT);
970 125001920 : int error, local;
971 125001920 : int rmt_blks = 0;
972 125001920 : unsigned int total;
973 :
974 250003840 : if (xfs_is_shutdown(dp->i_mount))
975 : return -EIO;
976 :
977 125000927 : error = xfs_qm_dqattach(dp);
978 124947472 : if (error)
979 : return error;
980 :
981 124948112 : args->geo = mp->m_attr_geo;
982 124948112 : args->whichfork = XFS_ATTR_FORK;
983 124948112 : args->hashval = xfs_da_hashname(args->name, args->namelen);
984 :
985 : /*
986 : * We have no control over the attribute names that userspace passes us
987 : * to remove, so we have to allow the name lookup prior to attribute
988 : * removal to fail as well. Preserve the logged flag, since we need
989 : * to pass that through to the logging code.
990 : */
991 124952476 : args->op_flags = XFS_DA_OP_OKNOENT |
992 124952476 : (args->op_flags & XFS_DA_OP_LOGGED);
993 :
994 124952476 : if (args->value) {
995 80054656 : XFS_STATS_INC(mp, xs_attr_set);
996 80065790 : args->total = xfs_attr_calc_size(args, &local);
997 :
998 : /*
999 : * If the inode doesn't have an attribute fork, add one.
1000 : * (inode must not be locked when we call this routine)
1001 : */
1002 80035502 : if (xfs_inode_has_attr_fork(dp) == 0) {
1003 4776220 : int sf_size = sizeof(struct xfs_attr_sf_hdr) +
1004 4776220 : xfs_attr_sf_entsize_byname(args->namelen,
1005 4776220 : args->valuelen);
1006 :
1007 4776220 : error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
1008 4776418 : if (error)
1009 : return error;
1010 : }
1011 :
1012 80016258 : if (!local)
1013 3131 : rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
1014 : } else {
1015 44897820 : XFS_STATS_INC(mp, xs_attr_remove);
1016 44950592 : rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
1017 : }
1018 :
1019 : /*
1020 : * Root fork attributes can use reserved data blocks for this
1021 : * operation if necessary
1022 : */
1023 124944126 : xfs_init_attr_trans(args, &tres, &total);
1024 124816008 : error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
1025 124810781 : if (error)
1026 : return error;
1027 :
1028 124701430 : if (args->value || xfs_inode_hasattr(dp)) {
1029 112904464 : error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
1030 112904464 : XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1031 112879751 : if (error == -EFBIG)
1032 22 : error = xfs_iext_count_upgrade(args->trans, dp,
1033 22 : XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1034 112879751 : if (error)
1035 22 : goto out_trans_cancel;
1036 : }
1037 :
1038 124676695 : error = xfs_attr_lookup(args);
1039 125011427 : switch (error) {
1040 40040695 : case -EEXIST:
1041 : /* if no value, we are performing a remove operation */
1042 40040695 : if (!args->value) {
1043 23062920 : error = xfs_attr_defer_remove(args);
1044 23062920 : break;
1045 : }
1046 : /* Pure create fails if the attr already exists */
1047 16977775 : if (args->attr_flags & XATTR_CREATE)
1048 142570 : goto out_trans_cancel;
1049 :
1050 16835205 : error = xfs_attr_defer_replace(args);
1051 16835205 : break;
1052 84970702 : case -ENOATTR:
1053 : /* Can't remove what isn't there. */
1054 84970702 : if (!args->value)
1055 21930090 : goto out_trans_cancel;
1056 :
1057 : /* Pure replace fails if no existing attr to replace. */
1058 63040612 : if (args->attr_flags & XATTR_REPLACE)
1059 10335634 : goto out_trans_cancel;
1060 :
1061 52704978 : error = xfs_attr_defer_add(args);
1062 52704978 : break;
1063 30 : default:
1064 30 : goto out_trans_cancel;
1065 : }
1066 92509487 : if (error)
1067 0 : goto out_trans_cancel;
1068 :
1069 : /*
1070 : * If this is a synchronous mount, make sure that the
1071 : * transaction goes to disk before returning to the user.
1072 : */
1073 92509487 : if (xfs_has_wsync(mp))
1074 0 : xfs_trans_set_sync(args->trans);
1075 :
1076 92509487 : if (!(args->op_flags & XFS_DA_OP_NOTIME))
1077 92415378 : xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
1078 :
1079 : /*
1080 : * Commit the last in the sequence of transactions.
1081 : */
1082 92420853 : xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
1083 92562671 : error = xfs_trans_commit(args->trans);
1084 124917236 : out_unlock:
1085 124917236 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
1086 124917236 : return error;
1087 :
1088 32408346 : out_trans_cancel:
1089 32408346 : if (args->trans)
1090 32400331 : xfs_trans_cancel(args->trans);
1091 32405060 : goto out_unlock;
1092 : }
1093 :
1094 : /*========================================================================
1095 : * External routines when attribute list is inside the inode
1096 : *========================================================================*/
1097 :
1098 : static inline int xfs_attr_sf_totsize(struct xfs_inode *dp)
1099 : {
1100 24039124 : struct xfs_attr_shortform *sf;
1101 :
1102 24039124 : sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
1103 24039124 : return be16_to_cpu(sf->hdr.totsize);
1104 : }
1105 :
1106 : /*
1107 : * Add a name to the shortform attribute list structure
1108 : * This is the external routine.
1109 : */
1110 : static int
1111 24030714 : xfs_attr_shortform_addname(
1112 : struct xfs_da_args *args)
1113 : {
1114 24030714 : int newsize, forkoff;
1115 24030714 : int error;
1116 :
1117 24030714 : trace_xfs_attr_sf_addname(args);
1118 :
1119 24028435 : error = xfs_attr_shortform_lookup(args);
1120 24048175 : switch (error) {
1121 18708309 : case -ENOATTR:
1122 18708309 : if (args->op_flags & XFS_DA_OP_REPLACE)
1123 : return error;
1124 : break;
1125 5339866 : case -EEXIST:
1126 5339866 : if (!(args->op_flags & XFS_DA_OP_REPLACE))
1127 : return error;
1128 :
1129 5339866 : error = xfs_attr_sf_removename(args);
1130 5341375 : if (error)
1131 : return error;
1132 :
1133 : /*
1134 : * Since we have removed the old attr, clear XFS_DA_OP_REPLACE
1135 : * so that the new attr doesn't fit in shortform format, the
1136 : * leaf format add routine won't trip over the attr not being
1137 : * around.
1138 : */
1139 5341375 : args->op_flags &= ~XFS_DA_OP_REPLACE;
1140 5341375 : break;
1141 : case 0:
1142 : break;
1143 : default:
1144 : return error;
1145 : }
1146 :
1147 24049684 : if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
1148 24049684 : args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
1149 : return -ENOSPC;
1150 :
1151 24039124 : newsize = xfs_attr_sf_totsize(args->dp);
1152 24039124 : newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
1153 :
1154 24039124 : forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
1155 24038118 : if (!forkoff)
1156 : return -ENOSPC;
1157 :
1158 21204351 : xfs_attr_shortform_add(args, forkoff);
1159 21204351 : return 0;
1160 : }
1161 :
1162 :
1163 : /*========================================================================
1164 : * External routines when attribute list is one block
1165 : *========================================================================*/
1166 :
1167 : /* Save the current remote block info and clear the current pointers. */
1168 : static void
1169 : xfs_attr_save_rmt_blk(
1170 : struct xfs_da_args *args)
1171 : {
1172 11244166 : args->blkno2 = args->blkno;
1173 11244166 : args->index2 = args->index;
1174 11244166 : args->rmtblkno2 = args->rmtblkno;
1175 11244166 : args->rmtblkcnt2 = args->rmtblkcnt;
1176 11244166 : args->rmtvaluelen2 = args->rmtvaluelen;
1177 11244166 : args->rmtblkno = 0;
1178 11244166 : args->rmtblkcnt = 0;
1179 11244166 : args->rmtvaluelen = 0;
1180 11244166 : }
1181 :
1182 : /* Set stored info about a remote block */
1183 : static void
1184 11240801 : xfs_attr_restore_rmt_blk(
1185 : struct xfs_da_args *args)
1186 : {
1187 11240801 : args->blkno = args->blkno2;
1188 11240801 : args->index = args->index2;
1189 11240801 : args->rmtblkno = args->rmtblkno2;
1190 11240801 : args->rmtblkcnt = args->rmtblkcnt2;
1191 11240801 : args->rmtvaluelen = args->rmtvaluelen2;
1192 11240801 : }
1193 :
1194 : /*
1195 : * Tries to add an attribute to an inode in leaf form
1196 : *
1197 : * This function is meant to execute as part of a delayed operation and leaves
1198 : * the transaction handling to the caller. On success the attribute is added
1199 : * and the inode and transaction are left dirty. If there is not enough space,
1200 : * the attr data is converted to node format and -ENOSPC is returned. Caller is
1201 : * responsible for handling the dirty inode and transaction or adding the attr
1202 : * in node format.
1203 : */
1204 : STATIC int
1205 47054174 : xfs_attr_leaf_try_add(
1206 : struct xfs_da_args *args)
1207 : {
1208 47054174 : struct xfs_buf *bp;
1209 47054174 : int error;
1210 :
1211 47054174 : error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
1212 47070351 : if (error)
1213 : return error;
1214 :
1215 : /*
1216 : * Look up the xattr name to set the insertion point for the new xattr.
1217 : */
1218 47070715 : error = xfs_attr3_leaf_lookup_int(bp, args);
1219 47090338 : switch (error) {
1220 36064179 : case -ENOATTR:
1221 36064179 : if (args->op_flags & XFS_DA_OP_REPLACE)
1222 0 : goto out_brelse;
1223 : break;
1224 11026159 : case -EEXIST:
1225 11026159 : if (!(args->op_flags & XFS_DA_OP_REPLACE))
1226 0 : goto out_brelse;
1227 :
1228 11026159 : trace_xfs_attr_leaf_replace(args);
1229 : /*
1230 : * Save the existing remote attr state so that the current
1231 : * values reflect the state of the new attribute we are about to
1232 : * add, not the attribute we just found and will remove later.
1233 : */
1234 11023048 : xfs_attr_save_rmt_blk(args);
1235 : break;
1236 : case 0:
1237 : break;
1238 0 : default:
1239 0 : goto out_brelse;
1240 : }
1241 :
1242 47087227 : return xfs_attr3_leaf_add(bp, args);
1243 :
1244 0 : out_brelse:
1245 0 : xfs_trans_brelse(args->trans, bp);
1246 0 : return error;
1247 : }
1248 :
1249 : /*
1250 : * Return EEXIST if attr is found, or ENOATTR if not
1251 : */
1252 : STATIC int
1253 103124391 : xfs_attr_leaf_hasname(
1254 : struct xfs_da_args *args,
1255 : struct xfs_buf **bp)
1256 : {
1257 103124391 : int error = 0;
1258 :
1259 103124391 : error = xfs_attr3_leaf_read(args->trans, args->dp, 0, bp);
1260 103065519 : if (error)
1261 : return error;
1262 :
1263 103067215 : error = xfs_attr3_leaf_lookup_int(*bp, args);
1264 103129675 : if (error != -ENOATTR && error != -EEXIST)
1265 0 : xfs_trans_brelse(args->trans, *bp);
1266 :
1267 : return error;
1268 : }
1269 :
1270 : /*
1271 : * Remove a name from the leaf attribute list structure
1272 : *
1273 : * This leaf block cannot have a "remote" value, we only call this routine
1274 : * if bmap_one_block() says there is only one block (ie: no remote blks).
1275 : */
1276 : STATIC int
1277 17482500 : xfs_attr_leaf_removename(
1278 : struct xfs_da_args *args)
1279 : {
1280 17482500 : struct xfs_inode *dp;
1281 17482500 : struct xfs_buf *bp;
1282 17482500 : int error, forkoff;
1283 :
1284 17482500 : trace_xfs_attr_leaf_removename(args);
1285 :
1286 : /*
1287 : * Remove the attribute.
1288 : */
1289 17473788 : dp = args->dp;
1290 :
1291 17473788 : error = xfs_attr_leaf_hasname(args, &bp);
1292 17501627 : if (error == -ENOATTR) {
1293 33 : xfs_trans_brelse(args->trans, bp);
1294 33 : if (args->op_flags & XFS_DA_OP_RECOVERY)
1295 : return 0;
1296 0 : return error;
1297 17501594 : } else if (error != -EEXIST)
1298 : return error;
1299 :
1300 17501005 : xfs_attr3_leaf_remove(bp, args);
1301 :
1302 : /*
1303 : * If the result is small enough, shrink it all into the inode.
1304 : */
1305 17498369 : forkoff = xfs_attr_shortform_allfit(bp, dp);
1306 17495287 : if (forkoff)
1307 1160981 : return xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1308 : /* bp is gone due to xfs_da_shrink_inode */
1309 :
1310 : return 0;
1311 : }
1312 :
1313 : /*
1314 : * Look up a name in a leaf attribute list structure.
1315 : *
1316 : * This leaf block cannot have a "remote" value, we only call this routine
1317 : * if bmap_one_block() says there is only one block (ie: no remote blks).
1318 : *
1319 : * Returns 0 on successful retrieval, otherwise an error.
1320 : */
1321 : STATIC int
1322 9332393 : xfs_attr_leaf_get(xfs_da_args_t *args)
1323 : {
1324 9332393 : struct xfs_buf *bp;
1325 9332393 : int error;
1326 :
1327 9332393 : trace_xfs_attr_leaf_get(args);
1328 :
1329 9331900 : error = xfs_attr_leaf_hasname(args, &bp);
1330 :
1331 9332874 : if (error == -ENOATTR) {
1332 3777366 : xfs_trans_brelse(args->trans, bp);
1333 3777366 : return error;
1334 5555508 : } else if (error != -EEXIST)
1335 : return error;
1336 :
1337 :
1338 5555290 : error = xfs_attr3_leaf_getvalue(bp, args);
1339 5554958 : xfs_trans_brelse(args->trans, bp);
1340 5554958 : return error;
1341 : }
1342 :
1343 : /* Return EEXIST if attr is found, or ENOATTR if not. */
1344 : STATIC int
1345 3816744 : xfs_attr_node_lookup(
1346 : struct xfs_da_args *args,
1347 : struct xfs_da_state *state)
1348 : {
1349 3816744 : int retval, error;
1350 :
1351 : /*
1352 : * Search to see if name exists, and get back a pointer to it.
1353 : */
1354 3816744 : error = xfs_da3_node_lookup_int(state, &retval);
1355 3816797 : if (error)
1356 : return error;
1357 :
1358 3816777 : return retval;
1359 : }
1360 :
1361 : /*========================================================================
1362 : * External routines when attribute list size > geo->blksize
1363 : *========================================================================*/
1364 :
1365 : STATIC int
1366 1274081 : xfs_attr_node_addname_find_attr(
1367 : struct xfs_attr_intent *attr)
1368 : {
1369 1274081 : struct xfs_da_args *args = attr->xattri_da_args;
1370 1274081 : int error;
1371 :
1372 : /*
1373 : * Search to see if name already exists, and get back a pointer
1374 : * to where it should go.
1375 : */
1376 1274081 : xfs_attr_item_init_da_state(attr);
1377 1274100 : error = xfs_attr_node_lookup(args, attr->xattri_da_state);
1378 1274145 : switch (error) {
1379 1053025 : case -ENOATTR:
1380 1053025 : if (args->op_flags & XFS_DA_OP_REPLACE)
1381 0 : goto error;
1382 : break;
1383 221120 : case -EEXIST:
1384 221120 : if (!(args->op_flags & XFS_DA_OP_REPLACE))
1385 0 : goto error;
1386 :
1387 :
1388 221120 : trace_xfs_attr_node_replace(args);
1389 : /*
1390 : * Save the existing remote attr state so that the current
1391 : * values reflect the state of the new attribute we are about to
1392 : * add, not the attribute we just found and will remove later.
1393 : */
1394 221118 : xfs_attr_save_rmt_blk(args);
1395 : break;
1396 : case 0:
1397 : break;
1398 0 : default:
1399 0 : goto error;
1400 : }
1401 :
1402 : return 0;
1403 0 : error:
1404 0 : if (attr->xattri_da_state) {
1405 0 : xfs_da_state_free(attr->xattri_da_state);
1406 0 : attr->xattri_da_state = NULL;
1407 : }
1408 : return error;
1409 : }
1410 :
1411 : /*
1412 : * Add a name to a Btree-format attribute list.
1413 : *
1414 : * This will involve walking down the Btree, and may involve splitting
1415 : * leaf nodes and even splitting intermediate nodes up to and including
1416 : * the root node (a special case of an intermediate node).
1417 : */
1418 : static int
1419 1274102 : xfs_attr_node_try_addname(
1420 : struct xfs_attr_intent *attr)
1421 : {
1422 1274102 : struct xfs_da_state *state = attr->xattri_da_state;
1423 1274102 : struct xfs_da_state_blk *blk;
1424 1274102 : int error;
1425 :
1426 1274102 : trace_xfs_attr_node_addname(state->args);
1427 :
1428 1274077 : blk = &state->path.blk[state->path.active-1];
1429 1274076 : ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1430 :
1431 1274076 : error = xfs_attr3_leaf_add(blk->bp, state->args);
1432 1274113 : if (error == -ENOSPC) {
1433 88864 : if (state->path.active == 1) {
1434 : /*
1435 : * Its really a single leaf node, but it had
1436 : * out-of-line values so it looked like it *might*
1437 : * have been a b-tree. Let the caller deal with this.
1438 : */
1439 0 : goto out;
1440 : }
1441 :
1442 : /*
1443 : * Split as many Btree elements as required.
1444 : * This code tracks the new and old attr's location
1445 : * in the index/blkno/rmtblkno/rmtblkcnt fields and
1446 : * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
1447 : */
1448 88864 : error = xfs_da3_split(state);
1449 88864 : if (error)
1450 11 : goto out;
1451 : } else {
1452 : /*
1453 : * Addition succeeded, update Btree hashvals.
1454 : */
1455 1185249 : xfs_da3_fixhashpath(state, &state->path);
1456 : }
1457 :
1458 1274134 : out:
1459 1274134 : xfs_da_state_free(state);
1460 1274116 : attr->xattri_da_state = NULL;
1461 1274116 : return error;
1462 : }
1463 :
1464 : static int
1465 603892 : xfs_attr_node_removename(
1466 : struct xfs_da_args *args,
1467 : struct xfs_da_state *state)
1468 : {
1469 603892 : struct xfs_da_state_blk *blk;
1470 603892 : int retval;
1471 :
1472 : /*
1473 : * Remove the name and update the hashvals in the tree.
1474 : */
1475 603892 : blk = &state->path.blk[state->path.active-1];
1476 603892 : ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1477 603892 : retval = xfs_attr3_leaf_remove(blk->bp, args);
1478 603897 : xfs_da3_fixhashpath(state, &state->path);
1479 :
1480 603894 : return retval;
1481 : }
1482 :
1483 : static int
1484 603890 : xfs_attr_node_remove_attr(
1485 : struct xfs_attr_intent *attr)
1486 : {
1487 603890 : struct xfs_da_args *args = attr->xattri_da_args;
1488 603890 : struct xfs_da_state *state = xfs_da_state_alloc(args);
1489 603910 : int retval = 0;
1490 603910 : int error = 0;
1491 :
1492 : /*
1493 : * The attr we are removing has already been marked incomplete, so
1494 : * we need to set the filter appropriately to re-find the "old"
1495 : * attribute entry after any split ops.
1496 : */
1497 603910 : args->attr_filter |= XFS_ATTR_INCOMPLETE;
1498 603910 : error = xfs_da3_node_lookup_int(state, &retval);
1499 603900 : if (error)
1500 0 : goto out;
1501 :
1502 603900 : error = xfs_attr_node_removename(args, state);
1503 :
1504 : /*
1505 : * Check to see if the tree needs to be collapsed.
1506 : */
1507 603886 : if (retval && (state->path.active > 1)) {
1508 603788 : error = xfs_da3_join(state);
1509 603784 : if (error)
1510 10 : goto out;
1511 : }
1512 603872 : retval = error = 0;
1513 :
1514 603882 : out:
1515 603882 : xfs_da_state_free(state);
1516 603896 : if (error)
1517 : return error;
1518 603886 : return retval;
1519 : }
1520 :
1521 : /*
1522 : * Retrieve the attribute data from a node attribute list.
1523 : *
1524 : * This routine gets called for any attribute fork that has more than one
1525 : * block, ie: both true Btree attr lists and for single-leaf-blocks with
1526 : * "remote" values taking up more blocks.
1527 : *
1528 : * Returns 0 on successful retrieval, otherwise an error.
1529 : */
1530 : STATIC int
1531 225812 : xfs_attr_node_get(
1532 : struct xfs_da_args *args)
1533 : {
1534 225812 : struct xfs_da_state *state;
1535 225812 : struct xfs_da_state_blk *blk;
1536 225812 : int i;
1537 225812 : int error;
1538 :
1539 225812 : trace_xfs_attr_node_get(args);
1540 :
1541 : /*
1542 : * Search to see if name exists, and get back a pointer to it.
1543 : */
1544 225810 : state = xfs_da_state_alloc(args);
1545 225812 : error = xfs_attr_node_lookup(args, state);
1546 225812 : if (error != -EEXIST)
1547 74829 : goto out_release;
1548 :
1549 : /*
1550 : * Get the value, local or "remote"
1551 : */
1552 150983 : blk = &state->path.blk[state->path.active - 1];
1553 150982 : error = xfs_attr3_leaf_getvalue(blk->bp, args);
1554 :
1555 : /*
1556 : * If not in a transaction, we have to release all the buffers.
1557 : */
1558 225811 : out_release:
1559 676375 : for (i = 0; i < state->path.active; i++) {
1560 450563 : xfs_trans_brelse(args->trans, state->path.blk[i].bp);
1561 450565 : state->path.blk[i].bp = NULL;
1562 : }
1563 :
1564 225812 : xfs_da_state_free(state);
1565 225813 : return error;
1566 : }
1567 :
1568 : /* Returns true if the attribute entry name is valid. */
1569 : bool
1570 681164078 : xfs_attr_namecheck(
1571 : const void *name,
1572 : size_t length)
1573 : {
1574 : /*
1575 : * MAXNAMELEN includes the trailing null, but (name/length) leave it
1576 : * out, so use >= for the length check.
1577 : */
1578 681164078 : if (length >= MAXNAMELEN)
1579 : return false;
1580 :
1581 : /* There shouldn't be any nulls here */
1582 1362328156 : return !memchr(name, 0, length);
1583 : }
1584 :
1585 : int __init
1586 50 : xfs_attr_intent_init_cache(void)
1587 : {
1588 50 : xfs_attr_intent_cache = kmem_cache_create("xfs_attr_intent",
1589 : sizeof(struct xfs_attr_intent),
1590 : 0, 0, NULL);
1591 :
1592 50 : return xfs_attr_intent_cache != NULL ? 0 : -ENOMEM;
1593 : }
1594 :
1595 : void
1596 49 : xfs_attr_intent_destroy_cache(void)
1597 : {
1598 49 : kmem_cache_destroy(xfs_attr_intent_cache);
1599 49 : xfs_attr_intent_cache = NULL;
1600 49 : }
|