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 7306911581 : xfs_inode_hasattr(
69 : struct xfs_inode *ip)
70 : {
71 7413900846 : if (!xfs_inode_has_attr_fork(ip))
72 : return 0;
73 7963115809 : if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
74 704526205 : ip->i_af.if_nextents == 0)
75 19030727 : 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 1016875543 : xfs_attr_is_leaf(
85 : struct xfs_inode *ip)
86 : {
87 1016875543 : struct xfs_ifork *ifp = &ip->i_af;
88 1016875543 : struct xfs_iext_cursor icur;
89 1016875543 : struct xfs_bmbt_irec imap;
90 :
91 1016875543 : if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
92 : return false;
93 :
94 1000800390 : xfs_iext_first(ifp, &icur);
95 1000702622 : xfs_iext_get_extent(ifp, &icur, &imap);
96 1002254899 : 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 251221461 : xfs_attr_get_ilocked(
226 : struct xfs_da_args *args)
227 : {
228 251221461 : ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
229 :
230 250879774 : if (!xfs_inode_hasattr(args->dp))
231 : return -ENOATTR;
232 :
233 249588887 : if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
234 218525281 : return xfs_attr_shortform_getvalue(args);
235 31063606 : if (xfs_attr_is_leaf(args->dp))
236 30159278 : return xfs_attr_leaf_get(args);
237 963813 : 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 91105129 : xfs_attr_get(
258 : struct xfs_da_args *args)
259 : {
260 91105129 : uint lock_mode;
261 91105129 : int error;
262 :
263 91105129 : XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
264 :
265 182060704 : if (xfs_is_shutdown(args->dp->i_mount))
266 : return -EIO;
267 :
268 91029492 : args->geo = args->dp->i_mount->m_attr_geo;
269 91029492 : args->whichfork = XFS_ATTR_FORK;
270 91029492 : args->hashval = xfs_da_hashname(args->name, args->namelen);
271 :
272 : /* Entirely possible to look up a name which doesn't exist */
273 91047402 : args->op_flags = XFS_DA_OP_OKNOENT;
274 :
275 91047402 : lock_mode = xfs_ilock_attr_map_shared(args->dp);
276 90986821 : error = xfs_attr_get_ilocked(args);
277 90957806 : xfs_iunlock(args->dp, lock_mode);
278 :
279 90957806 : return error;
280 : }
281 :
282 : /*
283 : * Calculate how many blocks we need for the new attribute,
284 : */
285 : int
286 225112378 : xfs_attr_calc_size(
287 : struct xfs_da_args *args,
288 : int *local)
289 : {
290 225112378 : struct xfs_mount *mp = args->dp->i_mount;
291 225112378 : int size;
292 225112378 : 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 225112378 : size = xfs_attr_leaf_newentsize(args, local);
299 225083110 : nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
300 225083110 : if (*local) {
301 225079598 : 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 3512 : uint dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
311 3512 : nblks += dblocks;
312 3512 : nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
313 : }
314 :
315 225083110 : return nblks;
316 : }
317 :
318 : /* Initialize transaction reservation for attr operations */
319 : void
320 332055157 : xfs_init_attr_trans(
321 : struct xfs_da_args *args,
322 : struct xfs_trans_res *tres,
323 : unsigned int *total)
324 : {
325 332055157 : struct xfs_mount *mp = args->dp->i_mount;
326 :
327 332055157 : if (args->value) {
328 225180930 : tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
329 225180930 : M_RES(mp)->tr_attrsetrt.tr_logres *
330 225180930 : args->total;
331 225180930 : tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
332 225180930 : tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
333 225180930 : *total = args->total;
334 : } else {
335 106874227 : *tres = M_RES(mp)->tr_attrrm;
336 106874227 : *total = XFS_ATTRRM_SPACE_RES(mp);
337 : }
338 332055157 : }
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 236600381 : xfs_attr_try_sf_addname(
347 : struct xfs_inode *dp,
348 : struct xfs_da_args *args)
349 : {
350 :
351 236600381 : int error;
352 :
353 : /*
354 : * Build initial attribute list (if required).
355 : */
356 236600381 : if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
357 107939134 : xfs_attr_shortform_create(args);
358 :
359 236644763 : error = xfs_attr_shortform_addname(args);
360 236672122 : 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 228440285 : if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
368 228434375 : xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
369 :
370 228437631 : if (xfs_has_wsync(dp->i_mount))
371 1346 : xfs_trans_set_sync(args->trans);
372 :
373 : return error;
374 : }
375 :
376 : static int
377 236603468 : xfs_attr_sf_addname(
378 : struct xfs_attr_intent *attr)
379 : {
380 236603468 : struct xfs_da_args *args = attr->xattri_da_args;
381 236603468 : struct xfs_inode *dp = args->dp;
382 236603468 : int error = 0;
383 :
384 236603468 : error = xfs_attr_try_sf_addname(dp, args);
385 236660493 : if (error != -ENOSPC) {
386 228428808 : ASSERT(!error || error == -EEXIST);
387 228428808 : attr->xattri_dela_state = XFS_DAS_DONE;
388 228428808 : 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 8231685 : error = xfs_attr_shortform_to_leaf(args);
396 8232160 : if (error)
397 : return error;
398 :
399 8232156 : attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
400 236660964 : out:
401 236660964 : trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
402 236660964 : 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 366450104 : xfs_attr_complete_op(
418 : struct xfs_attr_intent *attr,
419 : enum xfs_delattr_state replace_state)
420 : {
421 366450104 : struct xfs_da_args *args = attr->xattri_da_args;
422 366450104 : bool do_replace = args->op_flags & XFS_DA_OP_REPLACE;
423 :
424 366450104 : args->op_flags &= ~XFS_DA_OP_REPLACE;
425 366450104 : if (!do_replace)
426 : return XFS_DAS_DONE;
427 :
428 94262941 : args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
429 94262941 : 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 60428252 : ASSERT(args->new_namelen > 0);
437 :
438 60428252 : args->name = args->new_name;
439 60428252 : args->namelen = args->new_namelen;
440 60428252 : args->hashval = xfs_da_hashname(args->name, args->namelen);
441 60428196 : args->value = args->new_value;
442 60428196 : args->valuelen = args->new_valuelen;
443 60428196 : return replace_state;
444 : }
445 :
446 : static int
447 139981041 : xfs_attr_leaf_addname(
448 : struct xfs_attr_intent *attr)
449 : {
450 139981041 : struct xfs_da_args *args = attr->xattri_da_args;
451 139981041 : int error;
452 :
453 139981041 : 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 140119850 : error = xfs_attr_leaf_try_add(args);
460 :
461 140101174 : if (error == -ENOSPC) {
462 75030 : error = xfs_attr3_leaf_to_node(args);
463 75031 : 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 75020 : attr->xattri_dela_state = XFS_DAS_NODE_ADD;
471 75020 : goto out;
472 : }
473 140026144 : 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 140026144 : if (args->rmtblkno)
482 3029 : attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
483 : else
484 140023115 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
485 : XFS_DAS_LEAF_REPLACE);
486 139855269 : out:
487 139855269 : trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
488 139855269 : 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 3583195 : xfs_attr_node_addname(
500 : struct xfs_attr_intent *attr)
501 : {
502 3583195 : struct xfs_da_args *args = attr->xattri_da_args;
503 3583195 : int error;
504 :
505 3583195 : error = xfs_attr_node_addname_find_attr(attr);
506 3583408 : if (error)
507 : return error;
508 :
509 3583374 : error = xfs_attr_node_try_addname(attr);
510 3583136 : 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 3583136 : if (error)
521 : return error;
522 :
523 3583125 : if (args->rmtblkno)
524 133 : attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
525 : else
526 3582992 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
527 : XFS_DAS_NODE_REPLACE);
528 3583128 : out:
529 3583128 : trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
530 3583128 : return error;
531 : }
532 :
533 : static int
534 3162 : xfs_attr_rmtval_alloc(
535 : struct xfs_attr_intent *attr)
536 : {
537 3162 : struct xfs_da_args *args = attr->xattri_da_args;
538 3162 : 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 3162 : if (attr->xattri_blkcnt > 0) {
547 3162 : error = xfs_attr_rmtval_set_blk(attr);
548 3162 : if (error)
549 : return error;
550 : /* Roll the transaction only if there is more to allocate. */
551 3162 : if (attr->xattri_blkcnt > 0)
552 0 : goto out;
553 : }
554 :
555 3162 : error = xfs_attr_rmtval_set_value(args);
556 3162 : if (error)
557 : return error;
558 :
559 6324 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
560 3162 : ++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 3162 : if (attr->xattri_dela_state == XFS_DAS_DONE)
567 3152 : error = xfs_attr3_leaf_clearflag(args);
568 10 : out:
569 3162 : trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
570 3162 : 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 1218185 : 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 1218185 : error = xfs_attr_fillstate(state);
590 1218185 : if (error)
591 : return error;
592 :
593 : /*
594 : * Mark the attribute as INCOMPLETE
595 : */
596 1218185 : 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 4800976 : xfs_attr_item_init_da_state(
602 : struct xfs_attr_intent *attr)
603 : {
604 4800976 : struct xfs_da_args *args = attr->xattri_da_args;
605 :
606 4800976 : if (!attr->xattri_da_state)
607 4793126 : attr->xattri_da_state = xfs_da_state_alloc(args);
608 : else
609 7850 : xfs_da_state_reset(attr->xattri_da_state, args);
610 4801444 : }
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 1218170 : int xfs_attr_node_removename_setup(
619 : struct xfs_attr_intent *attr)
620 : {
621 1218170 : struct xfs_da_args *args = attr->xattri_da_args;
622 1218170 : struct xfs_da_state *state;
623 1218170 : int error;
624 :
625 1218170 : xfs_attr_item_init_da_state(attr);
626 1218189 : error = xfs_attr_node_lookup(args, attr->xattri_da_state);
627 1218215 : if (error != -EEXIST)
628 33 : goto out;
629 1218182 : error = 0;
630 :
631 1218182 : state = attr->xattri_da_state;
632 1218182 : ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
633 1218182 : ASSERT(state->path.blk[state->path.active - 1].magic ==
634 : XFS_ATTR_LEAF_MAGIC);
635 :
636 1218185 : error = xfs_attr_leaf_mark_incomplete(args, state);
637 1218132 : if (error)
638 0 : goto out;
639 1218132 : if (args->rmtblkno > 0)
640 68 : error = xfs_attr_rmtval_invalidate(args);
641 1218064 : out:
642 1218165 : if (error) {
643 33 : xfs_da_state_free(attr->xattri_da_state);
644 33 : attr->xattri_da_state = NULL;
645 : }
646 :
647 1218165 : 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 32656394 : xfs_attr_leaf_remove_attr(
657 : struct xfs_attr_intent *attr)
658 : {
659 32656394 : struct xfs_da_args *args = attr->xattri_da_args;
660 32656394 : struct xfs_inode *dp = args->dp;
661 32656394 : struct xfs_buf *bp = NULL;
662 32656394 : int forkoff;
663 32656394 : int error;
664 :
665 32656394 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
666 : args->blkno, &bp);
667 32656268 : if (error)
668 : return error;
669 :
670 32656271 : xfs_attr3_leaf_remove(bp, args);
671 :
672 32656193 : forkoff = xfs_attr_shortform_allfit(bp, dp);
673 32655977 : if (forkoff)
674 745119 : 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 1906393 : xfs_attr_leaf_shrink(
687 : struct xfs_da_args *args)
688 : {
689 1906393 : struct xfs_inode *dp = args->dp;
690 1906393 : struct xfs_buf *bp;
691 1906393 : int forkoff;
692 1906393 : int error;
693 :
694 1906393 : if (!xfs_attr_is_leaf(dp))
695 : return 0;
696 :
697 146 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
698 146 : if (error)
699 : return error;
700 :
701 146 : forkoff = xfs_attr_shortform_allfit(bp, dp);
702 146 : 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 90 : 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 637728676 : xfs_attr_set_iter(
722 : struct xfs_attr_intent *attr)
723 : {
724 637728676 : struct xfs_da_args *args = attr->xattri_da_args;
725 637728676 : int error = 0;
726 :
727 : /* State machine switch */
728 : next_state:
729 671073345 : switch (attr->xattri_dela_state) {
730 0 : case XFS_DAS_UNINIT:
731 0 : ASSERT(0);
732 0 : return -EFSCORRUPTED;
733 236625625 : case XFS_DAS_SF_ADD:
734 236625625 : return xfs_attr_sf_addname(attr);
735 140069090 : case XFS_DAS_LEAF_ADD:
736 140069090 : return xfs_attr_leaf_addname(attr);
737 3583273 : case XFS_DAS_NODE_ADD:
738 3583273 : return xfs_attr_node_addname(attr);
739 :
740 133771052 : case XFS_DAS_SF_REMOVE:
741 133771052 : error = xfs_attr_sf_removename(args);
742 133773263 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
743 : xfs_attr_init_add_state(args));
744 133767699 : break;
745 54550612 : case XFS_DAS_LEAF_REMOVE:
746 54550612 : error = xfs_attr_leaf_removename(args);
747 54580701 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
748 : xfs_attr_init_add_state(args));
749 54567880 : break;
750 1218202 : case XFS_DAS_NODE_REMOVE:
751 1218202 : error = xfs_attr_node_removename_setup(attr);
752 1218152 : 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 1218119 : if (error)
760 : return error;
761 1218119 : attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
762 1218119 : if (args->rmtblkno == 0)
763 1218049 : attr->xattri_dela_state++;
764 : break;
765 :
766 3162 : case XFS_DAS_LEAF_SET_RMT:
767 : case XFS_DAS_NODE_SET_RMT:
768 3162 : error = xfs_attr_rmtval_find_space(attr);
769 3162 : if (error)
770 0 : return error;
771 3162 : attr->xattri_dela_state++;
772 3162 : fallthrough;
773 :
774 3162 : case XFS_DAS_LEAF_ALLOC_RMT:
775 : case XFS_DAS_NODE_ALLOC_RMT:
776 3162 : error = xfs_attr_rmtval_alloc(attr);
777 3162 : if (error)
778 0 : return error;
779 3162 : if (attr->xattri_dela_state == XFS_DAS_DONE)
780 : break;
781 10 : goto next_state;
782 :
783 33344656 : 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 33344656 : error = xfs_attr3_leaf_flipflags(args);
791 33344417 : 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 33344417 : attr->xattri_dela_state++;
798 33344417 : break;
799 :
800 33344737 : 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 33344737 : xfs_attr_restore_rmt_blk(args);
810 33344659 : if (args->rmtblkno) {
811 20 : error = xfs_attr_rmtval_invalidate(args);
812 20 : if (error)
813 0 : return error;
814 : } else {
815 33344639 : attr->xattri_dela_state++;
816 : }
817 :
818 33344659 : attr->xattri_dela_state++;
819 33344659 : 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 32656412 : case XFS_DAS_LEAF_REMOVE_ATTR:
843 32656412 : error = xfs_attr_leaf_remove_attr(attr);
844 32655785 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
845 : xfs_attr_init_add_state(args));
846 32655752 : break;
847 :
848 1906436 : case XFS_DAS_NODE_REMOVE_ATTR:
849 1906436 : error = xfs_attr_node_remove_attr(attr);
850 1906424 : if (!error)
851 1906407 : error = xfs_attr_leaf_shrink(args);
852 1906419 : attr->xattri_dela_state = xfs_attr_complete_op(attr,
853 : xfs_attr_init_add_state(args));
854 1906413 : break;
855 0 : default:
856 0 : ASSERT(0);
857 0 : break;
858 : }
859 :
860 257463553 : trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
861 257463553 : return error;
862 : }
863 :
864 :
865 : /*
866 : * Return EEXIST if attr is found, or ENOATTR if not
867 : */
868 : static int
869 331668408 : xfs_attr_lookup(
870 : struct xfs_da_args *args)
871 : {
872 331668408 : struct xfs_inode *dp = args->dp;
873 331668408 : struct xfs_buf *bp = NULL;
874 331668408 : struct xfs_da_state *state;
875 331668408 : int error;
876 :
877 331668408 : if (!xfs_inode_hasattr(dp))
878 : return -ENOATTR;
879 :
880 325805216 : if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
881 95346379 : return xfs_attr_sf_findname(args, NULL, NULL);
882 :
883 230458837 : if (xfs_attr_is_leaf(dp)) {
884 225116989 : error = xfs_attr_leaf_hasname(args, &bp);
885 :
886 225136796 : if (bp)
887 225136786 : xfs_trans_brelse(args->trans, bp);
888 :
889 225209841 : return error;
890 : }
891 :
892 5431296 : state = xfs_da_state_alloc(args);
893 5431387 : error = xfs_attr_node_lookup(args, state);
894 5431132 : xfs_da_state_free(state);
895 5431132 : 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 500582328 : struct xfs_attr_intent *new;
906 :
907 0 : new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
908 500617747 : new->xattri_op_flags = op_flags;
909 500617747 : new->xattri_da_args = args;
910 :
911 500617747 : *attr = new;
912 500617747 : return 0;
913 : }
914 :
915 : /* Sets an attribute for an inode as a deferred operation */
916 : int
917 264834006 : xfs_attr_defer_add(
918 : struct xfs_da_args *args)
919 : {
920 264834006 : struct xfs_attr_intent *new;
921 264834006 : int op_flag = XFS_ATTRI_OP_FLAGS_SET;
922 264834006 : int error = 0;
923 :
924 264834006 : if (args->op_flags & XFS_DA_OP_NVLOOKUP)
925 120776770 : op_flag = XFS_ATTRI_OP_FLAGS_NVSET;
926 :
927 264834006 : error = xfs_attr_intent_init(args, op_flag, &new);
928 264871480 : if (error)
929 : return error;
930 :
931 264871480 : new->xattri_dela_state = xfs_attr_init_add_state(args);
932 264702882 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
933 264672541 : trace_xfs_attr_defer_add(new->xattri_dela_state, args->dp);
934 :
935 264579992 : return 0;
936 : }
937 :
938 : /* Sets an attribute for an inode as a deferred operation */
939 : int
940 107155892 : xfs_attr_defer_replace(
941 : struct xfs_da_args *args)
942 : {
943 107155892 : struct xfs_attr_intent *new;
944 107155892 : int op_flag = XFS_ATTRI_OP_FLAGS_REPLACE;
945 107155892 : int error = 0;
946 :
947 107155892 : if (args->op_flags & XFS_DA_OP_NVLOOKUP)
948 60428287 : op_flag = XFS_ATTRI_OP_FLAGS_NVREPLACE;
949 :
950 107155892 : error = xfs_attr_intent_init(args, op_flag, &new);
951 107154480 : if (error)
952 : return error;
953 :
954 107154480 : new->xattri_dela_state = xfs_attr_init_replace_state(args);
955 107147655 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
956 107140454 : trace_xfs_attr_defer_replace(new->xattri_dela_state, args->dp);
957 :
958 107134858 : return 0;
959 : }
960 :
961 : /* Removes an attribute for an inode as a deferred operation */
962 : int
963 128592430 : xfs_attr_defer_remove(
964 : struct xfs_da_args *args)
965 : {
966 :
967 128592430 : struct xfs_attr_intent *new;
968 128592430 : int op_flag = XFS_ATTRI_OP_FLAGS_REMOVE;
969 128592430 : int error;
970 :
971 128592430 : if (args->op_flags & XFS_DA_OP_NVLOOKUP)
972 63823335 : op_flag = XFS_ATTRI_OP_FLAGS_NVREMOVE;
973 :
974 128592430 : error = xfs_attr_intent_init(args, op_flag, &new);
975 128591787 : if (error)
976 : return error;
977 :
978 128591787 : new->xattri_dela_state = xfs_attr_init_remove_state(args);
979 128578272 : xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
980 128566284 : trace_xfs_attr_defer_remove(new->xattri_dela_state, args->dp);
981 :
982 128553156 : 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 332008521 : {
991 : struct xfs_mount *mp = ip->i_mount;
992 : struct xfs_trans *tp; /* transaction pointer */
993 332008521 : unsigned int blks; /* space reservation */
994 332008521 : int error; /* error return value */
995 332008521 :
996 332008521 : if (xfs_is_metadir_inode(ip))
997 : ASSERT(XFS_IS_DQDETACHED(ip->i_mount, ip));
998 332008521 : else
999 332008521 : ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
1000 332008521 :
1001 332008521 : blks = XFS_ADDAFORK_SPACE_RES(mp);
1002 :
1003 664017042 : error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_addafork, blks, 0,
1004 : rsvd, &tp);
1005 : if (error)
1006 332007531 : return error;
1007 331956452 :
1008 : if (xfs_inode_has_attr_fork(ip))
1009 : goto trans_cancel;
1010 331891862 :
1011 331891862 : error = xfs_bmap_add_attrfork(tp, ip, size, rsvd);
1012 331891862 : 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 331855896 : xfs_trans_cancel(tp);
1021 331855896 : xfs_iunlock(ip, XFS_ILOCK_EXCL);
1022 : return error;
1023 331855896 : }
1024 225033723 :
1025 225115236 : /*
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 225094534 : struct xfs_da_args *args)
1032 4764010 : {
1033 4764010 : struct xfs_inode *dp = args->dp;
1034 4764010 : struct xfs_mount *mp = dp->i_mount;
1035 : struct xfs_trans_res tres;
1036 4764010 : bool rsvd = (args->attr_filter & (XFS_ATTR_ROOT |
1037 4766949 : XFS_ATTR_PARENT));
1038 : bool is_remove = args->op_flags & XFS_DA_OP_REMOVE;
1039 : int error, local;
1040 : int rmt_blks = 0;
1041 225097016 : unsigned int total;
1042 3457 :
1043 : if (xfs_is_shutdown(dp->i_mount))
1044 106822173 : return -EIO;
1045 106898583 :
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 331990803 : args->hashval = xfs_da_hashname(args->name, args->namelen);
1053 331916148 :
1054 332350362 : /*
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 332172982 : * removal to fail as well. Preserve the logged and vlookup flags,
1058 331152900 : * since we need to pass them through to the lower levels.
1059 331152900 : */
1060 330295710 : args->op_flags &= (XFS_DA_OP_LOGGED | XFS_DA_OP_NVLOOKUP);
1061 22 : args->op_flags |= XFS_DA_OP_OKNOENT;
1062 22 :
1063 330295710 : if (!is_remove) {
1064 22 : XFS_STATS_INC(mp, xs_attr_set);
1065 : args->total = xfs_attr_calc_size(args, &local);
1066 :
1067 331315770 : /*
1068 331962630 : * If the inode doesn't have an attribute fork, add one.
1069 111998549 : * (inode must not be locked when we call this routine)
1070 : */
1071 111998549 : if (xfs_inode_has_attr_fork(dp) == 0) {
1072 64783173 : int sf_size = sizeof(struct xfs_attr_sf_hdr) +
1073 64783173 : xfs_attr_sf_entsize_byname(args->namelen,
1074 : args->valuelen);
1075 :
1076 47215376 : error = xfs_attr_add_fork(dp, sf_size, rsvd);
1077 485742 : if (error)
1078 : return error;
1079 46729634 : }
1080 46729634 :
1081 219964051 : if (!local)
1082 : rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
1083 219964051 : } else {
1084 42016965 : XFS_STATS_INC(mp, xs_attr_remove);
1085 : rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
1086 : }
1087 177947086 :
1088 29036345 : /*
1089 : * Root fork attributes can use reserved data blocks for this
1090 148910741 : * operation if necessary
1091 148910741 : */
1092 30 : xfs_init_attr_trans(args, &tres, &total);
1093 30 : error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
1094 : if (error)
1095 260226528 : 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 260226528 : XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1103 0 : if (error)
1104 : goto out_trans_cancel;
1105 260226528 : }
1106 259997292 :
1107 : error = xfs_attr_lookup(args);
1108 : switch (error) {
1109 : case -EEXIST:
1110 : /* if no value, we are performing a remove operation */
1111 259659047 : if (is_remove) {
1112 260184273 : error = xfs_attr_defer_remove(args);
1113 332192512 : break;
1114 332192512 : }
1115 332192512 : /* Pure create fails if the attr already exists */
1116 : if (args->attr_flags & XATTR_CREATE)
1117 71539104 : goto out_trans_cancel;
1118 71539104 :
1119 71561104 : error = xfs_attr_defer_replace(args);
1120 71606785 : 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 4472813 : if (args->attr_flags & XATTR_REPLACE)
1128 : goto out_trans_cancel;
1129 241124272 :
1130 : error = xfs_attr_defer_add(args);
1131 241124272 : break;
1132 241124272 : 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 236621977 : * transaction goes to disk before returning to the user.
1141 : */
1142 : if (xfs_has_wsync(mp))
1143 236621977 : xfs_trans_set_sync(args->trans);
1144 236621977 :
1145 : if (!(args->op_flags & XFS_DA_OP_NOTIME))
1146 236621977 : xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
1147 :
1148 236604476 : /*
1149 236659292 : * Commit the last in the sequence of transactions.
1150 223783061 : */
1151 223783061 : xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
1152 : error = xfs_trans_commit(args->trans);
1153 : out_unlock:
1154 12876231 : xfs_iunlock(dp, XFS_ILOCK_EXCL);
1155 12876231 : return error;
1156 :
1157 : out_trans_cancel:
1158 12876231 : if (args->trans)
1159 12879553 : 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 12879553 : {
1169 12879553 : 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 236662614 : * Add a name to the shortform attribute list structure
1177 236662614 : * This is the external routine.
1178 : */
1179 : static int
1180 236651459 : xfs_attr_shortform_addname(
1181 236651459 : struct xfs_da_args *args)
1182 : {
1183 236651459 : int newsize, forkoff;
1184 236644313 : int error;
1185 :
1186 : trace_xfs_attr_sf_addname(args);
1187 228423603 :
1188 228423603 : 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 33339315 :
1202 33339315 : /*
1203 33339315 : * Since we have removed the old attr, clear XFS_DA_OP_REPLACE
1204 33339315 : * so that the new attr doesn't fit in shortform format, the
1205 33339315 : * leaf format add routine won't trip over the attr not being
1206 33339315 : * around.
1207 33339315 : */
1208 33339315 : args->op_flags &= ~XFS_DA_OP_REPLACE;
1209 33339315 : break;
1210 : case 0:
1211 : break;
1212 : default:
1213 33344707 : return error;
1214 : }
1215 :
1216 33344707 : if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
1217 33344707 : args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
1218 33344707 : return -ENOSPC;
1219 33344707 :
1220 33344707 : newsize = xfs_attr_sf_totsize(args->dp);
1221 33344707 : 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 140132705 : *========================================================================*/
1235 :
1236 : /* Save the current remote block info and clear the current pointers. */
1237 140132705 : static void
1238 140132705 : xfs_attr_save_rmt_blk(
1239 : struct xfs_da_args *args)
1240 140132705 : {
1241 140220768 : 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 140228505 : args->rmtblkcnt = 0;
1248 140258914 : args->rmtvaluelen = 0;
1249 107599822 : }
1250 107599822 :
1251 0 : /* Set stored info about a remote block */
1252 : static void
1253 32659092 : xfs_attr_restore_rmt_blk(
1254 32659092 : struct xfs_da_args *args)
1255 0 : {
1256 : args->blkno = args->blkno2;
1257 32659092 : args->index = args->index2;
1258 : args->rmtblkno = args->rmtblkno2;
1259 : args->rmtblkcnt = args->rmtblkcnt2;
1260 : args->rmtvaluelen = args->rmtvaluelen2;
1261 : }
1262 :
1263 32651118 : /*
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 140250940 : * 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 309655782 : return error;
1283 :
1284 : /*
1285 : * Look up the xattr name to set the insertion point for the new xattr.
1286 309655782 : */
1287 : error = xfs_attr3_leaf_lookup_int(bp, args);
1288 309655782 : switch (error) {
1289 309588962 : case -ENOATTR:
1290 : if (args->op_flags & XFS_DA_OP_REPLACE)
1291 : goto out_brelse;
1292 309620077 : break;
1293 309704206 : 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 54527246 : break;
1307 : default:
1308 : goto out_brelse;
1309 54527246 : }
1310 54527246 :
1311 54527246 : return xfs_attr3_leaf_add(bp, args);
1312 :
1313 54527246 : out_brelse:
1314 : xfs_trans_brelse(args->trans, bp);
1315 : return error;
1316 : }
1317 :
1318 54506387 : /*
1319 : * Return EEXIST if attr is found, or ENOATTR if not
1320 54506387 : */
1321 54588609 : STATIC int
1322 33 : xfs_attr_leaf_hasname(
1323 33 : struct xfs_da_args *args,
1324 : struct xfs_buf **bp)
1325 0 : {
1326 54588576 : int error = 0;
1327 :
1328 : error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, bp);
1329 54587055 : if (error)
1330 : return error;
1331 :
1332 : error = xfs_attr3_leaf_lookup_int(*bp, args);
1333 : if (error != -ENOATTR && error != -EEXIST)
1334 54580463 : xfs_trans_brelse(args->trans, *bp);
1335 54580676 :
1336 3562536 : 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 30149365 : int error, forkoff;
1352 :
1353 30149365 : trace_xfs_attr_leaf_removename(args);
1354 30149365 :
1355 : /*
1356 30149365 : * Remove the attribute.
1357 : */
1358 30115699 : dp = args->dp;
1359 :
1360 30140894 : error = xfs_attr_leaf_hasname(args, &bp);
1361 11060687 : if (error == -ENOATTR) {
1362 11060687 : xfs_trans_brelse(args->trans, bp);
1363 19080207 : if (args->op_flags & XFS_DA_OP_RECOVERY)
1364 : return 0;
1365 : return error;
1366 : } else if (error != -EEXIST)
1367 19078475 : return error;
1368 19087973 :
1369 19087973 : xfs_attr3_leaf_remove(bp, args);
1370 :
1371 : /*
1372 : * If the result is small enough, shrink it all into the inode.
1373 : */
1374 11196431 : 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 11196431 :
1379 : return 0;
1380 : }
1381 :
1382 : /*
1383 11196431 : * Look up a name in a leaf attribute list structure.
1384 11196573 : *
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 11196553 : *
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 3583030 :
1396 : trace_xfs_attr_leaf_get(args);
1397 :
1398 3583030 : error = xfs_attr_leaf_hasname(args, &bp);
1399 3583030 :
1400 : if (error == -ENOATTR) {
1401 : xfs_trans_brelse(args->trans, bp);
1402 : return error;
1403 : } else if (error != -EEXIST)
1404 : return error;
1405 3583030 :
1406 3583314 :
1407 3583442 : error = xfs_attr3_leaf_getvalue(bp, args);
1408 2895232 : xfs_trans_brelse(args->trans, bp);
1409 2895232 : return error;
1410 0 : }
1411 :
1412 688210 : /* Return EEXIST if attr is found, or ENOATTR if not. */
1413 688210 : STATIC int
1414 0 : xfs_attr_node_lookup(
1415 : struct xfs_da_args *args,
1416 : struct xfs_da_state *state)
1417 688210 : {
1418 : int retval, error;
1419 :
1420 : /*
1421 : * Search to see if name exists, and get back a pointer to it.
1422 : */
1423 688197 : 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 3583305 : case -ENOATTR:
1449 : if (args->op_flags & XFS_DA_OP_REPLACE)
1450 : goto error;
1451 3583305 : break;
1452 3583305 : case -EEXIST:
1453 3583305 : if (!(args->op_flags & XFS_DA_OP_REPLACE))
1454 : goto error;
1455 3583305 :
1456 :
1457 3583236 : trace_xfs_attr_node_replace(args);
1458 3583254 : /*
1459 : * Save the existing remote attr state so that the current
1460 3583254 : * values reflect the state of the new attribute we are about to
1461 3583324 : * add, not the attribute we just found and will remove later.
1462 195164 : */
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 195164 : return error;
1478 195164 : }
1479 11 :
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 3388160 : * leaf nodes and even splitting intermediate nodes up to and including
1485 : * the root node (a special case of an intermediate node).
1486 : */
1487 3583292 : static int
1488 3583292 : xfs_attr_node_try_addname(
1489 3583368 : struct xfs_attr_intent *attr)
1490 3583368 : {
1491 : struct xfs_da_state *state = attr->xattri_da_state;
1492 : struct xfs_da_state_blk *blk;
1493 : int error;
1494 1906436 :
1495 : trace_xfs_attr_node_addname(state->args);
1496 :
1497 : blk = &state->path.blk[state->path.active-1];
1498 1906436 : ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1499 1906436 :
1500 : error = xfs_attr3_leaf_add(blk->bp, state->args);
1501 : if (error == -ENOSPC) {
1502 : if (state->path.active == 1) {
1503 : /*
1504 1906436 : * Its really a single leaf node, but it had
1505 1906436 : * out-of-line values so it looked like it *might*
1506 1906436 : * have been a b-tree. Let the caller deal with this.
1507 1906432 : */
1508 : goto out;
1509 1906430 : }
1510 :
1511 : /*
1512 : * Split as many Btree elements as required.
1513 1906436 : * 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 1906436 : */
1517 1906436 : error = xfs_da3_split(state);
1518 1906436 : if (error)
1519 1906436 : goto out;
1520 : } else {
1521 : /*
1522 : * Addition succeeded, update Btree hashvals.
1523 : */
1524 : xfs_da3_fixhashpath(state, &state->path);
1525 : }
1526 1906436 :
1527 1906436 : out:
1528 1906436 : xfs_da_state_free(state);
1529 0 : attr->xattri_da_state = NULL;
1530 : return error;
1531 1906436 : }
1532 :
1533 : static int
1534 : xfs_attr_node_removename(
1535 : struct xfs_da_args *args,
1536 1906426 : struct xfs_da_state *state)
1537 1904040 : {
1538 1904030 : struct xfs_da_state_blk *blk;
1539 10 : int retval;
1540 :
1541 1906406 : /*
1542 : * Remove the name and update the hashvals in the tree.
1543 1906416 : */
1544 1906416 : blk = &state->path.blk[state->path.active-1];
1545 1906424 : ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1546 : retval = xfs_attr3_leaf_remove(blk->bp, args);
1547 1906414 : 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 963813 :
1561 : /*
1562 : * The attr we are removing has already been marked incomplete, so
1563 963813 : * we need to set the filter appropriately to re-find the "old"
1564 963813 : * attribute entry after any split ops.
1565 963813 : */
1566 963813 : args->attr_filter |= XFS_ATTR_INCOMPLETE;
1567 : error = xfs_da3_node_lookup_int(state, &retval);
1568 963813 : if (error)
1569 : goto out;
1570 :
1571 : error = xfs_attr_node_removename(args, state);
1572 :
1573 963808 : /*
1574 963835 : * Check to see if the tree needs to be collapsed.
1575 963827 : */
1576 227786 : if (retval && (state->path.active > 1)) {
1577 : error = xfs_da3_join(state);
1578 : if (error)
1579 : goto out;
1580 : }
1581 736041 : retval = error = 0;
1582 736032 :
1583 : out:
1584 : xfs_da_state_free(state);
1585 : if (error)
1586 : return error;
1587 963834 : return retval;
1588 2893536 : }
1589 1929685 :
1590 1929701 : /*
1591 : * Retrieve the attribute data from a node attribute list.
1592 : *
1593 963851 : * This routine gets called for any attribute fork that has more than one
1594 963838 : * 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 6820936716 : 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 6820936716 : int i;
1606 759604252 : 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 6061332464 : */
1613 : state = xfs_da_state_alloc(args);
1614 : error = xfs_attr_node_lookup(args, state);
1615 : if (error != -EEXIST)
1616 12122664928 : goto out_release;
1617 :
1618 : /*
1619 : * Get the value, local or "remote"
1620 59 : */
1621 : blk = &state->path.blk[state->path.active - 1];
1622 59 : error = xfs_attr3_leaf_getvalue(blk->bp, args);
1623 :
1624 : /*
1625 : * If not in a transaction, we have to release all the buffers.
1626 59 : */
1627 : out_release:
1628 : for (i = 0; i < state->path.active; i++) {
1629 : xfs_trans_brelse(args->trans, state->path.blk[i].bp);
1630 58 : state->path.blk[i].bp = NULL;
1631 : }
1632 58 :
1633 58 : xfs_da_state_free(state);
1634 58 : 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 : }
|