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