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