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 2493987087 : xfs_inode_hasattr(
69 : struct xfs_inode *ip)
70 : {
71 2600001478 : if (!xfs_inode_has_attr_fork(ip))
72 : return 0;
73 3111160663 : if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
74 472243862 : ip->i_af.if_nextents == 0)
75 1578834 : 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 835119071 : xfs_attr_is_leaf(
85 : struct xfs_inode *ip)
86 : {
87 835119071 : struct xfs_ifork *ifp = &ip->i_af;
88 835119071 : struct xfs_iext_cursor icur;
89 835119071 : struct xfs_bmbt_irec imap;
90 :
91 835119071 : if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
92 : return false;
93 :
94 818911489 : xfs_iext_first(ifp, &icur);
95 818839721 : xfs_iext_get_extent(ifp, &icur, &imap);
96 819201968 : 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 171159780 : xfs_attr_get_ilocked(
226 : struct xfs_da_args *args)
227 : {
228 171159780 : ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
229 :
230 171158353 : if (!xfs_inode_hasattr(args->dp))
231 : return -ENOATTR;
232 :
233 171145448 : if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
234 137807984 : return xfs_attr_shortform_getvalue(args);
235 33337464 : if (xfs_attr_is_leaf(args->dp))
236 32550306 : return xfs_attr_leaf_get(args);
237 786807 : 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 74647962 : xfs_attr_get(
258 : struct xfs_da_args *args)
259 : {
260 74647962 : uint lock_mode;
261 74647962 : int error;
262 :
263 74647962 : XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
264 :
265 149295924 : if (xfs_is_shutdown(args->dp->i_mount))
266 : return -EIO;
267 :
268 74646986 : args->geo = args->dp->i_mount->m_attr_geo;
269 74646986 : args->whichfork = XFS_ATTR_FORK;
270 74646986 : args->hashval = xfs_da_hashname(args->name, args->namelen);
271 :
272 : /* Entirely possible to look up a name which doesn't exist */
273 74646022 : args->op_flags = XFS_DA_OP_OKNOENT;
274 :
275 74646022 : lock_mode = xfs_ilock_attr_map_shared(args->dp);
276 74646554 : error = xfs_attr_get_ilocked(args);
277 74645174 : xfs_iunlock(args->dp, lock_mode);
278 :
279 74645174 : return error;
280 : }
281 :
282 : /*
283 : * Calculate how many blocks we need for the new attribute,
284 : */
285 : int
286 234730861 : xfs_attr_calc_size(
287 : struct xfs_da_args *args,
288 : int *local)
289 : {
290 234730861 : struct xfs_mount *mp = args->dp->i_mount;
291 234730861 : int size;
292 234730861 : 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 234730861 : size = xfs_attr_leaf_newentsize(args, local);
299 234733150 : nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
300 234733150 : if (*local) {
301 234732435 : 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 715 : uint dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
311 715 : nblks += dblocks;
312 715 : nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
313 : }
314 :
315 234733150 : return nblks;
316 : }
317 :
318 : /* Initialize transaction reservation for attr operations */
319 : void
320 340765465 : xfs_init_attr_trans(
321 : struct xfs_da_args *args,
322 : struct xfs_trans_res *tres,
323 : unsigned int *total)
324 : {
325 340765465 : struct xfs_mount *mp = args->dp->i_mount;
326 :
327 340765465 : if (args->value) {
328 234732215 : tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
329 234732215 : M_RES(mp)->tr_attrsetrt.tr_logres *
330 234732215 : args->total;
331 234732215 : tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
332 234732215 : tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
333 234732215 : *total = args->total;
334 : } else {
335 106033250 : *tres = M_RES(mp)->tr_attrrm;
336 106033250 : *total = XFS_ATTRRM_SPACE_RES(mp);
337 : }
338 340765465 : }
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 164734836 : xfs_attr_try_sf_addname(
347 : struct xfs_inode *dp,
348 : struct xfs_da_args *args)
349 : {
350 :
351 164734836 : int error;
352 :
353 : /*
354 : * Build initial attribute list (if required).
355 : */
356 164734836 : if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
357 62964995 : xfs_attr_shortform_create(args);
358 :
359 164734862 : error = xfs_attr_shortform_addname(args);
360 164739093 : 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 156152300 : if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
368 156152087 : xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
369 :
370 156153873 : if (xfs_has_wsync(dp->i_mount))
371 270 : xfs_trans_set_sync(args->trans);
372 :
373 : return error;
374 : }
375 :
376 : static int
377 164738106 : xfs_attr_sf_addname(
378 : struct xfs_attr_intent *attr)
379 : {
380 164738106 : struct xfs_da_args *args = attr->xattri_da_args;
381 164738106 : struct xfs_inode *dp = args->dp;
382 164738106 : int error = 0;
383 :
384 164738106 : error = xfs_attr_try_sf_addname(dp, args);
385 164734376 : if (error != -ENOSPC) {
386 156147560 : ASSERT(!error || error == -EEXIST);
387 156147560 : attr->xattri_dela_state = XFS_DAS_DONE;
388 156147560 : 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 8586816 : error = xfs_attr_shortform_to_leaf(args);
396 8586720 : if (error)
397 : return error;
398 :
399 8586717 : attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
400 164734277 : out:
401 164734277 : trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
402 164734277 : 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 341036528 : xfs_attr_complete_op(
418 : struct xfs_attr_intent *attr,
419 : enum xfs_delattr_state replace_state)
420 : {
421 341036528 : struct xfs_da_args *args = attr->xattri_da_args;
422 341036528 : bool do_replace = args->op_flags & XFS_DA_OP_REPLACE;
423 :
424 341036528 : args->op_flags &= ~XFS_DA_OP_REPLACE;
425 341036528 : if (!do_replace)
426 : return XFS_DAS_DONE;
427 :
428 76772159 : args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
429 76772159 : 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 39781127 : ASSERT(args->new_namelen > 0);
437 :
438 39781127 : args->name = args->new_name;
439 39781127 : args->namelen = args->new_namelen;
440 39781127 : args->hashval = xfs_da_hashname(args->name, args->namelen);
441 39781129 : args->value = args->new_value;
442 39781129 : args->valuelen = args->new_valuelen;
443 39781129 : return replace_state;
444 : }
445 :
446 : static int
447 151840453 : xfs_attr_leaf_addname(
448 : struct xfs_attr_intent *attr)
449 : {
450 151840453 : struct xfs_da_args *args = attr->xattri_da_args;
451 151840453 : int error;
452 :
453 151840453 : 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 151844860 : error = xfs_attr_leaf_try_add(args);
460 :
461 151842369 : if (error == -ENOSPC) {
462 80091 : error = xfs_attr3_leaf_to_node(args);
463 80091 : 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 80089 : attr->xattri_dela_state = XFS_DAS_NODE_ADD;
471 80089 : goto out;
472 : }
473 151762278 : 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 151762278 : if (args->rmtblkno)
482 581 : attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
483 : else
484 151761697 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
485 : XFS_DAS_LEAF_REPLACE);
486 151851075 : out:
487 151851075 : trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
488 151851075 : 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 3219837 : xfs_attr_node_addname(
500 : struct xfs_attr_intent *attr)
501 : {
502 3219837 : struct xfs_da_args *args = attr->xattri_da_args;
503 3219837 : int error;
504 :
505 3219837 : error = xfs_attr_node_addname_find_attr(attr);
506 3219852 : if (error)
507 : return error;
508 :
509 3219835 : error = xfs_attr_node_try_addname(attr);
510 3219848 : 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 3219848 : if (error)
521 : return error;
522 :
523 3219846 : if (args->rmtblkno)
524 4 : attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
525 : else
526 3219842 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
527 : XFS_DAS_NODE_REPLACE);
528 3219845 : out:
529 3219845 : trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
530 3219845 : return error;
531 : }
532 :
533 : static int
534 585 : xfs_attr_rmtval_alloc(
535 : struct xfs_attr_intent *attr)
536 : {
537 585 : struct xfs_da_args *args = attr->xattri_da_args;
538 585 : 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 585 : if (attr->xattri_blkcnt > 0) {
547 585 : error = xfs_attr_rmtval_set_blk(attr);
548 585 : if (error)
549 : return error;
550 : /* Roll the transaction only if there is more to allocate. */
551 585 : if (attr->xattri_blkcnt > 0)
552 0 : goto out;
553 : }
554 :
555 585 : error = xfs_attr_rmtval_set_value(args);
556 585 : if (error)
557 : return error;
558 :
559 1170 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
560 585 : ++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 585 : if (attr->xattri_dela_state == XFS_DAS_DONE)
567 583 : error = xfs_attr3_leaf_clearflag(args);
568 2 : out:
569 585 : trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
570 585 : 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 1283333 : 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 1283333 : error = xfs_attr_fillstate(state);
590 1283333 : if (error)
591 : return error;
592 :
593 : /*
594 : * Mark the attribute as INCOMPLETE
595 : */
596 1283333 : 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 4503173 : xfs_attr_item_init_da_state(
602 : struct xfs_attr_intent *attr)
603 : {
604 4503173 : struct xfs_da_args *args = attr->xattri_da_args;
605 :
606 4503173 : if (!attr->xattri_da_state)
607 4493711 : attr->xattri_da_state = xfs_da_state_alloc(args);
608 : else
609 9462 : xfs_da_state_reset(attr->xattri_da_state, args);
610 4503172 : }
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 1283333 : int xfs_attr_node_removename_setup(
619 : struct xfs_attr_intent *attr)
620 : {
621 1283333 : struct xfs_da_args *args = attr->xattri_da_args;
622 1283333 : struct xfs_da_state *state;
623 1283333 : int error;
624 :
625 1283333 : xfs_attr_item_init_da_state(attr);
626 1283335 : error = xfs_attr_node_lookup(args, attr->xattri_da_state);
627 1283339 : if (error != -EEXIST)
628 6 : goto out;
629 1283333 : error = 0;
630 :
631 1283333 : state = attr->xattri_da_state;
632 1283333 : ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
633 1283333 : ASSERT(state->path.blk[state->path.active - 1].magic ==
634 : XFS_ATTR_LEAF_MAGIC);
635 :
636 1283333 : error = xfs_attr_leaf_mark_incomplete(args, state);
637 1283332 : if (error)
638 0 : goto out;
639 1283332 : if (args->rmtblkno > 0)
640 12 : error = xfs_attr_rmtval_invalidate(args);
641 1283320 : out:
642 1283338 : if (error) {
643 6 : xfs_da_state_free(attr->xattri_da_state);
644 6 : attr->xattri_da_state = NULL;
645 : }
646 :
647 1283338 : 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 36207591 : xfs_attr_leaf_remove_attr(
657 : struct xfs_attr_intent *attr)
658 : {
659 36207591 : struct xfs_da_args *args = attr->xattri_da_args;
660 36207591 : struct xfs_inode *dp = args->dp;
661 36207591 : struct xfs_buf *bp = NULL;
662 36207591 : int forkoff;
663 36207591 : int error;
664 :
665 36207591 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
666 : args->blkno, &bp);
667 36207630 : if (error)
668 : return error;
669 :
670 36208574 : xfs_attr3_leaf_remove(bp, args);
671 :
672 36208115 : forkoff = xfs_attr_shortform_allfit(bp, dp);
673 36208898 : if (forkoff)
674 803032 : 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 2065816 : xfs_attr_leaf_shrink(
687 : struct xfs_da_args *args)
688 : {
689 2065816 : struct xfs_inode *dp = args->dp;
690 2065816 : struct xfs_buf *bp;
691 2065816 : int forkoff;
692 2065816 : int error;
693 :
694 2065816 : if (!xfs_attr_is_leaf(dp))
695 : return 0;
696 :
697 86 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
698 86 : if (error)
699 : return error;
700 :
701 86 : forkoff = xfs_attr_shortform_allfit(bp, dp);
702 86 : 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 76 : 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 544138213 : xfs_attr_set_iter(
722 : struct xfs_attr_intent *attr)
723 : {
724 544138213 : struct xfs_da_args *args = attr->xattri_da_args;
725 544138213 : int error = 0;
726 :
727 : /* State machine switch */
728 : next_state:
729 581128176 : switch (attr->xattri_dela_state) {
730 0 : case XFS_DAS_UNINIT:
731 0 : ASSERT(0);
732 0 : return -EFSCORRUPTED;
733 164731796 : case XFS_DAS_SF_ADD:
734 164731796 : return xfs_attr_sf_addname(attr);
735 151819680 : case XFS_DAS_LEAF_ADD:
736 151819680 : return xfs_attr_leaf_addname(attr);
737 3219833 : case XFS_DAS_NODE_ADD:
738 3219833 : return xfs_attr_node_addname(attr);
739 :
740 88998651 : case XFS_DAS_SF_REMOVE:
741 88998651 : error = xfs_attr_sf_removename(args);
742 88998958 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
743 : xfs_attr_init_add_state(args));
744 89000053 : break;
745 58820381 : case XFS_DAS_LEAF_REMOVE:
746 58820381 : error = xfs_attr_leaf_removename(args);
747 58822029 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
748 : xfs_attr_init_add_state(args));
749 58824439 : break;
750 1283334 : case XFS_DAS_NODE_REMOVE:
751 1283334 : error = xfs_attr_node_removename_setup(attr);
752 1283338 : 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 1283332 : if (error)
760 : return error;
761 1283332 : attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
762 1283332 : if (args->rmtblkno == 0)
763 1283320 : attr->xattri_dela_state++;
764 : break;
765 :
766 585 : case XFS_DAS_LEAF_SET_RMT:
767 : case XFS_DAS_NODE_SET_RMT:
768 585 : error = xfs_attr_rmtval_find_space(attr);
769 585 : if (error)
770 0 : return error;
771 585 : attr->xattri_dela_state++;
772 585 : fallthrough;
773 :
774 585 : case XFS_DAS_LEAF_ALLOC_RMT:
775 : case XFS_DAS_NODE_ALLOC_RMT:
776 585 : error = xfs_attr_rmtval_alloc(attr);
777 585 : if (error)
778 0 : return error;
779 585 : if (attr->xattri_dela_state == XFS_DAS_DONE)
780 : break;
781 2 : goto next_state;
782 :
783 36989742 : 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 36989742 : error = xfs_attr3_leaf_flipflags(args);
791 36989983 : 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 36989983 : attr->xattri_dela_state++;
798 36989983 : break;
799 :
800 36991040 : 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 36991040 : xfs_attr_restore_rmt_blk(args);
810 36989961 : if (args->rmtblkno) {
811 4 : error = xfs_attr_rmtval_invalidate(args);
812 4 : if (error)
813 0 : return error;
814 : } else {
815 36989957 : attr->xattri_dela_state++;
816 : }
817 :
818 36989961 : attr->xattri_dela_state++;
819 36989961 : 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 36207292 : case XFS_DAS_LEAF_REMOVE_ATTR:
843 36207292 : error = xfs_attr_leaf_remove_attr(attr);
844 36208738 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
845 : xfs_attr_init_add_state(args));
846 36208710 : break;
847 :
848 2065826 : case XFS_DAS_NODE_REMOVE_ATTR:
849 2065826 : error = xfs_attr_node_remove_attr(attr);
850 2065821 : if (!error)
851 2065812 : error = xfs_attr_leaf_shrink(args);
852 2065834 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
853 : xfs_attr_init_add_state(args));
854 2065829 : break;
855 0 : default:
856 0 : ASSERT(0);
857 0 : break;
858 : }
859 :
860 224372951 : trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
861 224372951 : return error;
862 : }
863 :
864 :
865 : /*
866 : * Return EEXIST if attr is found, or ENOATTR if not
867 : */
868 : static int
869 340695211 : xfs_attr_lookup(
870 : struct xfs_da_args *args)
871 : {
872 340695211 : struct xfs_inode *dp = args->dp;
873 340695211 : struct xfs_buf *bp = NULL;
874 340695211 : struct xfs_da_state *state;
875 340695211 : int error;
876 :
877 340695211 : if (!xfs_inode_hasattr(dp))
878 : return -ENOATTR;
879 :
880 340359116 : if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
881 89187327 : return xfs_attr_sf_findname(args, NULL, NULL);
882 :
883 251171789 : if (xfs_attr_is_leaf(dp)) {
884 245799065 : error = xfs_attr_leaf_hasname(args, &bp);
885 :
886 245771220 : if (bp)
887 245771217 : xfs_trans_brelse(args->trans, bp);
888 :
889 245823193 : return error;
890 : }
891 :
892 5354612 : state = xfs_da_state_alloc(args);
893 5354599 : error = xfs_attr_node_lookup(args, state);
894 5354598 : xfs_da_state_free(state);
895 5354598 : 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 420428648 : struct xfs_attr_intent *new;
906 :
907 0 : new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
908 420434218 : new->xattri_op_flags = op_flags;
909 420434218 : new->xattri_da_args = args;
910 :
911 420434218 : *attr = new;
912 420434218 : return 0;
913 : }
914 :
915 : /* Sets an attribute for an inode as a deferred operation */
916 : int
917 220844476 : xfs_attr_defer_add(
918 : struct xfs_da_args *args)
919 : {
920 220844476 : struct xfs_attr_intent *new;
921 220844476 : int op_flag = XFS_ATTRI_OP_FLAGS_SET;
922 220844476 : int error = 0;
923 :
924 220844476 : if (args->op_flags & XFS_DA_OP_NVLOOKUP)
925 69169824 : op_flag = XFS_ATTRI_OP_FLAGS_NVSET;
926 :
927 220844476 : error = xfs_attr_intent_init(args, op_flag, &new);
928 220846819 : if (error)
929 : return error;
930 :
931 220846819 : new->xattri_dela_state = xfs_attr_init_add_state(args);
932 220852654 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
933 220856629 : trace_xfs_attr_defer_add(new->xattri_dela_state, args->dp);
934 :
935 220857182 : return 0;
936 : }
937 :
938 : /* Sets an attribute for an inode as a deferred operation */
939 : int
940 90269297 : xfs_attr_defer_replace(
941 : struct xfs_da_args *args)
942 : {
943 90269297 : struct xfs_attr_intent *new;
944 90269297 : int op_flag = XFS_ATTRI_OP_FLAGS_REPLACE;
945 90269297 : int error = 0;
946 :
947 90269297 : if (args->op_flags & XFS_DA_OP_NVLOOKUP)
948 39781117 : op_flag = XFS_ATTRI_OP_FLAGS_NVREPLACE;
949 :
950 90269297 : error = xfs_attr_intent_init(args, op_flag, &new);
951 90268381 : if (error)
952 : return error;
953 :
954 90268381 : new->xattri_dela_state = xfs_attr_init_replace_state(args);
955 90271120 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
956 90270813 : trace_xfs_attr_defer_replace(new->xattri_dela_state, args->dp);
957 :
958 90270811 : return 0;
959 : }
960 :
961 : /* Removes an attribute for an inode as a deferred operation */
962 : int
963 109314875 : xfs_attr_defer_remove(
964 : struct xfs_da_args *args)
965 : {
966 :
967 109314875 : struct xfs_attr_intent *new;
968 109314875 : int op_flag = XFS_ATTRI_OP_FLAGS_REMOVE;
969 109314875 : int error;
970 :
971 109314875 : if (args->op_flags & XFS_DA_OP_NVLOOKUP)
972 39071803 : op_flag = XFS_ATTRI_OP_FLAGS_NVREMOVE;
973 :
974 109314875 : error = xfs_attr_intent_init(args, op_flag, &new);
975 109319018 : if (error)
976 : return error;
977 :
978 109319018 : new->xattri_dela_state = xfs_attr_init_remove_state(args);
979 109322640 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
980 109322615 : trace_xfs_attr_defer_remove(new->xattri_dela_state, args->dp);
981 :
982 109322589 : return 0;
983 : }
984 :
985 : int
986 : xfs_attr_add_fork(
987 : struct xfs_inode *ip, /* incore inode pointer */
988 : int size, /* space new attribute needs */
989 : int rsvd) /* xact may use reserved blks */
990 340738878 : {
991 : struct xfs_mount *mp = ip->i_mount;
992 : struct xfs_trans *tp; /* transaction pointer */
993 340738878 : unsigned int blks; /* space reservation */
994 340738878 : int error; /* error return value */
995 340738878 :
996 340738878 : if (xfs_is_metadir_inode(ip))
997 : ASSERT(XFS_IS_DQDETACHED(ip->i_mount, ip));
998 340738878 : else
999 340738878 : ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
1000 340738878 :
1001 340738878 : blks = XFS_ADDAFORK_SPACE_RES(mp);
1002 :
1003 681477756 : error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_addafork, blks, 0,
1004 : rsvd, &tp);
1005 : if (error)
1006 340738673 : return error;
1007 340758975 :
1008 : if (xfs_inode_has_attr_fork(ip))
1009 : goto trans_cancel;
1010 340685522 :
1011 340685522 : error = xfs_bmap_add_attrfork(tp, ip, size, rsvd);
1012 340685522 : if (error)
1013 : goto trans_cancel;
1014 :
1015 : error = xfs_trans_commit(tp);
1016 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
1017 : return error;
1018 :
1019 : trans_cancel:
1020 340783032 : xfs_trans_cancel(tp);
1021 340783032 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
1022 : return error;
1023 340783032 : }
1024 234744960 :
1025 234744960 : /*
1026 : * Note: If args->value is NULL the attribute will be removed, just like the
1027 : * Linux ->setattr API.
1028 : */
1029 : int
1030 : xfs_attr_set(
1031 234297025 : struct xfs_da_args *args)
1032 317645 : {
1033 317645 : struct xfs_inode *dp = args->dp;
1034 317645 : struct xfs_mount *mp = dp->i_mount;
1035 : struct xfs_trans_res tres;
1036 317645 : bool rsvd = (args->attr_filter & (XFS_ATTR_ROOT |
1037 317661 : XFS_ATTR_PARENT));
1038 : bool is_remove = args->op_flags & XFS_DA_OP_REMOVE;
1039 : int error, local;
1040 : int rmt_blks = 0;
1041 234297041 : unsigned int total;
1042 705 :
1043 : if (xfs_is_shutdown(dp->i_mount))
1044 106038072 : return -EIO;
1045 106038072 :
1046 : error = xfs_qm_dqattach(dp);
1047 : if (error)
1048 : return error;
1049 :
1050 : args->geo = mp->m_attr_geo;
1051 : args->whichfork = XFS_ATTR_FORK;
1052 340331253 : args->hashval = xfs_da_hashname(args->name, args->namelen);
1053 340719904 :
1054 340793304 : /*
1055 : * We have no control over the attribute names that userspace passes us
1056 : * to remove, so we have to allow the name lookup prior to attribute
1057 340707930 : * removal to fail as well. Preserve the logged and vlookup flags,
1058 340697783 : * since we need to pass them through to the lower levels.
1059 340697783 : */
1060 340655966 : args->op_flags &= (XFS_DA_OP_LOGGED | XFS_DA_OP_NVLOOKUP);
1061 4 : args->op_flags |= XFS_DA_OP_OKNOENT;
1062 4 :
1063 340655966 : if (!is_remove) {
1064 4 : XFS_STATS_INC(mp, xs_attr_set);
1065 : args->total = xfs_attr_calc_size(args, &local);
1066 :
1067 340666109 : /*
1068 340667105 : * If the inode doesn't have an attribute fork, add one.
1069 121414538 : * (inode must not be locked when we call this routine)
1070 : */
1071 121414538 : if (xfs_inode_has_attr_fork(dp) == 0) {
1072 70250944 : int sf_size = sizeof(struct xfs_attr_sf_hdr) +
1073 70250944 : xfs_attr_sf_entsize_byname(args->namelen,
1074 : args->valuelen);
1075 :
1076 51163594 : error = xfs_attr_add_fork(dp, sf_size, rsvd);
1077 675036 : if (error)
1078 : return error;
1079 50488558 : }
1080 50488558 :
1081 219252460 : if (!local)
1082 : rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
1083 219252460 : } else {
1084 35757116 : XFS_STATS_INC(mp, xs_attr_remove);
1085 : rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
1086 : }
1087 183495344 :
1088 31433068 : /*
1089 : * Root fork attributes can use reserved data blocks for this
1090 152062276 : * operation if necessary
1091 152062276 : */
1092 107 : xfs_init_attr_trans(args, &tres, &total);
1093 107 : error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
1094 : if (error)
1095 272829065 : return error;
1096 0 :
1097 : if (!is_remove || xfs_inode_hasattr(dp)) {
1098 : error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
1099 : XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1100 : if (error == -EFBIG)
1101 : error = xfs_iext_count_upgrade(args->trans, dp,
1102 272829065 : XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1103 0 : if (error)
1104 : goto out_trans_cancel;
1105 272829065 : }
1106 272752212 :
1107 : error = xfs_attr_lookup(args);
1108 : switch (error) {
1109 : case -EEXIST:
1110 : /* if no value, we are performing a remove operation */
1111 272888576 : if (is_remove) {
1112 272837372 : error = xfs_attr_defer_remove(args);
1113 340695725 : break;
1114 340695725 : }
1115 340695725 : /* Pure create fails if the attr already exists */
1116 : if (args->attr_flags & XATTR_CREATE)
1117 67865331 : goto out_trans_cancel;
1118 67865331 :
1119 67865398 : error = xfs_attr_defer_replace(args);
1120 67869078 : break;
1121 : case -ENOATTR:
1122 : /* Can't remove what isn't there. */
1123 : if (is_remove)
1124 : goto out_trans_cancel;
1125 :
1126 : /* Pure replace fails if no existing attr to replace. */
1127 277448 : if (args->attr_flags & XATTR_REPLACE)
1128 : goto out_trans_cancel;
1129 165013619 :
1130 : error = xfs_attr_defer_add(args);
1131 165013619 : break;
1132 165013619 : default:
1133 : goto out_trans_cancel;
1134 : }
1135 : if (error)
1136 : goto out_trans_cancel;
1137 :
1138 : /*
1139 : * If this is a synchronous mount, make sure that the
1140 164732781 : * transaction goes to disk before returning to the user.
1141 : */
1142 : if (xfs_has_wsync(mp))
1143 164732781 : xfs_trans_set_sync(args->trans);
1144 164732781 :
1145 : if (!(args->op_flags & XFS_DA_OP_NOTIME))
1146 164732781 : xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
1147 :
1148 164738004 : /*
1149 164738115 : * Commit the last in the sequence of transactions.
1150 151234975 : */
1151 151234975 : xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
1152 : error = xfs_trans_commit(args->trans);
1153 : out_unlock:
1154 13500237 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
1155 13500237 : return error;
1156 :
1157 : out_trans_cancel:
1158 13500237 : if (args->trans)
1159 13500336 : xfs_trans_cancel(args->trans);
1160 : goto out_unlock;
1161 : }
1162 :
1163 : /*========================================================================
1164 : * External routines when attribute list is inside the inode
1165 : *========================================================================*/
1166 :
1167 : int xfs_attr_sf_totsize(struct xfs_inode *dp)
1168 13500336 : {
1169 13500336 : struct xfs_attr_shortform *sf;
1170 :
1171 : sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
1172 : return be16_to_cpu(sf->hdr.totsize);
1173 : }
1174 :
1175 : /*
1176 164738214 : * Add a name to the shortform attribute list structure
1177 164738214 : * This is the external routine.
1178 : */
1179 : static int
1180 164736171 : xfs_attr_shortform_addname(
1181 164736171 : struct xfs_da_args *args)
1182 : {
1183 164736171 : int newsize, forkoff;
1184 164735146 : int error;
1185 :
1186 : trace_xfs_attr_sf_addname(args);
1187 156150380 :
1188 156150380 : error = xfs_attr_shortform_lookup(args);
1189 : switch (error) {
1190 : case -ENOATTR:
1191 : if (args->op_flags & XFS_DA_OP_REPLACE)
1192 : return error;
1193 : break;
1194 : case -EEXIST:
1195 : if (!(args->op_flags & XFS_DA_OP_REPLACE))
1196 : return error;
1197 :
1198 : error = xfs_attr_sf_removename(args);
1199 : if (error)
1200 : return error;
1201 37010238 :
1202 37010238 : /*
1203 37010238 : * Since we have removed the old attr, clear XFS_DA_OP_REPLACE
1204 37010238 : * so that the new attr doesn't fit in shortform format, the
1205 37010238 : * leaf format add routine won't trip over the attr not being
1206 37010238 : * around.
1207 37010238 : */
1208 37010238 : args->op_flags &= ~XFS_DA_OP_REPLACE;
1209 37010238 : break;
1210 : case 0:
1211 : break;
1212 : default:
1213 36990656 : return error;
1214 : }
1215 :
1216 36990656 : if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
1217 36990656 : args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
1218 36990656 : return -ENOSPC;
1219 36990656 :
1220 36990656 : newsize = xfs_attr_sf_totsize(args->dp);
1221 36990656 : newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
1222 :
1223 : forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
1224 : if (!forkoff)
1225 : return -ENOSPC;
1226 :
1227 : xfs_attr_shortform_add(args, forkoff);
1228 : return 0;
1229 : }
1230 :
1231 :
1232 : /*========================================================================
1233 : * External routines when attribute list is one block
1234 151831395 : *========================================================================*/
1235 :
1236 : /* Save the current remote block info and clear the current pointers. */
1237 151831395 : static void
1238 151831395 : xfs_attr_save_rmt_blk(
1239 : struct xfs_da_args *args)
1240 151831395 : {
1241 151827844 : args->blkno2 = args->blkno;
1242 : args->index2 = args->index;
1243 : args->rmtblkno2 = args->rmtblkno;
1244 : args->rmtblkcnt2 = args->rmtblkcnt;
1245 : args->rmtvaluelen2 = args->rmtvaluelen;
1246 : args->rmtblkno = 0;
1247 151855159 : args->rmtblkcnt = 0;
1248 151842505 : args->rmtvaluelen = 0;
1249 115616164 : }
1250 115616164 :
1251 0 : /* Set stored info about a remote block */
1252 : static void
1253 36226341 : xfs_attr_restore_rmt_blk(
1254 36226341 : struct xfs_da_args *args)
1255 0 : {
1256 : args->blkno = args->blkno2;
1257 36226341 : args->index = args->index2;
1258 : args->rmtblkno = args->rmtblkno2;
1259 : args->rmtblkcnt = args->rmtblkcnt2;
1260 : args->rmtvaluelen = args->rmtvaluelen2;
1261 : }
1262 :
1263 36227742 : /*
1264 : * Tries to add an attribute to an inode in leaf form
1265 : *
1266 : * This function is meant to execute as part of a delayed operation and leaves
1267 0 : * the transaction handling to the caller. On success the attribute is added
1268 0 : * and the inode and transaction are left dirty. If there is not enough space,
1269 : * the attr data is converted to node format and -ENOSPC is returned. Caller is
1270 : * responsible for handling the dirty inode and transaction or adding the attr
1271 151843906 : * in node format.
1272 : */
1273 0 : STATIC int
1274 0 : xfs_attr_leaf_try_add(
1275 0 : struct xfs_da_args *args)
1276 : {
1277 : struct xfs_buf *bp;
1278 : int error;
1279 :
1280 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
1281 : if (error)
1282 337005190 : return error;
1283 :
1284 : /*
1285 : * Look up the xattr name to set the insertion point for the new xattr.
1286 337005190 : */
1287 : error = xfs_attr3_leaf_lookup_int(bp, args);
1288 337005190 : switch (error) {
1289 336970003 : case -ENOATTR:
1290 : if (args->op_flags & XFS_DA_OP_REPLACE)
1291 : goto out_brelse;
1292 336967342 : break;
1293 337082595 : case -EEXIST:
1294 0 : if (!(args->op_flags & XFS_DA_OP_REPLACE))
1295 : goto out_brelse;
1296 :
1297 : trace_xfs_attr_leaf_replace(args);
1298 : /*
1299 : * Save the existing remote attr state so that the current
1300 : * values reflect the state of the new attribute we are about to
1301 : * add, not the attribute we just found and will remove later.
1302 : */
1303 : xfs_attr_save_rmt_blk(args);
1304 : break;
1305 : case 0:
1306 58820960 : break;
1307 : default:
1308 : goto out_brelse;
1309 58820960 : }
1310 58820960 :
1311 58820960 : return xfs_attr3_leaf_add(bp, args);
1312 :
1313 58820960 : out_brelse:
1314 : xfs_trans_brelse(args->trans, bp);
1315 : return error;
1316 : }
1317 :
1318 58824698 : /*
1319 : * Return EEXIST if attr is found, or ENOATTR if not
1320 58824698 : */
1321 58825765 : STATIC int
1322 7 : xfs_attr_leaf_hasname(
1323 7 : struct xfs_da_args *args,
1324 : struct xfs_buf **bp)
1325 0 : {
1326 58825758 : int error = 0;
1327 :
1328 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, bp);
1329 58824863 : if (error)
1330 : return error;
1331 :
1332 : error = xfs_attr3_leaf_lookup_int(*bp, args);
1333 : if (error != -ENOATTR && error != -EEXIST)
1334 58825633 : xfs_trans_brelse(args->trans, *bp);
1335 58824684 :
1336 3697927 : return error;
1337 : }
1338 :
1339 : /*
1340 : * Remove a name from the leaf attribute list structure
1341 : *
1342 : * This leaf block cannot have a "remote" value, we only call this routine
1343 : * if bmap_one_block() says there is only one block (ie: no remote blks).
1344 : */
1345 : STATIC int
1346 : xfs_attr_leaf_removename(
1347 : struct xfs_da_args *args)
1348 : {
1349 : struct xfs_inode *dp;
1350 : struct xfs_buf *bp;
1351 32550007 : int error, forkoff;
1352 :
1353 32550007 : trace_xfs_attr_leaf_removename(args);
1354 32550007 :
1355 : /*
1356 32550007 : * Remove the attribute.
1357 : */
1358 32550784 : dp = args->dp;
1359 :
1360 32550632 : error = xfs_attr_leaf_hasname(args, &bp);
1361 12175168 : if (error == -ENOATTR) {
1362 12175168 : xfs_trans_brelse(args->trans, bp);
1363 20375464 : if (args->op_flags & XFS_DA_OP_RECOVERY)
1364 : return 0;
1365 : return error;
1366 : } else if (error != -EEXIST)
1367 20375454 : return error;
1368 20375361 :
1369 20375361 : xfs_attr3_leaf_remove(bp, args);
1370 :
1371 : /*
1372 : * If the result is small enough, shrink it all into the inode.
1373 : */
1374 10644368 : forkoff = xfs_attr_shortform_allfit(bp, dp);
1375 : if (forkoff)
1376 : return xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1377 : /* bp is gone due to xfs_da_shrink_inode */
1378 10644368 :
1379 : return 0;
1380 : }
1381 :
1382 : /*
1383 10644368 : * Look up a name in a leaf attribute list structure.
1384 10644502 : *
1385 : * This leaf block cannot have a "remote" value, we only call this routine
1386 : * if bmap_one_block() says there is only one block (ie: no remote blks).
1387 10644298 : *
1388 : * Returns 0 on successful retrieval, otherwise an error.
1389 : */
1390 : STATIC int
1391 : xfs_attr_leaf_get(xfs_da_args_t *args)
1392 : {
1393 : struct xfs_buf *bp;
1394 : int error;
1395 3219820 :
1396 : trace_xfs_attr_leaf_get(args);
1397 :
1398 3219820 : error = xfs_attr_leaf_hasname(args, &bp);
1399 3219820 :
1400 : if (error == -ENOATTR) {
1401 : xfs_trans_brelse(args->trans, bp);
1402 : return error;
1403 : } else if (error != -EEXIST)
1404 : return error;
1405 3219820 :
1406 3219845 :
1407 3219848 : error = xfs_attr3_leaf_getvalue(bp, args);
1408 2437353 : xfs_trans_brelse(args->trans, bp);
1409 2437353 : return error;
1410 0 : }
1411 :
1412 782495 : /* Return EEXIST if attr is found, or ENOATTR if not. */
1413 782495 : STATIC int
1414 0 : xfs_attr_node_lookup(
1415 : struct xfs_da_args *args,
1416 : struct xfs_da_state *state)
1417 782495 : {
1418 : int retval, error;
1419 :
1420 : /*
1421 : * Search to see if name exists, and get back a pointer to it.
1422 : */
1423 782496 : error = xfs_da3_node_lookup_int(state, &retval);
1424 : if (error)
1425 : return error;
1426 :
1427 0 : return retval;
1428 0 : }
1429 :
1430 : /*========================================================================
1431 : * External routines when attribute list size > geo->blksize
1432 0 : *========================================================================*/
1433 0 :
1434 0 : STATIC int
1435 0 : xfs_attr_node_addname_find_attr(
1436 : struct xfs_attr_intent *attr)
1437 : {
1438 : struct xfs_da_args *args = attr->xattri_da_args;
1439 : int error;
1440 :
1441 : /*
1442 : * Search to see if name already exists, and get back a pointer
1443 : * to where it should go.
1444 : */
1445 : xfs_attr_item_init_da_state(attr);
1446 : error = xfs_attr_node_lookup(args, attr->xattri_da_state);
1447 : switch (error) {
1448 3219783 : case -ENOATTR:
1449 : if (args->op_flags & XFS_DA_OP_REPLACE)
1450 : goto error;
1451 3219783 : break;
1452 3219783 : case -EEXIST:
1453 3219783 : if (!(args->op_flags & XFS_DA_OP_REPLACE))
1454 : goto error;
1455 3219783 :
1456 :
1457 3219844 : trace_xfs_attr_node_replace(args);
1458 3219844 : /*
1459 : * Save the existing remote attr state so that the current
1460 3219844 : * values reflect the state of the new attribute we are about to
1461 3219845 : * add, not the attribute we just found and will remove later.
1462 108624 : */
1463 : xfs_attr_save_rmt_blk(args);
1464 : break;
1465 : case 0:
1466 : break;
1467 : default:
1468 0 : goto error;
1469 : }
1470 :
1471 : return 0;
1472 : error:
1473 : if (attr->xattri_da_state) {
1474 : xfs_da_state_free(attr->xattri_da_state);
1475 : attr->xattri_da_state = NULL;
1476 : }
1477 108624 : return error;
1478 108624 : }
1479 2 :
1480 : /*
1481 : * Add a name to a Btree-format attribute list.
1482 : *
1483 : * This will involve walking down the Btree, and may involve splitting
1484 3111221 : * leaf nodes and even splitting intermediate nodes up to and including
1485 : * the root node (a special case of an intermediate node).
1486 : */
1487 3219850 : static int
1488 3219850 : xfs_attr_node_try_addname(
1489 3219846 : struct xfs_attr_intent *attr)
1490 3219846 : {
1491 : struct xfs_da_state *state = attr->xattri_da_state;
1492 : struct xfs_da_state_blk *blk;
1493 : int error;
1494 2065822 :
1495 : trace_xfs_attr_node_addname(state->args);
1496 :
1497 : blk = &state->path.blk[state->path.active-1];
1498 2065822 : ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1499 2065822 :
1500 : error = xfs_attr3_leaf_add(blk->bp, state->args);
1501 : if (error == -ENOSPC) {
1502 : if (state->path.active == 1) {
1503 : /*
1504 2065822 : * Its really a single leaf node, but it had
1505 2065822 : * out-of-line values so it looked like it *might*
1506 2065822 : * have been a b-tree. Let the caller deal with this.
1507 2065824 : */
1508 : goto out;
1509 2065828 : }
1510 :
1511 : /*
1512 : * Split as many Btree elements as required.
1513 2065829 : * This code tracks the new and old attr's location
1514 : * in the index/blkno/rmtblkno/rmtblkcnt fields and
1515 : * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
1516 2065829 : */
1517 2065829 : error = xfs_da3_split(state);
1518 2065829 : if (error)
1519 2065829 : goto out;
1520 : } else {
1521 : /*
1522 : * Addition succeeded, update Btree hashvals.
1523 : */
1524 : xfs_da3_fixhashpath(state, &state->path);
1525 : }
1526 2065829 :
1527 2065829 : out:
1528 2065820 : xfs_da_state_free(state);
1529 0 : attr->xattri_da_state = NULL;
1530 : return error;
1531 2065820 : }
1532 :
1533 : static int
1534 : xfs_attr_node_removename(
1535 : struct xfs_da_args *args,
1536 2065826 : struct xfs_da_state *state)
1537 2065399 : {
1538 2065401 : struct xfs_da_state_blk *blk;
1539 2 : int retval;
1540 :
1541 2065826 : /*
1542 : * Remove the name and update the hashvals in the tree.
1543 2065828 : */
1544 2065828 : blk = &state->path.blk[state->path.active-1];
1545 2065829 : ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1546 : retval = xfs_attr3_leaf_remove(blk->bp, args);
1547 2065827 : xfs_da3_fixhashpath(state, &state->path);
1548 :
1549 : return retval;
1550 : }
1551 :
1552 : static int
1553 : xfs_attr_node_remove_attr(
1554 : struct xfs_attr_intent *attr)
1555 : {
1556 : struct xfs_da_args *args = attr->xattri_da_args;
1557 : struct xfs_da_state *state = xfs_da_state_alloc(args);
1558 : int retval = 0;
1559 : int error = 0;
1560 786808 :
1561 : /*
1562 : * The attr we are removing has already been marked incomplete, so
1563 786808 : * we need to set the filter appropriately to re-find the "old"
1564 786808 : * attribute entry after any split ops.
1565 786808 : */
1566 786808 : args->attr_filter |= XFS_ATTR_INCOMPLETE;
1567 : error = xfs_da3_node_lookup_int(state, &retval);
1568 786808 : if (error)
1569 : goto out;
1570 :
1571 : error = xfs_attr_node_removename(args, state);
1572 :
1573 786807 : /*
1574 786807 : * Check to see if the tree needs to be collapsed.
1575 786808 : */
1576 250363 : if (retval && (state->path.active > 1)) {
1577 : error = xfs_da3_join(state);
1578 : if (error)
1579 : goto out;
1580 : }
1581 536445 : retval = error = 0;
1582 536445 :
1583 : out:
1584 : xfs_da_state_free(state);
1585 : if (error)
1586 : return error;
1587 786808 : return retval;
1588 2359666 : }
1589 1572858 :
1590 1572858 : /*
1591 : * Retrieve the attribute data from a node attribute list.
1592 : *
1593 786808 : * This routine gets called for any attribute fork that has more than one
1594 786808 : * block, ie: both true Btree attr lists and for single-leaf-blocks with
1595 : * "remote" values taking up more blocks.
1596 : *
1597 : * Returns 0 on successful retrieval, otherwise an error.
1598 : */
1599 7158034247 : STATIC int
1600 : xfs_attr_node_get(
1601 : struct xfs_da_args *args)
1602 : {
1603 : struct xfs_da_state *state;
1604 : struct xfs_da_state_blk *blk;
1605 7158034247 : int i;
1606 389323140 : int error;
1607 :
1608 : trace_xfs_attr_node_get(args);
1609 :
1610 : /*
1611 : * Search to see if name exists, and get back a pointer to it.
1612 6768711107 : */
1613 : state = xfs_da_state_alloc(args);
1614 : error = xfs_attr_node_lookup(args, state);
1615 : if (error != -EEXIST)
1616 13537422214 : goto out_release;
1617 :
1618 : /*
1619 : * Get the value, local or "remote"
1620 12 : */
1621 : blk = &state->path.blk[state->path.active - 1];
1622 12 : error = xfs_attr3_leaf_getvalue(blk->bp, args);
1623 :
1624 : /*
1625 : * If not in a transaction, we have to release all the buffers.
1626 12 : */
1627 : out_release:
1628 : for (i = 0; i < state->path.active; i++) {
1629 : xfs_trans_brelse(args->trans, state->path.blk[i].bp);
1630 12 : state->path.blk[i].bp = NULL;
1631 : }
1632 12 :
1633 12 : xfs_da_state_free(state);
1634 12 : return error;
1635 : }
1636 :
1637 : /* Returns true if the attribute entry name is valid. */
1638 : bool
1639 : xfs_attr_namecheck(
1640 : struct xfs_mount *mp,
1641 : const void *name,
1642 : size_t length,
1643 : unsigned int flags)
1644 : {
1645 : if (flags & XFS_ATTR_PARENT)
1646 : return xfs_parent_namecheck(mp, name, length, flags);
1647 :
1648 : /*
1649 : * MAXNAMELEN includes the trailing null, but (name/length) leave it
1650 : * out, so use >= for the length check.
1651 : */
1652 : if (length >= MAXNAMELEN)
1653 : return false;
1654 :
1655 : /* There shouldn't be any nulls here */
1656 : return !memchr(name, 0, length);
1657 : }
1658 :
1659 : int __init
1660 : xfs_attr_intent_init_cache(void)
1661 : {
1662 : xfs_attr_intent_cache = kmem_cache_create("xfs_attr_intent",
1663 : sizeof(struct xfs_attr_intent),
1664 : 0, 0, NULL);
1665 :
1666 : return xfs_attr_intent_cache != NULL ? 0 : -ENOMEM;
1667 : }
1668 :
1669 : void
1670 : xfs_attr_intent_destroy_cache(void)
1671 : {
1672 : kmem_cache_destroy(xfs_attr_intent_cache);
1673 : xfs_attr_intent_cache = NULL;
1674 : }
|