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 6487815318 : xfs_inode_hasattr(
69 : struct xfs_inode *ip)
70 : {
71 6551212943 : if (!xfs_inode_has_attr_fork(ip))
72 : return 0;
73 7002531582 : if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
74 450802294 : ip->i_af.if_nextents == 0)
75 79850805 : 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 550845783 : xfs_attr_is_leaf(
85 : struct xfs_inode *ip)
86 : {
87 550845783 : struct xfs_ifork *ifp = &ip->i_af;
88 550845783 : struct xfs_iext_cursor icur;
89 550845783 : struct xfs_bmbt_irec imap;
90 :
91 550845783 : if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
92 : return false;
93 :
94 541668378 : xfs_iext_first(ifp, &icur);
95 541689285 : xfs_iext_get_extent(ifp, &icur, &imap);
96 542658355 : 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 270537951 : xfs_attr_get_ilocked(
226 : struct xfs_da_args *args)
227 : {
228 270537951 : ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
229 :
230 270226994 : if (!xfs_inode_hasattr(args->dp))
231 : return -ENOATTR;
232 :
233 268965432 : if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
234 251183031 : return xfs_attr_shortform_getvalue(args);
235 17782401 : if (xfs_attr_is_leaf(args->dp))
236 17112445 : return xfs_attr_leaf_get(args);
237 683472 : 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 69497376 : xfs_attr_get(
258 : struct xfs_da_args *args)
259 : {
260 69497376 : uint lock_mode;
261 69497376 : int error;
262 :
263 69497376 : XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
264 :
265 138759136 : if (xfs_is_shutdown(args->dp->i_mount))
266 : return -EIO;
267 :
268 69378657 : args->geo = args->dp->i_mount->m_attr_geo;
269 69378657 : args->whichfork = XFS_ATTR_FORK;
270 69378657 : args->hashval = xfs_da_hashname(args->name, args->namelen);
271 :
272 : /* Entirely possible to look up a name which doesn't exist */
273 69383448 : args->op_flags = XFS_DA_OP_OKNOENT;
274 :
275 69383448 : lock_mode = xfs_ilock_attr_map_shared(args->dp);
276 69391397 : error = xfs_attr_get_ilocked(args);
277 69370960 : xfs_iunlock(args->dp, lock_mode);
278 :
279 69370960 : return error;
280 : }
281 :
282 : /*
283 : * Calculate how many blocks we need for the new attribute,
284 : */
285 : int
286 126725940 : xfs_attr_calc_size(
287 : struct xfs_da_args *args,
288 : int *local)
289 : {
290 126725940 : struct xfs_mount *mp = args->dp->i_mount;
291 126725940 : int size;
292 126725940 : 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 126725940 : size = xfs_attr_leaf_newentsize(args, local);
299 126716710 : nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
300 126716710 : if (*local) {
301 126713397 : if (size > (args->geo->blksize / 2)) {
302 : /* Double split possible */
303 11 : 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 3313 : uint dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
311 3313 : nblks += dblocks;
312 3313 : nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
313 : }
314 :
315 126716710 : return nblks;
316 : }
317 :
318 : /* Initialize transaction reservation for attr operations */
319 : void
320 190013675 : xfs_init_attr_trans(
321 : struct xfs_da_args *args,
322 : struct xfs_trans_res *tres,
323 : unsigned int *total)
324 : {
325 190013675 : struct xfs_mount *mp = args->dp->i_mount;
326 :
327 190013675 : if (args->value) {
328 126721992 : tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
329 126721992 : M_RES(mp)->tr_attrsetrt.tr_logres *
330 126721992 : args->total;
331 126721992 : tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
332 126721992 : tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
333 126721992 : *total = args->total;
334 : } else {
335 63291683 : *tres = M_RES(mp)->tr_attrrm;
336 63291683 : *total = XFS_ATTRRM_SPACE_RES(mp);
337 : }
338 190013675 : }
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 199664250 : xfs_attr_try_sf_addname(
347 : struct xfs_inode *dp,
348 : struct xfs_da_args *args)
349 : {
350 :
351 199664250 : int error;
352 :
353 : /*
354 : * Build initial attribute list (if required).
355 : */
356 199664250 : if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
357 98650909 : xfs_attr_shortform_create(args);
358 :
359 199869430 : error = xfs_attr_shortform_addname(args);
360 199761883 : 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 195081820 : if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
368 195077906 : xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
369 :
370 195057400 : if (xfs_has_wsync(dp->i_mount))
371 708 : xfs_trans_set_sync(args->trans);
372 :
373 : return error;
374 : }
375 :
376 : static int
377 199669665 : xfs_attr_sf_addname(
378 : struct xfs_attr_intent *attr)
379 : {
380 199669665 : struct xfs_da_args *args = attr->xattri_da_args;
381 199669665 : struct xfs_inode *dp = args->dp;
382 199669665 : int error = 0;
383 :
384 199669665 : error = xfs_attr_try_sf_addname(dp, args);
385 199725990 : if (error != -ENOSPC) {
386 195046015 : ASSERT(!error || error == -EEXIST);
387 195046015 : attr->xattri_dela_state = XFS_DAS_DONE;
388 195046015 : 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 4679975 : error = xfs_attr_shortform_to_leaf(args);
396 4680191 : if (error)
397 : return error;
398 :
399 4680184 : attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
400 199726199 : out:
401 199726199 : trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
402 199726199 : 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 251163941 : xfs_attr_complete_op(
418 : struct xfs_attr_intent *attr,
419 : enum xfs_delattr_state replace_state)
420 : {
421 251163941 : struct xfs_da_args *args = attr->xattri_da_args;
422 251163941 : bool do_replace = args->op_flags & XFS_DA_OP_REPLACE;
423 :
424 251163941 : args->op_flags &= ~XFS_DA_OP_REPLACE;
425 251163941 : if (!do_replace)
426 : return XFS_DAS_DONE;
427 :
428 75582339 : args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
429 75582339 : 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 57239629 : ASSERT(args->new_namelen > 0);
437 :
438 57239629 : args->name = args->new_name;
439 57239629 : args->namelen = args->new_namelen;
440 57239629 : args->hashval = xfs_da_hashname(args->name, args->namelen);
441 57239524 : args->value = args->new_value;
442 57239524 : args->valuelen = args->new_valuelen;
443 57239524 : return replace_state;
444 : }
445 :
446 : static int
447 76960479 : xfs_attr_leaf_addname(
448 : struct xfs_attr_intent *attr)
449 : {
450 76960479 : struct xfs_da_args *args = attr->xattri_da_args;
451 76960479 : int error;
452 :
453 76960479 : 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 77009153 : error = xfs_attr_leaf_try_add(args);
460 :
461 77008538 : if (error == -ENOSPC) {
462 41036 : error = xfs_attr3_leaf_to_node(args);
463 41036 : 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 41025 : attr->xattri_dela_state = XFS_DAS_NODE_ADD;
471 41025 : goto out;
472 : }
473 76967502 : 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 76967502 : if (args->rmtblkno)
482 2862 : attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
483 : else
484 76964640 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
485 : XFS_DAS_LEAF_REPLACE);
486 76930141 : out:
487 76930141 : trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
488 76930141 : 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 2160705 : xfs_attr_node_addname(
500 : struct xfs_attr_intent *attr)
501 : {
502 2160705 : struct xfs_da_args *args = attr->xattri_da_args;
503 2160705 : int error;
504 :
505 2160705 : error = xfs_attr_node_addname_find_attr(attr);
506 2160787 : if (error)
507 : return error;
508 :
509 2160769 : error = xfs_attr_node_try_addname(attr);
510 2160642 : 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 2160642 : if (error)
521 : return error;
522 :
523 2160631 : if (args->rmtblkno)
524 101 : attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
525 : else
526 2160530 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
527 : XFS_DAS_NODE_REPLACE);
528 2160638 : out:
529 2160638 : trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
530 2160638 : return error;
531 : }
532 :
533 : static int
534 2963 : xfs_attr_rmtval_alloc(
535 : struct xfs_attr_intent *attr)
536 : {
537 2963 : struct xfs_da_args *args = attr->xattri_da_args;
538 2963 : 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 2963 : if (attr->xattri_blkcnt > 0) {
547 2963 : error = xfs_attr_rmtval_set_blk(attr);
548 2963 : if (error)
549 : return error;
550 : /* Roll the transaction only if there is more to allocate. */
551 2963 : if (attr->xattri_blkcnt > 0)
552 0 : goto out;
553 : }
554 :
555 2963 : error = xfs_attr_rmtval_set_value(args);
556 2963 : if (error)
557 : return error;
558 :
559 5926 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
560 2963 : ++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 2963 : if (attr->xattri_dela_state == XFS_DAS_DONE)
567 2953 : error = xfs_attr3_leaf_clearflag(args);
568 10 : out:
569 2963 : trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
570 2963 : 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 688950 : 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 688950 : error = xfs_attr_fillstate(state);
590 688950 : if (error)
591 : return error;
592 :
593 : /*
594 : * Mark the attribute as INCOMPLETE
595 : */
596 688950 : 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 2849571 : xfs_attr_item_init_da_state(
602 : struct xfs_attr_intent *attr)
603 : {
604 2849571 : struct xfs_da_args *args = attr->xattri_da_args;
605 :
606 2849571 : if (!attr->xattri_da_state)
607 2843363 : attr->xattri_da_state = xfs_da_state_alloc(args);
608 : else
609 6208 : xfs_da_state_reset(attr->xattri_da_state, args);
610 2849674 : }
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 688977 : int xfs_attr_node_removename_setup(
619 : struct xfs_attr_intent *attr)
620 : {
621 688977 : struct xfs_da_args *args = attr->xattri_da_args;
622 688977 : struct xfs_da_state *state;
623 688977 : int error;
624 :
625 688977 : xfs_attr_item_init_da_state(attr);
626 688974 : error = xfs_attr_node_lookup(args, attr->xattri_da_state);
627 688987 : if (error != -EEXIST)
628 33 : goto out;
629 688954 : error = 0;
630 :
631 688954 : state = attr->xattri_da_state;
632 688954 : ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
633 688952 : ASSERT(state->path.blk[state->path.active - 1].magic ==
634 : XFS_ATTR_LEAF_MAGIC);
635 :
636 688950 : error = xfs_attr_leaf_mark_incomplete(args, state);
637 688937 : if (error)
638 0 : goto out;
639 688937 : if (args->rmtblkno > 0)
640 68 : error = xfs_attr_rmtval_invalidate(args);
641 688869 : out:
642 688970 : if (error) {
643 33 : xfs_da_state_free(attr->xattri_da_state);
644 33 : attr->xattri_da_state = NULL;
645 : }
646 :
647 688970 : 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 17555110 : xfs_attr_leaf_remove_attr(
657 : struct xfs_attr_intent *attr)
658 : {
659 17555110 : struct xfs_da_args *args = attr->xattri_da_args;
660 17555110 : struct xfs_inode *dp = args->dp;
661 17555110 : struct xfs_buf *bp = NULL;
662 17555110 : int forkoff;
663 17555110 : int error;
664 :
665 17555110 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
666 : args->blkno, &bp);
667 17556138 : if (error)
668 : return error;
669 :
670 17556099 : xfs_attr3_leaf_remove(bp, args);
671 :
672 17555179 : forkoff = xfs_attr_shortform_allfit(bp, dp);
673 17555776 : if (forkoff)
674 411129 : 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 1047041 : xfs_attr_leaf_shrink(
687 : struct xfs_da_args *args)
688 : {
689 1047041 : struct xfs_inode *dp = args->dp;
690 1047041 : struct xfs_buf *bp;
691 1047041 : int forkoff;
692 1047041 : int error;
693 :
694 1047041 : if (!xfs_attr_is_leaf(dp))
695 : return 0;
696 :
697 117 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
698 117 : if (error)
699 : return error;
700 :
701 117 : forkoff = xfs_attr_shortform_allfit(bp, dp);
702 117 : if (forkoff) {
703 56 : error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
704 : /* bp is gone due to xfs_da_shrink_inode */
705 : } else {
706 61 : 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 469544133 : xfs_attr_set_iter(
722 : struct xfs_attr_intent *attr)
723 : {
724 469544133 : struct xfs_da_args *args = attr->xattri_da_args;
725 469544133 : int error = 0;
726 :
727 : /* State machine switch */
728 : next_state:
729 487458098 : switch (attr->xattri_dela_state) {
730 0 : case XFS_DAS_UNINIT:
731 0 : ASSERT(0);
732 0 : return -EFSCORRUPTED;
733 199720262 : case XFS_DAS_SF_ADD:
734 199720262 : return xfs_attr_sf_addname(attr);
735 76995733 : case XFS_DAS_LEAF_ADD:
736 76995733 : return xfs_attr_leaf_addname(attr);
737 2160730 : case XFS_DAS_NODE_ADD:
738 2160730 : return xfs_attr_node_addname(attr);
739 :
740 123107278 : case XFS_DAS_SF_REMOVE:
741 123107278 : error = xfs_attr_sf_removename(args);
742 123125989 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
743 : xfs_attr_init_add_state(args));
744 123092570 : break;
745 30351993 : case XFS_DAS_LEAF_REMOVE:
746 30351993 : error = xfs_attr_leaf_removename(args);
747 30358470 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
748 : xfs_attr_init_add_state(args));
749 30349242 : break;
750 688974 : case XFS_DAS_NODE_REMOVE:
751 688974 : error = xfs_attr_node_removename_setup(attr);
752 688958 : if (error == -ENOATTR &&
753 33 : (args->op_flags & XFS_DA_OP_RECOVERY)) {
754 33 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
755 : xfs_attr_init_add_state(args));
756 33 : error = 0;
757 33 : break;
758 : }
759 688925 : if (error)
760 : return error;
761 688925 : attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
762 688925 : if (args->rmtblkno == 0)
763 688853 : attr->xattri_dela_state++;
764 : break;
765 :
766 2963 : case XFS_DAS_LEAF_SET_RMT:
767 : case XFS_DAS_NODE_SET_RMT:
768 2963 : error = xfs_attr_rmtval_find_space(attr);
769 2963 : if (error)
770 0 : return error;
771 2963 : attr->xattri_dela_state++;
772 2963 : fallthrough;
773 :
774 2963 : case XFS_DAS_LEAF_ALLOC_RMT:
775 : case XFS_DAS_NODE_ALLOC_RMT:
776 2963 : error = xfs_attr_rmtval_alloc(attr);
777 2963 : if (error)
778 0 : return error;
779 2963 : if (attr->xattri_dela_state == XFS_DAS_DONE)
780 : break;
781 10 : goto next_state;
782 :
783 17912971 : 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 17912971 : error = xfs_attr3_leaf_flipflags(args);
791 17912750 : 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 17912750 : attr->xattri_dela_state++;
798 17912750 : break;
799 :
800 17914843 : 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 17914843 : xfs_attr_restore_rmt_blk(args);
810 17913955 : if (args->rmtblkno) {
811 20 : error = xfs_attr_rmtval_invalidate(args);
812 20 : if (error)
813 0 : return error;
814 : } else {
815 17913935 : attr->xattri_dela_state++;
816 : }
817 :
818 17913955 : attr->xattri_dela_state++;
819 17913955 : goto next_state;
820 :
821 88 : case XFS_DAS_LEAF_REMOVE_RMT:
822 : case XFS_DAS_NODE_REMOVE_RMT:
823 88 : error = xfs_attr_rmtval_remove(attr);
824 88 : if (error == -EAGAIN) {
825 : error = 0;
826 : break;
827 : }
828 88 : 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 88 : attr->xattri_dela_state++;
840 88 : break;
841 :
842 17555193 : case XFS_DAS_LEAF_REMOVE_ATTR:
843 17555193 : error = xfs_attr_leaf_remove_attr(attr);
844 17555403 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
845 : xfs_attr_init_add_state(args));
846 17553261 : break;
847 :
848 1047070 : case XFS_DAS_NODE_REMOVE_ATTR:
849 1047070 : error = xfs_attr_node_remove_attr(attr);
850 1047067 : if (!error)
851 1047041 : error = xfs_attr_leaf_shrink(args);
852 1047072 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
853 : xfs_attr_init_add_state(args));
854 1047053 : break;
855 0 : default:
856 0 : ASSERT(0);
857 0 : break;
858 : }
859 :
860 190646875 : trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
861 190646875 : return error;
862 : }
863 :
864 :
865 : /*
866 : * Return EEXIST if attr is found, or ENOATTR if not
867 : */
868 : static int
869 189814031 : xfs_attr_lookup(
870 : struct xfs_da_args *args)
871 : {
872 189814031 : struct xfs_inode *dp = args->dp;
873 189814031 : struct xfs_buf *bp = NULL;
874 189814031 : struct xfs_da_state *state;
875 189814031 : int error;
876 :
877 189814031 : if (!xfs_inode_hasattr(dp))
878 : return -ENOATTR;
879 :
880 184239616 : if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
881 58901610 : return xfs_attr_sf_findname(args, NULL, NULL);
882 :
883 125338006 : if (xfs_attr_is_leaf(dp)) {
884 122314164 : error = xfs_attr_leaf_hasname(args, &bp);
885 :
886 122317360 : if (bp)
887 122317350 : xfs_trans_brelse(args->trans, bp);
888 :
889 122386928 : return error;
890 : }
891 :
892 3103680 : state = xfs_da_state_alloc(args);
893 3103738 : error = xfs_attr_node_lookup(args, state);
894 3103683 : xfs_da_state_free(state);
895 3103683 : 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 370789749 : struct xfs_attr_intent *new;
906 :
907 0 : new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
908 370759814 : new->xattri_op_flags = op_flags;
909 370759814 : new->xattri_da_args = args;
910 :
911 370759814 : *attr = new;
912 370759814 : return 0;
913 : }
914 :
915 : /* Sets an attribute for an inode as a deferred operation */
916 : int
917 191410611 : xfs_attr_defer_add(
918 : struct xfs_da_args *args)
919 : {
920 191410611 : struct xfs_attr_intent *new;
921 191410611 : int op_flag = XFS_ATTRI_OP_FLAGS_SET;
922 191410611 : int error = 0;
923 :
924 191410611 : if (args->op_flags & XFS_DA_OP_NVLOOKUP)
925 110915589 : op_flag = XFS_ATTRI_OP_FLAGS_NVSET;
926 :
927 191410611 : error = xfs_attr_intent_init(args, op_flag, &new);
928 191386845 : if (error)
929 : return error;
930 :
931 191386845 : new->xattri_dela_state = xfs_attr_init_add_state(args);
932 191329919 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
933 191278528 : trace_xfs_attr_defer_add(new->xattri_dela_state, args->dp);
934 :
935 191232295 : return 0;
936 : }
937 :
938 : /* Sets an attribute for an inode as a deferred operation */
939 : int
940 82889706 : xfs_attr_defer_replace(
941 : struct xfs_da_args *args)
942 : {
943 82889706 : struct xfs_attr_intent *new;
944 82889706 : int op_flag = XFS_ATTRI_OP_FLAGS_REPLACE;
945 82889706 : int error = 0;
946 :
947 82889706 : if (args->op_flags & XFS_DA_OP_NVLOOKUP)
948 57239884 : op_flag = XFS_ATTRI_OP_FLAGS_NVREPLACE;
949 :
950 82889706 : error = xfs_attr_intent_init(args, op_flag, &new);
951 82888470 : if (error)
952 : return error;
953 :
954 82888470 : new->xattri_dela_state = xfs_attr_init_replace_state(args);
955 82886928 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
956 82884525 : trace_xfs_attr_defer_replace(new->xattri_dela_state, args->dp);
957 :
958 82882816 : return 0;
959 : }
960 :
961 : /* Removes an attribute for an inode as a deferred operation */
962 : int
963 96489432 : xfs_attr_defer_remove(
964 : struct xfs_da_args *args)
965 : {
966 :
967 96489432 : struct xfs_attr_intent *new;
968 96489432 : int op_flag = XFS_ATTRI_OP_FLAGS_REMOVE;
969 96489432 : int error;
970 :
971 96489432 : if (args->op_flags & XFS_DA_OP_NVLOOKUP)
972 61102376 : op_flag = XFS_ATTRI_OP_FLAGS_NVREMOVE;
973 :
974 96489432 : error = xfs_attr_intent_init(args, op_flag, &new);
975 96484499 : if (error)
976 : return error;
977 :
978 96484499 : new->xattri_dela_state = xfs_attr_init_remove_state(args);
979 96471272 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
980 96474428 : trace_xfs_attr_defer_remove(new->xattri_dela_state, args->dp);
981 :
982 96470474 : 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 190064256 : xfs_attr_set(
991 : struct xfs_da_args *args)
992 : {
993 190064256 : struct xfs_inode *dp = args->dp;
994 190064256 : struct xfs_mount *mp = dp->i_mount;
995 190064256 : struct xfs_trans_res tres;
996 190064256 : bool rsvd = (args->attr_filter & (XFS_ATTR_ROOT |
997 : XFS_ATTR_PARENT));
998 190064256 : bool is_remove = args->op_flags & XFS_DA_OP_REMOVE;
999 190064256 : int error, local;
1000 190064256 : int rmt_blks = 0;
1001 190064256 : unsigned int total;
1002 :
1003 380128512 : if (xfs_is_shutdown(dp->i_mount))
1004 : return -EIO;
1005 :
1006 190063265 : error = xfs_qm_dqattach(dp);
1007 189980282 : if (error)
1008 : return error;
1009 :
1010 189980231 : args->geo = mp->m_attr_geo;
1011 189980231 : args->whichfork = XFS_ATTR_FORK;
1012 189980231 : 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 190010103 : args->op_flags &= (XFS_DA_OP_LOGGED | XFS_DA_OP_NVLOOKUP);
1021 190010103 : args->op_flags |= XFS_DA_OP_OKNOENT;
1022 :
1023 190010103 : if (!is_remove) {
1024 126715087 : XFS_STATS_INC(mp, xs_attr_set);
1025 126732958 : 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 126718206 : if (xfs_inode_has_attr_fork(dp) == 0) {
1032 4494514 : int sf_size = sizeof(struct xfs_attr_sf_hdr) +
1033 4494514 : xfs_attr_sf_entsize_byname(args->namelen,
1034 4494514 : args->valuelen);
1035 :
1036 4494514 : error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
1037 4494814 : if (error)
1038 : return error;
1039 : }
1040 :
1041 126718193 : if (!local)
1042 3258 : rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
1043 : } else {
1044 63295016 : XFS_STATS_INC(mp, xs_attr_remove);
1045 63308895 : 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 190018653 : xfs_init_attr_trans(args, &tres, &total);
1053 189932705 : error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
1054 190194470 : if (error)
1055 : return error;
1056 :
1057 190075981 : if (!is_remove || xfs_inode_hasattr(dp)) {
1058 189074025 : error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
1059 189074025 : XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1060 188675189 : if (error == -EFBIG)
1061 22 : error = xfs_iext_count_upgrade(args->trans, dp,
1062 22 : XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1063 188675189 : if (error)
1064 22 : goto out_trans_cancel;
1065 : }
1066 :
1067 189677123 : error = xfs_attr_lookup(args);
1068 189924470 : switch (error) {
1069 61263011 : case -EEXIST:
1070 : /* if no value, we are performing a remove operation */
1071 61263011 : if (is_remove) {
1072 35391108 : error = xfs_attr_defer_remove(args);
1073 35391108 : break;
1074 : }
1075 : /* Pure create fails if the attr already exists */
1076 25871903 : if (args->attr_flags & XATTR_CREATE)
1077 222183 : goto out_trans_cancel;
1078 :
1079 25649720 : error = xfs_attr_defer_replace(args);
1080 25649720 : break;
1081 128661429 : case -ENOATTR:
1082 : /* Can't remove what isn't there. */
1083 128661429 : if (is_remove)
1084 27841557 : goto out_trans_cancel;
1085 :
1086 : /* Pure replace fails if no existing attr to replace. */
1087 100819872 : if (args->attr_flags & XATTR_REPLACE)
1088 15861638 : goto out_trans_cancel;
1089 :
1090 84958234 : error = xfs_attr_defer_add(args);
1091 84958234 : break;
1092 30 : default:
1093 30 : goto out_trans_cancel;
1094 : }
1095 145946410 : 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 145946410 : if (xfs_has_wsync(mp))
1103 0 : xfs_trans_set_sync(args->trans);
1104 :
1105 145946410 : if (!(args->op_flags & XFS_DA_OP_NOTIME))
1106 145870694 : xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
1107 :
1108 : /*
1109 : * Commit the last in the sequence of transactions.
1110 : */
1111 145690662 : xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
1112 145906807 : error = xfs_trans_commit(args->trans);
1113 190017145 : out_unlock:
1114 190017145 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
1115 190017145 : return error;
1116 :
1117 43925430 : out_trans_cancel:
1118 43925430 : if (args->trans)
1119 43995839 : xfs_trans_cancel(args->trans);
1120 44029217 : goto out_unlock;
1121 : }
1122 :
1123 : /*========================================================================
1124 : * External routines when attribute list is inside the inode
1125 : *========================================================================*/
1126 :
1127 4271893 : int xfs_attr_sf_totsize(struct xfs_inode *dp)
1128 : {
1129 203984509 : struct xfs_attr_shortform *sf;
1130 :
1131 203984509 : sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
1132 203984509 : 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 199849504 : xfs_attr_shortform_addname(
1141 : struct xfs_da_args *args)
1142 : {
1143 199849504 : int newsize, forkoff;
1144 199849504 : int error;
1145 :
1146 199849504 : trace_xfs_attr_sf_addname(args);
1147 :
1148 199826911 : error = xfs_attr_shortform_lookup(args);
1149 199721903 : switch (error) {
1150 192423331 : case -ENOATTR:
1151 192423331 : if (args->op_flags & XFS_DA_OP_REPLACE)
1152 : return error;
1153 : break;
1154 7298572 : case -EEXIST:
1155 7298572 : if (!(args->op_flags & XFS_DA_OP_REPLACE))
1156 : return error;
1157 :
1158 7298572 : error = xfs_attr_sf_removename(args);
1159 7300199 : 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 7300199 : args->op_flags &= ~XFS_DA_OP_REPLACE;
1169 7300199 : break;
1170 : case 0:
1171 : break;
1172 : default:
1173 : return error;
1174 : }
1175 :
1176 199723530 : if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
1177 199723530 : args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
1178 : return -ENOSPC;
1179 :
1180 199712616 : newsize = xfs_attr_sf_totsize(args->dp);
1181 199712616 : newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
1182 :
1183 199712616 : forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
1184 199672515 : if (!forkoff)
1185 : return -ENOSPC;
1186 :
1187 195003360 : xfs_attr_shortform_add(args, forkoff);
1188 195003360 : 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 17918706 : args->blkno2 = args->blkno;
1202 17918706 : args->index2 = args->index;
1203 17918706 : args->rmtblkno2 = args->rmtblkno;
1204 17918706 : args->rmtblkcnt2 = args->rmtblkcnt;
1205 17918706 : args->rmtvaluelen2 = args->rmtvaluelen;
1206 17918706 : args->rmtblkno = 0;
1207 17918706 : args->rmtblkcnt = 0;
1208 17918706 : args->rmtvaluelen = 0;
1209 17918706 : }
1210 :
1211 : /* Set stored info about a remote block */
1212 : static void
1213 17914451 : xfs_attr_restore_rmt_blk(
1214 : struct xfs_da_args *args)
1215 : {
1216 17914451 : args->blkno = args->blkno2;
1217 17914451 : args->index = args->index2;
1218 17914451 : args->rmtblkno = args->rmtblkno2;
1219 17914451 : args->rmtblkcnt = args->rmtblkcnt2;
1220 17914451 : args->rmtvaluelen = args->rmtvaluelen2;
1221 17914451 : }
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 77010041 : xfs_attr_leaf_try_add(
1235 : struct xfs_da_args *args)
1236 : {
1237 77010041 : struct xfs_buf *bp;
1238 77010041 : int error;
1239 :
1240 77010041 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
1241 77061878 : if (error)
1242 : return error;
1243 :
1244 : /*
1245 : * Look up the xattr name to set the insertion point for the new xattr.
1246 : */
1247 77063682 : error = xfs_attr3_leaf_lookup_int(bp, args);
1248 77073075 : switch (error) {
1249 59510436 : case -ENOATTR:
1250 59510436 : if (args->op_flags & XFS_DA_OP_REPLACE)
1251 0 : goto out_brelse;
1252 : break;
1253 17562639 : case -EEXIST:
1254 17562639 : if (!(args->op_flags & XFS_DA_OP_REPLACE))
1255 0 : goto out_brelse;
1256 :
1257 17562639 : 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 17560598 : xfs_attr_save_rmt_blk(args);
1264 : break;
1265 : case 0:
1266 : break;
1267 0 : default:
1268 0 : goto out_brelse;
1269 : }
1270 :
1271 77071034 : 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 169698003 : xfs_attr_leaf_hasname(
1283 : struct xfs_da_args *args,
1284 : struct xfs_buf **bp)
1285 : {
1286 169698003 : int error = 0;
1287 :
1288 169698003 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, bp);
1289 169737446 : if (error)
1290 : return error;
1291 :
1292 169746093 : error = xfs_attr3_leaf_lookup_int(*bp, args);
1293 169728473 : 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 30344123 : xfs_attr_leaf_removename(
1307 : struct xfs_da_args *args)
1308 : {
1309 30344123 : struct xfs_inode *dp;
1310 30344123 : struct xfs_buf *bp;
1311 30344123 : int error, forkoff;
1312 :
1313 30344123 : trace_xfs_attr_leaf_removename(args);
1314 :
1315 : /*
1316 : * Remove the attribute.
1317 : */
1318 30333735 : dp = args->dp;
1319 :
1320 30333735 : error = xfs_attr_leaf_hasname(args, &bp);
1321 30367152 : if (error == -ENOATTR) {
1322 33 : xfs_trans_brelse(args->trans, bp);
1323 33 : if (args->op_flags & XFS_DA_OP_RECOVERY)
1324 : return 0;
1325 0 : return error;
1326 30367119 : } else if (error != -EEXIST)
1327 : return error;
1328 :
1329 30365096 : xfs_attr3_leaf_remove(bp, args);
1330 :
1331 : /*
1332 : * If the result is small enough, shrink it all into the inode.
1333 : */
1334 30359079 : forkoff = xfs_attr_shortform_allfit(bp, dp);
1335 30359468 : if (forkoff)
1336 2059103 : 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 17112156 : xfs_attr_leaf_get(xfs_da_args_t *args)
1352 : {
1353 17112156 : struct xfs_buf *bp;
1354 17112156 : int error;
1355 :
1356 17112156 : trace_xfs_attr_leaf_get(args);
1357 :
1358 17108916 : error = xfs_attr_leaf_hasname(args, &bp);
1359 :
1360 17112045 : if (error == -ENOATTR) {
1361 6022573 : xfs_trans_brelse(args->trans, bp);
1362 6022573 : return error;
1363 11089472 : } else if (error != -EEXIST)
1364 : return error;
1365 :
1366 :
1367 11087803 : error = xfs_attr3_leaf_getvalue(bp, args);
1368 11078450 : xfs_trans_brelse(args->trans, bp);
1369 11078450 : return error;
1370 : }
1371 :
1372 : /* Return EEXIST if attr is found, or ENOATTR if not. */
1373 : STATIC int
1374 6636820 : xfs_attr_node_lookup(
1375 : struct xfs_da_args *args,
1376 : struct xfs_da_state *state)
1377 : {
1378 6636820 : int retval, error;
1379 :
1380 : /*
1381 : * Search to see if name exists, and get back a pointer to it.
1382 : */
1383 6636820 : error = xfs_da3_node_lookup_int(state, &retval);
1384 6636939 : if (error)
1385 : return error;
1386 :
1387 6636919 : return retval;
1388 : }
1389 :
1390 : /*========================================================================
1391 : * External routines when attribute list size > geo->blksize
1392 : *========================================================================*/
1393 :
1394 : STATIC int
1395 2160654 : xfs_attr_node_addname_find_attr(
1396 : struct xfs_attr_intent *attr)
1397 : {
1398 2160654 : struct xfs_da_args *args = attr->xattri_da_args;
1399 2160654 : 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 2160654 : xfs_attr_item_init_da_state(attr);
1406 2160724 : error = xfs_attr_node_lookup(args, attr->xattri_da_state);
1407 2160786 : switch (error) {
1408 1802677 : case -ENOATTR:
1409 1802677 : if (args->op_flags & XFS_DA_OP_REPLACE)
1410 0 : goto error;
1411 : break;
1412 358109 : case -EEXIST:
1413 358109 : if (!(args->op_flags & XFS_DA_OP_REPLACE))
1414 0 : goto error;
1415 :
1416 :
1417 358109 : 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 358108 : 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 2160743 : xfs_attr_node_try_addname(
1449 : struct xfs_attr_intent *attr)
1450 : {
1451 2160743 : struct xfs_da_state *state = attr->xattri_da_state;
1452 2160743 : struct xfs_da_state_blk *blk;
1453 2160743 : int error;
1454 :
1455 2160743 : trace_xfs_attr_node_addname(state->args);
1456 :
1457 2160731 : blk = &state->path.blk[state->path.active-1];
1458 2160730 : ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1459 :
1460 2160730 : error = xfs_attr3_leaf_add(blk->bp, state->args);
1461 2160732 : if (error == -ENOSPC) {
1462 143329 : 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 143329 : error = xfs_da3_split(state);
1478 143329 : if (error)
1479 11 : goto out;
1480 : } else {
1481 : /*
1482 : * Addition succeeded, update Btree hashvals.
1483 : */
1484 2017403 : xfs_da3_fixhashpath(state, &state->path);
1485 : }
1486 :
1487 2160739 : out:
1488 2160739 : xfs_da_state_free(state);
1489 2160736 : attr->xattri_da_state = NULL;
1490 2160736 : return error;
1491 : }
1492 :
1493 : static int
1494 1047063 : xfs_attr_node_removename(
1495 : struct xfs_da_args *args,
1496 : struct xfs_da_state *state)
1497 : {
1498 1047063 : struct xfs_da_state_blk *blk;
1499 1047063 : int retval;
1500 :
1501 : /*
1502 : * Remove the name and update the hashvals in the tree.
1503 : */
1504 1047063 : blk = &state->path.blk[state->path.active-1];
1505 1047063 : ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1506 1047063 : retval = xfs_attr3_leaf_remove(blk->bp, args);
1507 1047062 : xfs_da3_fixhashpath(state, &state->path);
1508 :
1509 1047063 : return retval;
1510 : }
1511 :
1512 : static int
1513 1047064 : xfs_attr_node_remove_attr(
1514 : struct xfs_attr_intent *attr)
1515 : {
1516 1047064 : struct xfs_da_args *args = attr->xattri_da_args;
1517 1047064 : struct xfs_da_state *state = xfs_da_state_alloc(args);
1518 1047071 : int retval = 0;
1519 1047071 : 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 1047071 : args->attr_filter |= XFS_ATTR_INCOMPLETE;
1527 1047071 : error = xfs_da3_node_lookup_int(state, &retval);
1528 1047069 : if (error)
1529 0 : goto out;
1530 :
1531 1047069 : error = xfs_attr_node_removename(args, state);
1532 :
1533 : /*
1534 : * Check to see if the tree needs to be collapsed.
1535 : */
1536 1047051 : if (retval && (state->path.active > 1)) {
1537 1044672 : error = xfs_da3_join(state);
1538 1044668 : if (error)
1539 10 : goto out;
1540 : }
1541 1047037 : retval = error = 0;
1542 :
1543 1047047 : out:
1544 1047047 : xfs_da_state_free(state);
1545 1047063 : if (error)
1546 : return error;
1547 1047053 : 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 683471 : xfs_attr_node_get(
1561 : struct xfs_da_args *args)
1562 : {
1563 683471 : struct xfs_da_state *state;
1564 683471 : struct xfs_da_state_blk *blk;
1565 683471 : int i;
1566 683471 : int error;
1567 :
1568 683471 : trace_xfs_attr_node_get(args);
1569 :
1570 : /*
1571 : * Search to see if name exists, and get back a pointer to it.
1572 : */
1573 683471 : state = xfs_da_state_alloc(args);
1574 683479 : error = xfs_attr_node_lookup(args, state);
1575 683479 : if (error != -EEXIST)
1576 122081 : goto out_release;
1577 :
1578 : /*
1579 : * Get the value, local or "remote"
1580 : */
1581 561398 : blk = &state->path.blk[state->path.active - 1];
1582 561397 : 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 683477 : out_release:
1588 2052904 : for (i = 0; i < state->path.active; i++) {
1589 1369423 : xfs_trans_brelse(args->trans, state->path.blk[i].bp);
1590 1369427 : state->path.blk[i].bp = NULL;
1591 : }
1592 :
1593 683481 : xfs_da_state_free(state);
1594 683479 : return error;
1595 : }
1596 :
1597 : /* Returns true if the attribute entry name is valid. */
1598 : bool
1599 6330383073 : xfs_attr_namecheck(
1600 : struct xfs_mount *mp,
1601 : const void *name,
1602 : size_t length,
1603 : unsigned int flags)
1604 : {
1605 6330383073 : if (flags & XFS_ATTR_PARENT)
1606 1004676309 : 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 5325706764 : if (length >= MAXNAMELEN)
1613 : return false;
1614 :
1615 : /* There shouldn't be any nulls here */
1616 10651413528 : return !memchr(name, 0, length);
1617 : }
1618 :
1619 : int __init
1620 50 : xfs_attr_intent_init_cache(void)
1621 : {
1622 50 : xfs_attr_intent_cache = kmem_cache_create("xfs_attr_intent",
1623 : sizeof(struct xfs_attr_intent),
1624 : 0, 0, NULL);
1625 :
1626 50 : return xfs_attr_intent_cache != NULL ? 0 : -ENOMEM;
1627 : }
1628 :
1629 : void
1630 49 : xfs_attr_intent_destroy_cache(void)
1631 : {
1632 49 : kmem_cache_destroy(xfs_attr_intent_cache);
1633 49 : xfs_attr_intent_cache = NULL;
1634 49 : }
|