Skip to content

Commit 1a485fc

Browse files
allisonhendersondjwong
authored andcommitted
xfs: Factor out new helper functions xfs_attr_rmtval_set
Break xfs_attr_rmtval_set into two helper functions xfs_attr_rmt_find_hole and xfs_attr_rmtval_set_value. xfs_attr_rmtval_set rolls the transaction between the helpers, but delayed operations cannot. We will use the helpers later when constructing new delayed attribute routines. Signed-off-by: Allison Collins <[email protected]> Reviewed-by: Brian Foster <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Reviewed-by: Chandan Rajendra <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]> Acked-by: Dave Chinner <[email protected]>
1 parent deed951 commit 1a485fc

File tree

1 file changed

+92
-57
lines changed

1 file changed

+92
-57
lines changed

fs/xfs/libxfs/xfs_attr_remote.c

Lines changed: 92 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -440,81 +440,50 @@ xfs_attr_rmtval_get(
440440
}
441441

442442
/*
443-
* Write the value associated with an attribute into the out-of-line buffer
444-
* that we have defined for it.
443+
* Find a "hole" in the attribute address space large enough for us to drop the
444+
* new attribute's value into
445445
*/
446-
int
447-
xfs_attr_rmtval_set(
446+
STATIC int
447+
xfs_attr_rmt_find_hole(
448448
struct xfs_da_args *args)
449449
{
450450
struct xfs_inode *dp = args->dp;
451451
struct xfs_mount *mp = dp->i_mount;
452-
struct xfs_bmbt_irec map;
453-
xfs_dablk_t lblkno;
454-
xfs_fileoff_t lfileoff = 0;
455-
uint8_t *src = args->value;
456-
int blkcnt;
457-
int valuelen;
458-
int nmap;
459452
int error;
460-
int offset = 0;
461-
462-
trace_xfs_attr_rmtval_set(args);
453+
int blkcnt;
454+
xfs_fileoff_t lfileoff = 0;
463455

464456
/*
465-
* Find a "hole" in the attribute address space large enough for
466-
* us to drop the new attribute's value into. Because CRC enable
467-
* attributes have headers, we can't just do a straight byte to FSB
468-
* conversion and have to take the header space into account.
457+
* Because CRC enable attributes have headers, we can't just do a
458+
* straight byte to FSB conversion and have to take the header space
459+
* into account.
469460
*/
470461
blkcnt = xfs_attr3_rmt_blocks(mp, args->rmtvaluelen);
471462
error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff,
472463
XFS_ATTR_FORK);
473464
if (error)
474465
return error;
475466

476-
args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff;
467+
args->rmtblkno = (xfs_dablk_t)lfileoff;
477468
args->rmtblkcnt = blkcnt;
478469

479-
/*
480-
* Roll through the "value", allocating blocks on disk as required.
481-
*/
482-
while (blkcnt > 0) {
483-
/*
484-
* Allocate a single extent, up to the size of the value.
485-
*
486-
* Note that we have to consider this a data allocation as we
487-
* write the remote attribute without logging the contents.
488-
* Hence we must ensure that we aren't using blocks that are on
489-
* the busy list so that we don't overwrite blocks which have
490-
* recently been freed but their transactions are not yet
491-
* committed to disk. If we overwrite the contents of a busy
492-
* extent and then crash then the block may not contain the
493-
* correct metadata after log recovery occurs.
494-
*/
495-
nmap = 1;
496-
error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno,
497-
blkcnt, XFS_BMAPI_ATTRFORK, args->total, &map,
498-
&nmap);
499-
if (error)
500-
return error;
501-
error = xfs_defer_finish(&args->trans);
502-
if (error)
503-
return error;
504-
505-
ASSERT(nmap == 1);
506-
ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
507-
(map.br_startblock != HOLESTARTBLOCK));
508-
lblkno += map.br_blockcount;
509-
blkcnt -= map.br_blockcount;
470+
return 0;
471+
}
510472

511-
/*
512-
* Start the next trans in the chain.
513-
*/
514-
error = xfs_trans_roll_inode(&args->trans, dp);
515-
if (error)
516-
return error;
517-
}
473+
STATIC int
474+
xfs_attr_rmtval_set_value(
475+
struct xfs_da_args *args)
476+
{
477+
struct xfs_inode *dp = args->dp;
478+
struct xfs_mount *mp = dp->i_mount;
479+
struct xfs_bmbt_irec map;
480+
xfs_dablk_t lblkno;
481+
uint8_t *src = args->value;
482+
int blkcnt;
483+
int valuelen;
484+
int nmap;
485+
int error;
486+
int offset = 0;
518487

519488
/*
520489
* Roll through the "value", copying the attribute value to the
@@ -594,6 +563,72 @@ xfs_attr_rmtval_stale(
594563
return 0;
595564
}
596565

566+
/*
567+
* Write the value associated with an attribute into the out-of-line buffer
568+
* that we have defined for it.
569+
*/
570+
int
571+
xfs_attr_rmtval_set(
572+
struct xfs_da_args *args)
573+
{
574+
struct xfs_inode *dp = args->dp;
575+
struct xfs_bmbt_irec map;
576+
xfs_dablk_t lblkno;
577+
int blkcnt;
578+
int nmap;
579+
int error;
580+
581+
trace_xfs_attr_rmtval_set(args);
582+
583+
error = xfs_attr_rmt_find_hole(args);
584+
if (error)
585+
return error;
586+
587+
blkcnt = args->rmtblkcnt;
588+
lblkno = (xfs_dablk_t)args->rmtblkno;
589+
/*
590+
* Roll through the "value", allocating blocks on disk as required.
591+
*/
592+
while (blkcnt > 0) {
593+
/*
594+
* Allocate a single extent, up to the size of the value.
595+
*
596+
* Note that we have to consider this a data allocation as we
597+
* write the remote attribute without logging the contents.
598+
* Hence we must ensure that we aren't using blocks that are on
599+
* the busy list so that we don't overwrite blocks which have
600+
* recently been freed but their transactions are not yet
601+
* committed to disk. If we overwrite the contents of a busy
602+
* extent and then crash then the block may not contain the
603+
* correct metadata after log recovery occurs.
604+
*/
605+
nmap = 1;
606+
error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno,
607+
blkcnt, XFS_BMAPI_ATTRFORK, args->total, &map,
608+
&nmap);
609+
if (error)
610+
return error;
611+
error = xfs_defer_finish(&args->trans);
612+
if (error)
613+
return error;
614+
615+
ASSERT(nmap == 1);
616+
ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
617+
(map.br_startblock != HOLESTARTBLOCK));
618+
lblkno += map.br_blockcount;
619+
blkcnt -= map.br_blockcount;
620+
621+
/*
622+
* Start the next trans in the chain.
623+
*/
624+
error = xfs_trans_roll_inode(&args->trans, dp);
625+
if (error)
626+
return error;
627+
}
628+
629+
return xfs_attr_rmtval_set_value(args);
630+
}
631+
597632
/*
598633
* Remove the value associated with an attribute by deleting the
599634
* out-of-line buffer that it is stored on.

0 commit comments

Comments
 (0)