@@ -440,81 +440,50 @@ xfs_attr_rmtval_get(
440
440
}
441
441
442
442
/*
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
445
445
*/
446
- int
447
- xfs_attr_rmtval_set (
446
+ STATIC int
447
+ xfs_attr_rmt_find_hole (
448
448
struct xfs_da_args * args )
449
449
{
450
450
struct xfs_inode * dp = args -> dp ;
451
451
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 ;
459
452
int error ;
460
- int offset = 0 ;
461
-
462
- trace_xfs_attr_rmtval_set (args );
453
+ int blkcnt ;
454
+ xfs_fileoff_t lfileoff = 0 ;
463
455
464
456
/*
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.
469
460
*/
470
461
blkcnt = xfs_attr3_rmt_blocks (mp , args -> rmtvaluelen );
471
462
error = xfs_bmap_first_unused (args -> trans , args -> dp , blkcnt , & lfileoff ,
472
463
XFS_ATTR_FORK );
473
464
if (error )
474
465
return error ;
475
466
476
- args -> rmtblkno = lblkno = (xfs_dablk_t )lfileoff ;
467
+ args -> rmtblkno = (xfs_dablk_t )lfileoff ;
477
468
args -> rmtblkcnt = blkcnt ;
478
469
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
+ }
510
472
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 ;
518
487
519
488
/*
520
489
* Roll through the "value", copying the attribute value to the
@@ -594,6 +563,72 @@ xfs_attr_rmtval_stale(
594
563
return 0 ;
595
564
}
596
565
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
+
597
632
/*
598
633
* Remove the value associated with an attribute by deleting the
599
634
* out-of-line buffer that it is stored on.
0 commit comments