@@ -1262,10 +1262,18 @@ static int bch2_tmpfile(struct mnt_idmap *idmap,
1262
1262
return finish_open_simple (file , 0 );
1263
1263
}
1264
1264
1265
+ struct bch_fiemap_extent {
1266
+ struct bkey_buf kbuf ;
1267
+ unsigned flags ;
1268
+ };
1269
+
1265
1270
static int bch2_fill_extent (struct bch_fs * c ,
1266
1271
struct fiemap_extent_info * info ,
1267
- struct bkey_s_c k , unsigned flags )
1272
+ struct bch_fiemap_extent * fe )
1268
1273
{
1274
+ struct bkey_s_c k = bkey_i_to_s_c (fe -> kbuf .k );
1275
+ unsigned flags = fe -> flags ;
1276
+
1269
1277
if (bkey_extent_is_direct_data (k .k )) {
1270
1278
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c (k );
1271
1279
const union bch_extent_entry * entry ;
@@ -1318,6 +1326,36 @@ static int bch2_fill_extent(struct bch_fs *c,
1318
1326
}
1319
1327
}
1320
1328
1329
+ static int bch2_fiemap_extent (struct btree_trans * trans ,
1330
+ struct btree_iter * iter , struct bkey_s_c k ,
1331
+ struct bch_fiemap_extent * cur )
1332
+ {
1333
+ s64 offset_into_extent = iter -> pos .offset - bkey_start_offset (k .k );
1334
+ unsigned sectors = k .k -> size - offset_into_extent ;
1335
+
1336
+ bch2_bkey_buf_reassemble (& cur -> kbuf , trans -> c , k );
1337
+
1338
+ enum btree_id data_btree = BTREE_ID_extents ;
1339
+ int ret = bch2_read_indirect_extent (trans , & data_btree , & offset_into_extent ,
1340
+ & cur -> kbuf );
1341
+ if (ret )
1342
+ return ret ;
1343
+
1344
+ k = bkey_i_to_s_c (cur -> kbuf .k );
1345
+ sectors = min_t (unsigned , sectors , k .k -> size - offset_into_extent );
1346
+
1347
+ bch2_cut_front (POS (k .k -> p .inode ,
1348
+ bkey_start_offset (k .k ) + offset_into_extent ),
1349
+ cur -> kbuf .k );
1350
+ bch2_key_resize (& cur -> kbuf .k -> k , sectors );
1351
+ cur -> kbuf .k -> k .p = iter -> pos ;
1352
+ cur -> kbuf .k -> k .p .offset += cur -> kbuf .k -> k .size ;
1353
+
1354
+ cur -> flags = 0 ;
1355
+
1356
+ return 0 ;
1357
+ }
1358
+
1321
1359
static int bch2_fiemap (struct inode * vinode , struct fiemap_extent_info * info ,
1322
1360
u64 start , u64 len )
1323
1361
{
@@ -1326,7 +1364,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
1326
1364
struct btree_trans * trans ;
1327
1365
struct btree_iter iter ;
1328
1366
struct bkey_s_c k ;
1329
- struct bkey_buf cur , prev ;
1367
+ struct bch_fiemap_extent cur , prev ;
1330
1368
bool have_extent = false;
1331
1369
int ret = 0 ;
1332
1370
@@ -1340,15 +1378,14 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
1340
1378
1341
1379
start >>= 9 ;
1342
1380
1343
- bch2_bkey_buf_init (& cur );
1344
- bch2_bkey_buf_init (& prev );
1381
+ bch2_bkey_buf_init (& cur . kbuf );
1382
+ bch2_bkey_buf_init (& prev . kbuf );
1345
1383
trans = bch2_trans_get (c );
1346
1384
1347
1385
bch2_trans_iter_init (trans , & iter , BTREE_ID_extents ,
1348
1386
POS (ei -> v .i_ino , start ), 0 );
1349
1387
1350
1388
while (!ret || bch2_err_matches (ret , BCH_ERR_transaction_restart )) {
1351
- enum btree_id data_btree = BTREE_ID_extents ;
1352
1389
1353
1390
bch2_trans_begin (trans );
1354
1391
@@ -1373,39 +1410,21 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
1373
1410
continue ;
1374
1411
}
1375
1412
1376
- s64 offset_into_extent = iter .pos .offset - bkey_start_offset (k .k );
1377
- unsigned sectors = k .k -> size - offset_into_extent ;
1378
-
1379
- bch2_bkey_buf_reassemble (& cur , c , k );
1380
-
1381
- ret = bch2_read_indirect_extent (trans , & data_btree ,
1382
- & offset_into_extent , & cur );
1413
+ ret = bch2_fiemap_extent (trans , & iter , k , & cur );
1383
1414
if (ret )
1384
- continue ;
1385
-
1386
- k = bkey_i_to_s_c (cur .k );
1387
- bch2_bkey_buf_realloc (& prev , c , k .k -> u64s );
1388
-
1389
- sectors = min_t (unsigned , sectors , k .k -> size - offset_into_extent );
1390
- start = iter .pos .offset + sectors ;
1391
-
1392
- bch2_cut_front (POS (k .k -> p .inode ,
1393
- bkey_start_offset (k .k ) +
1394
- offset_into_extent ),
1395
- cur .k );
1396
- bch2_key_resize (& cur .k -> k , sectors );
1397
- cur .k -> k .p = iter .pos ;
1398
- cur .k -> k .p .offset += cur .k -> k .size ;
1415
+ break ;
1416
+ bch2_bkey_buf_realloc (& prev .kbuf , c , cur .kbuf .k -> k .u64s );
1417
+ start = cur .kbuf .k -> k .p .offset ;
1399
1418
1400
1419
if (have_extent ) {
1401
1420
bch2_trans_unlock (trans );
1402
- ret = bch2_fill_extent (c , info ,
1403
- bkey_i_to_s_c (prev .k ), 0 );
1421
+ ret = bch2_fill_extent (c , info , & prev );
1404
1422
if (ret )
1405
1423
break ;
1406
1424
}
1407
1425
1408
- bkey_copy (prev .k , cur .k );
1426
+ bkey_copy (prev .kbuf .k , cur .kbuf .k );
1427
+ prev .flags = cur .flags ;
1409
1428
have_extent = true;
1410
1429
1411
1430
bch2_btree_iter_set_pos (trans , & iter , POS (iter .pos .inode , start ));
@@ -1414,13 +1433,13 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
1414
1433
1415
1434
if (!ret && have_extent ) {
1416
1435
bch2_trans_unlock (trans );
1417
- ret = bch2_fill_extent ( c , info , bkey_i_to_s_c ( prev . k ),
1418
- FIEMAP_EXTENT_LAST );
1436
+ prev . flags |= FIEMAP_EXTENT_LAST ;
1437
+ ret = bch2_fill_extent ( c , info , & prev );
1419
1438
}
1420
1439
1421
1440
bch2_trans_put (trans );
1422
- bch2_bkey_buf_exit (& cur , c );
1423
- bch2_bkey_buf_exit (& prev , c );
1441
+ bch2_bkey_buf_exit (& cur . kbuf , c );
1442
+ bch2_bkey_buf_exit (& prev . kbuf , c );
1424
1443
return ret < 0 ? ret : 0 ;
1425
1444
}
1426
1445
0 commit comments