@@ -46,13 +46,16 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
46
46
STATIC int xfs_attr_leaf_get (xfs_da_args_t * args );
47
47
STATIC int xfs_attr_leaf_addname (xfs_da_args_t * args );
48
48
STATIC int xfs_attr_leaf_removename (xfs_da_args_t * args );
49
+ STATIC int xfs_attr_leaf_hasname (struct xfs_da_args * args , struct xfs_buf * * bp );
49
50
50
51
/*
51
52
* Internal routines when attribute list is more than one block.
52
53
*/
53
54
STATIC int xfs_attr_node_get (xfs_da_args_t * args );
54
55
STATIC int xfs_attr_node_addname (xfs_da_args_t * args );
55
56
STATIC int xfs_attr_node_removename (xfs_da_args_t * args );
57
+ STATIC int xfs_attr_node_hasname (xfs_da_args_t * args ,
58
+ struct xfs_da_state * * state );
56
59
STATIC int xfs_attr_fillstate (xfs_da_state_t * state );
57
60
STATIC int xfs_attr_refillstate (xfs_da_state_t * state );
58
61
@@ -260,6 +263,37 @@ xfs_attr_set_args(
260
263
return error ;
261
264
}
262
265
266
+ /*
267
+ * Return EEXIST if attr is found, or ENOATTR if not
268
+ */
269
+ int
270
+ xfs_has_attr (
271
+ struct xfs_da_args * args )
272
+ {
273
+ struct xfs_inode * dp = args -> dp ;
274
+ struct xfs_buf * bp = NULL ;
275
+ int error ;
276
+
277
+ if (!xfs_inode_hasattr (dp ))
278
+ return - ENOATTR ;
279
+
280
+ if (dp -> i_afp -> if_format == XFS_DINODE_FMT_LOCAL ) {
281
+ ASSERT (dp -> i_afp -> if_flags & XFS_IFINLINE );
282
+ return xfs_attr_sf_findname (args , NULL , NULL );
283
+ }
284
+
285
+ if (xfs_bmap_one_block (dp , XFS_ATTR_FORK )) {
286
+ error = xfs_attr_leaf_hasname (args , & bp );
287
+
288
+ if (bp )
289
+ xfs_trans_brelse (args -> trans , bp );
290
+
291
+ return error ;
292
+ }
293
+
294
+ return xfs_attr_node_hasname (args , NULL );
295
+ }
296
+
263
297
/*
264
298
* Remove the attribute specified in @args.
265
299
*/
@@ -469,26 +503,19 @@ STATIC int
469
503
xfs_attr_leaf_addname (
470
504
struct xfs_da_args * args )
471
505
{
472
- struct xfs_inode * dp ;
473
506
struct xfs_buf * bp ;
474
507
int retval , error , forkoff ;
508
+ struct xfs_inode * dp = args -> dp ;
475
509
476
510
trace_xfs_attr_leaf_addname (args );
477
511
478
- /*
479
- * Read the (only) block in the attribute list in.
480
- */
481
- dp = args -> dp ;
482
- args -> blkno = 0 ;
483
- error = xfs_attr3_leaf_read (args -> trans , args -> dp , args -> blkno , & bp );
484
- if (error )
485
- return error ;
486
-
487
512
/*
488
513
* Look up the given attribute in the leaf block. Figure out if
489
514
* the given flags produce an error or call for an atomic rename.
490
515
*/
491
- retval = xfs_attr3_leaf_lookup_int (bp , args );
516
+ retval = xfs_attr_leaf_hasname (args , & bp );
517
+ if (retval != - ENOATTR && retval != - EEXIST )
518
+ return retval ;
492
519
if (retval == - ENOATTR && (args -> attr_flags & XATTR_REPLACE ))
493
520
goto out_brelse ;
494
521
if (retval == - EEXIST ) {
@@ -639,6 +666,27 @@ xfs_attr_leaf_addname(
639
666
return retval ;
640
667
}
641
668
669
+ /*
670
+ * Return EEXIST if attr is found, or ENOATTR if not
671
+ */
672
+ STATIC int
673
+ xfs_attr_leaf_hasname (
674
+ struct xfs_da_args * args ,
675
+ struct xfs_buf * * bp )
676
+ {
677
+ int error = 0 ;
678
+
679
+ error = xfs_attr3_leaf_read (args -> trans , args -> dp , 0 , bp );
680
+ if (error )
681
+ return error ;
682
+
683
+ error = xfs_attr3_leaf_lookup_int (* bp , args );
684
+ if (error != - ENOATTR && error != - EEXIST )
685
+ xfs_trans_brelse (args -> trans , * bp );
686
+
687
+ return error ;
688
+ }
689
+
642
690
/*
643
691
* Remove a name from the leaf attribute list structure
644
692
*
@@ -659,16 +707,14 @@ xfs_attr_leaf_removename(
659
707
* Remove the attribute.
660
708
*/
661
709
dp = args -> dp ;
662
- args -> blkno = 0 ;
663
- error = xfs_attr3_leaf_read (args -> trans , args -> dp , args -> blkno , & bp );
664
- if (error )
665
- return error ;
666
710
667
- error = xfs_attr3_leaf_lookup_int (bp , args );
711
+ error = xfs_attr_leaf_hasname (args , & bp );
712
+
668
713
if (error == - ENOATTR ) {
669
714
xfs_trans_brelse (args -> trans , bp );
670
715
return error ;
671
- }
716
+ } else if (error != - EEXIST )
717
+ return error ;
672
718
673
719
xfs_attr3_leaf_remove (bp , args );
674
720
@@ -703,21 +749,53 @@ xfs_attr_leaf_get(xfs_da_args_t *args)
703
749
704
750
trace_xfs_attr_leaf_get (args );
705
751
706
- args -> blkno = 0 ;
707
- error = xfs_attr3_leaf_read (args -> trans , args -> dp , args -> blkno , & bp );
708
- if (error )
709
- return error ;
752
+ error = xfs_attr_leaf_hasname (args , & bp );
710
753
711
- error = xfs_attr3_leaf_lookup_int (bp , args );
712
- if (error != - EEXIST ) {
754
+ if (error == - ENOATTR ) {
713
755
xfs_trans_brelse (args -> trans , bp );
714
756
return error ;
715
- }
757
+ } else if (error != - EEXIST )
758
+ return error ;
759
+
760
+
716
761
error = xfs_attr3_leaf_getvalue (bp , args );
717
762
xfs_trans_brelse (args -> trans , bp );
718
763
return error ;
719
764
}
720
765
766
+ /*
767
+ * Return EEXIST if attr is found, or ENOATTR if not
768
+ * statep: If not null is set to point at the found state. Caller will
769
+ * be responsible for freeing the state in this case.
770
+ */
771
+ STATIC int
772
+ xfs_attr_node_hasname (
773
+ struct xfs_da_args * args ,
774
+ struct xfs_da_state * * statep )
775
+ {
776
+ struct xfs_da_state * state ;
777
+ int retval , error ;
778
+
779
+ state = xfs_da_state_alloc (args );
780
+ if (statep != NULL )
781
+ * statep = NULL ;
782
+
783
+ /*
784
+ * Search to see if name exists, and get back a pointer to it.
785
+ */
786
+ error = xfs_da3_node_lookup_int (state , & retval );
787
+ if (error ) {
788
+ xfs_da_state_free (state );
789
+ return error ;
790
+ }
791
+
792
+ if (statep != NULL )
793
+ * statep = state ;
794
+ else
795
+ xfs_da_state_free (state );
796
+ return retval ;
797
+ }
798
+
721
799
/*========================================================================
722
800
* External routines when attribute list size > geo->blksize
723
801
*========================================================================*/
@@ -748,15 +826,14 @@ xfs_attr_node_addname(
748
826
*/
749
827
dp = args -> dp ;
750
828
restart :
751
- state = xfs_da_state_alloc (args );
752
-
753
829
/*
754
830
* Search to see if name already exists, and get back a pointer
755
831
* to where it should go.
756
832
*/
757
- error = xfs_da3_node_lookup_int ( state , & retval );
758
- if (error )
833
+ retval = xfs_attr_node_hasname ( args , & state );
834
+ if (retval != - ENOATTR && retval != - EEXIST )
759
835
goto out ;
836
+
760
837
blk = & state -> path .blk [ state -> path .active - 1 ];
761
838
ASSERT (blk -> magic == XFS_ATTR_LEAF_MAGIC );
762
839
if (retval == - ENOATTR && (args -> attr_flags & XATTR_REPLACE ))
@@ -960,27 +1037,15 @@ xfs_attr_node_removename(
960
1037
{
961
1038
struct xfs_da_state * state ;
962
1039
struct xfs_da_state_blk * blk ;
963
- struct xfs_inode * dp ;
964
1040
struct xfs_buf * bp ;
965
1041
int retval , error , forkoff ;
1042
+ struct xfs_inode * dp = args -> dp ;
966
1043
967
1044
trace_xfs_attr_node_removename (args );
968
1045
969
- /*
970
- * Tie a string around our finger to remind us where we are.
971
- */
972
- dp = args -> dp ;
973
- state = xfs_da_state_alloc (args );
974
-
975
- /*
976
- * Search to see if name exists, and get back a pointer to it.
977
- */
978
- error = xfs_da3_node_lookup_int (state , & retval );
979
- if (error || (retval != - EEXIST )) {
980
- if (error == 0 )
981
- error = retval ;
1046
+ error = xfs_attr_node_hasname (args , & state );
1047
+ if (error != - EEXIST )
982
1048
goto out ;
983
- }
984
1049
985
1050
/*
986
1051
* If there is an out-of-line value, de-allocate the blocks.
@@ -1075,7 +1140,8 @@ xfs_attr_node_removename(
1075
1140
error = 0 ;
1076
1141
1077
1142
out :
1078
- xfs_da_state_free (state );
1143
+ if (state )
1144
+ xfs_da_state_free (state );
1079
1145
return error ;
1080
1146
}
1081
1147
@@ -1191,45 +1257,41 @@ xfs_attr_refillstate(xfs_da_state_t *state)
1191
1257
* Returns 0 on successful retrieval, otherwise an error.
1192
1258
*/
1193
1259
STATIC int
1194
- xfs_attr_node_get (xfs_da_args_t * args )
1260
+ xfs_attr_node_get (
1261
+ struct xfs_da_args * args )
1195
1262
{
1196
- xfs_da_state_t * state ;
1197
- xfs_da_state_blk_t * blk ;
1198
- int error , retval ;
1199
- int i ;
1263
+ struct xfs_da_state * state ;
1264
+ struct xfs_da_state_blk * blk ;
1265
+ int i ;
1266
+ int error ;
1200
1267
1201
1268
trace_xfs_attr_node_get (args );
1202
1269
1203
- state = xfs_da_state_alloc (args );
1204
-
1205
1270
/*
1206
1271
* Search to see if name exists, and get back a pointer to it.
1207
1272
*/
1208
- error = xfs_da3_node_lookup_int (state , & retval );
1209
- if (error ) {
1210
- retval = error ;
1211
- goto out_release ;
1212
- }
1213
- if (retval != - EEXIST )
1273
+ error = xfs_attr_node_hasname (args , & state );
1274
+ if (error != - EEXIST )
1214
1275
goto out_release ;
1215
1276
1216
1277
/*
1217
1278
* Get the value, local or "remote"
1218
1279
*/
1219
1280
blk = & state -> path .blk [state -> path .active - 1 ];
1220
- retval = xfs_attr3_leaf_getvalue (blk -> bp , args );
1281
+ error = xfs_attr3_leaf_getvalue (blk -> bp , args );
1221
1282
1222
1283
/*
1223
1284
* If not in a transaction, we have to release all the buffers.
1224
1285
*/
1225
1286
out_release :
1226
- for (i = 0 ; i < state -> path .active ; i ++ ) {
1287
+ for (i = 0 ; state != NULL && i < state -> path .active ; i ++ ) {
1227
1288
xfs_trans_brelse (args -> trans , state -> path .blk [i ].bp );
1228
1289
state -> path .blk [i ].bp = NULL ;
1229
1290
}
1230
1291
1231
- xfs_da_state_free (state );
1232
- return retval ;
1292
+ if (state )
1293
+ xfs_da_state_free (state );
1294
+ return error ;
1233
1295
}
1234
1296
1235
1297
/* Returns true if the attribute entry name is valid. */
0 commit comments