@@ -1337,54 +1337,54 @@ xfs_find_get_desired_pgoff(
1337
1337
return found ;
1338
1338
}
1339
1339
1340
- STATIC loff_t
1341
- xfs_seek_hole_data (
1342
- struct file * file ,
1340
+ /*
1341
+ * caller must lock inode with xfs_ilock_data_map_shared,
1342
+ * can we craft an appropriate ASSERT?
1343
+ *
1344
+ * end is because the VFS-level lseek interface is defined such that any
1345
+ * offset past i_size shall return -ENXIO, but we use this for quota code
1346
+ * which does not maintain i_size, and we want to SEEK_DATA past i_size.
1347
+ */
1348
+ loff_t
1349
+ __xfs_seek_hole_data (
1350
+ struct inode * inode ,
1343
1351
loff_t start ,
1352
+ loff_t end ,
1344
1353
int whence )
1345
1354
{
1346
- struct inode * inode = file -> f_mapping -> host ;
1347
1355
struct xfs_inode * ip = XFS_I (inode );
1348
1356
struct xfs_mount * mp = ip -> i_mount ;
1349
1357
loff_t uninitialized_var (offset );
1350
- xfs_fsize_t isize ;
1351
1358
xfs_fileoff_t fsbno ;
1352
- xfs_filblks_t end ;
1353
- uint lock ;
1359
+ xfs_filblks_t lastbno ;
1354
1360
int error ;
1355
1361
1356
- if (XFS_FORCED_SHUTDOWN (mp ))
1357
- return - EIO ;
1358
-
1359
- lock = xfs_ilock_data_map_shared (ip );
1360
-
1361
- isize = i_size_read (inode );
1362
- if (start >= isize ) {
1362
+ if (start >= end ) {
1363
1363
error = - ENXIO ;
1364
- goto out_unlock ;
1364
+ goto out_error ;
1365
1365
}
1366
1366
1367
1367
/*
1368
1368
* Try to read extents from the first block indicated
1369
1369
* by fsbno to the end block of the file.
1370
1370
*/
1371
1371
fsbno = XFS_B_TO_FSBT (mp , start );
1372
- end = XFS_B_TO_FSB (mp , isize );
1372
+ lastbno = XFS_B_TO_FSB (mp , end );
1373
1373
1374
1374
for (;;) {
1375
1375
struct xfs_bmbt_irec map [2 ];
1376
1376
int nmap = 2 ;
1377
1377
unsigned int i ;
1378
1378
1379
- error = xfs_bmapi_read (ip , fsbno , end - fsbno , map , & nmap ,
1379
+ error = xfs_bmapi_read (ip , fsbno , lastbno - fsbno , map , & nmap ,
1380
1380
XFS_BMAPI_ENTIRE );
1381
1381
if (error )
1382
- goto out_unlock ;
1382
+ goto out_error ;
1383
1383
1384
1384
/* No extents at given offset, must be beyond EOF */
1385
1385
if (nmap == 0 ) {
1386
1386
error = - ENXIO ;
1387
- goto out_unlock ;
1387
+ goto out_error ;
1388
1388
}
1389
1389
1390
1390
for (i = 0 ; i < nmap ; i ++ ) {
@@ -1426,15 +1426,15 @@ xfs_seek_hole_data(
1426
1426
* hole at the end of any file).
1427
1427
*/
1428
1428
if (whence == SEEK_HOLE ) {
1429
- offset = isize ;
1429
+ offset = end ;
1430
1430
break ;
1431
1431
}
1432
1432
/*
1433
1433
* If we were looking for data, it's nowhere to be found
1434
1434
*/
1435
1435
ASSERT (whence == SEEK_DATA );
1436
1436
error = - ENXIO ;
1437
- goto out_unlock ;
1437
+ goto out_error ;
1438
1438
}
1439
1439
1440
1440
ASSERT (i > 1 );
@@ -1445,14 +1445,14 @@ xfs_seek_hole_data(
1445
1445
*/
1446
1446
fsbno = map [i - 1 ].br_startoff + map [i - 1 ].br_blockcount ;
1447
1447
start = XFS_FSB_TO_B (mp , fsbno );
1448
- if (start >= isize ) {
1448
+ if (start >= end ) {
1449
1449
if (whence == SEEK_HOLE ) {
1450
- offset = isize ;
1450
+ offset = end ;
1451
1451
break ;
1452
1452
}
1453
1453
ASSERT (whence == SEEK_DATA );
1454
1454
error = - ENXIO ;
1455
- goto out_unlock ;
1455
+ goto out_error ;
1456
1456
}
1457
1457
}
1458
1458
@@ -1464,7 +1464,39 @@ xfs_seek_hole_data(
1464
1464
* situation in particular.
1465
1465
*/
1466
1466
if (whence == SEEK_HOLE )
1467
- offset = min_t (loff_t , offset , isize );
1467
+ offset = min_t (loff_t , offset , end );
1468
+
1469
+ return offset ;
1470
+
1471
+ out_error :
1472
+ return error ;
1473
+ }
1474
+
1475
+ STATIC loff_t
1476
+ xfs_seek_hole_data (
1477
+ struct file * file ,
1478
+ loff_t start ,
1479
+ int whence )
1480
+ {
1481
+ struct inode * inode = file -> f_mapping -> host ;
1482
+ struct xfs_inode * ip = XFS_I (inode );
1483
+ struct xfs_mount * mp = ip -> i_mount ;
1484
+ uint lock ;
1485
+ loff_t offset , end ;
1486
+ int error = 0 ;
1487
+
1488
+ if (XFS_FORCED_SHUTDOWN (mp ))
1489
+ return - EIO ;
1490
+
1491
+ lock = xfs_ilock_data_map_shared (ip );
1492
+
1493
+ end = i_size_read (inode );
1494
+ offset = __xfs_seek_hole_data (inode , start , end , whence );
1495
+ if (offset < 0 ) {
1496
+ error = offset ;
1497
+ goto out_unlock ;
1498
+ }
1499
+
1468
1500
offset = vfs_setpos (file , offset , inode -> i_sb -> s_maxbytes );
1469
1501
1470
1502
out_unlock :
0 commit comments