22
22
#include "ulist.h"
23
23
#include "transaction.h"
24
24
#include "delayed-ref.h"
25
+ #include "locking.h"
25
26
26
27
/*
27
28
* this structure records all encountered refs on the way up to the root
@@ -893,18 +894,22 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
893
894
s64 bytes_left = size - 1 ;
894
895
struct extent_buffer * eb = eb_in ;
895
896
struct btrfs_key found_key ;
897
+ int leave_spinning = path -> leave_spinning ;
896
898
897
899
if (bytes_left >= 0 )
898
900
dest [bytes_left ] = '\0' ;
899
901
902
+ path -> leave_spinning = 1 ;
900
903
while (1 ) {
901
904
len = btrfs_inode_ref_name_len (eb , iref );
902
905
bytes_left -= len ;
903
906
if (bytes_left >= 0 )
904
907
read_extent_buffer (eb , dest + bytes_left ,
905
908
(unsigned long )(iref + 1 ), len );
906
- if (eb != eb_in )
909
+ if (eb != eb_in ) {
910
+ btrfs_tree_read_unlock_blocking (eb );
907
911
free_extent_buffer (eb );
912
+ }
908
913
ret = inode_ref_info (parent , 0 , fs_root , path , & found_key );
909
914
if (ret > 0 )
910
915
ret = - ENOENT ;
@@ -919,8 +924,11 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
919
924
slot = path -> slots [0 ];
920
925
eb = path -> nodes [0 ];
921
926
/* make sure we can use eb after releasing the path */
922
- if (eb != eb_in )
927
+ if (eb != eb_in ) {
923
928
atomic_inc (& eb -> refs );
929
+ btrfs_tree_read_lock (eb );
930
+ btrfs_set_lock_blocking_rw (eb , BTRFS_READ_LOCK );
931
+ }
924
932
btrfs_release_path (path );
925
933
926
934
iref = btrfs_item_ptr (eb , slot , struct btrfs_inode_ref );
@@ -931,6 +939,7 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
931
939
}
932
940
933
941
btrfs_release_path (path );
942
+ path -> leave_spinning = leave_spinning ;
934
943
935
944
if (ret )
936
945
return ERR_PTR (ret );
@@ -1260,6 +1269,7 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
1260
1269
struct btrfs_key found_key ;
1261
1270
1262
1271
while (!ret ) {
1272
+ path -> leave_spinning = 1 ;
1263
1273
ret = inode_ref_info (inum , parent ? parent + 1 : 0 , fs_root , path ,
1264
1274
& found_key );
1265
1275
if (ret < 0 )
@@ -1275,6 +1285,8 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
1275
1285
eb = path -> nodes [0 ];
1276
1286
/* make sure we can use eb after releasing the path */
1277
1287
atomic_inc (& eb -> refs );
1288
+ btrfs_tree_read_lock (eb );
1289
+ btrfs_set_lock_blocking_rw (eb , BTRFS_READ_LOCK );
1278
1290
btrfs_release_path (path );
1279
1291
1280
1292
item = btrfs_item_nr (eb , slot );
@@ -1293,6 +1305,7 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
1293
1305
len = sizeof (* iref ) + name_len ;
1294
1306
iref = (struct btrfs_inode_ref * )((char * )iref + len );
1295
1307
}
1308
+ btrfs_tree_read_unlock_blocking (eb );
1296
1309
free_extent_buffer (eb );
1297
1310
}
1298
1311
0 commit comments