hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/fs/xfs/xfs_fsops.c
....@@ -11,15 +11,11 @@
1111 #include "xfs_trans_resv.h"
1212 #include "xfs_sb.h"
1313 #include "xfs_mount.h"
14
-#include "xfs_defer.h"
1514 #include "xfs_trans.h"
1615 #include "xfs_error.h"
17
-#include "xfs_btree.h"
1816 #include "xfs_alloc.h"
1917 #include "xfs_fsops.h"
2018 #include "xfs_trans_space.h"
21
-#include "xfs_rtalloc.h"
22
-#include "xfs_trace.h"
2319 #include "xfs_log.h"
2420 #include "xfs_ag.h"
2521 #include "xfs_ag_resv.h"
....@@ -40,7 +36,6 @@
4036 xfs_rfsblock_t new;
4137 xfs_agnumber_t oagcount;
4238 xfs_trans_t *tp;
43
- LIST_HEAD (buffer_list);
4439 struct aghdr_init_data id = {};
4540
4641 nb = in->newblocks;
....@@ -252,9 +247,9 @@
252247 if (mp->m_sb.sb_imax_pct) {
253248 uint64_t icount = mp->m_sb.sb_dblocks * mp->m_sb.sb_imax_pct;
254249 do_div(icount, 100);
255
- mp->m_maxicount = icount << mp->m_sb.sb_inopblog;
250
+ M_IGEO(mp)->maxicount = XFS_FSB_TO_INO(mp, icount);
256251 } else
257
- mp->m_maxicount = 0;
252
+ M_IGEO(mp)->maxicount = 0;
258253
259254 /* Update secondary superblocks now the physical grow has completed */
260255 error = xfs_update_secondary_sbs(mp);
....@@ -290,7 +285,7 @@
290285 * exported through ioctl XFS_IOC_FSCOUNTS
291286 */
292287
293
-int
288
+void
294289 xfs_fs_counts(
295290 xfs_mount_t *mp,
296291 xfs_fsop_counts_t *cnt)
....@@ -303,7 +298,6 @@
303298 spin_lock(&mp->m_sb_lock);
304299 cnt->freertx = mp->m_sb.sb_frextents;
305300 spin_unlock(&mp->m_sb_lock);
306
- return 0;
307301 }
308302
309303 /*
....@@ -382,46 +376,36 @@
382376 * If the request is larger than the current reservation, reserve the
383377 * blocks before we update the reserve counters. Sample m_fdblocks and
384378 * perform a partial reservation if the request exceeds free space.
379
+ *
380
+ * The code below estimates how many blocks it can request from
381
+ * fdblocks to stash in the reserve pool. This is a classic TOCTOU
382
+ * race since fdblocks updates are not always coordinated via
383
+ * m_sb_lock. Set the reserve size even if there's not enough free
384
+ * space to fill it because mod_fdblocks will refill an undersized
385
+ * reserve when it can.
385386 */
386
- error = -ENOSPC;
387
- do {
388
- free = percpu_counter_sum(&mp->m_fdblocks) -
389
- mp->m_alloc_set_aside;
390
- if (free <= 0)
391
- break;
392
-
393
- delta = request - mp->m_resblks;
394
- lcounter = free - delta;
395
- if (lcounter < 0)
396
- /* We can't satisfy the request, just get what we can */
397
- fdblks_delta = free;
398
- else
399
- fdblks_delta = delta;
400
-
387
+ free = percpu_counter_sum(&mp->m_fdblocks) -
388
+ xfs_fdblocks_unavailable(mp);
389
+ delta = request - mp->m_resblks;
390
+ mp->m_resblks = request;
391
+ if (delta > 0 && free > 0) {
401392 /*
402393 * We'll either succeed in getting space from the free block
403
- * count or we'll get an ENOSPC. If we get a ENOSPC, it means
404
- * things changed while we were calculating fdblks_delta and so
405
- * we should try again to see if there is anything left to
406
- * reserve.
394
+ * count or we'll get an ENOSPC. Don't set the reserved flag
395
+ * here - we don't want to reserve the extra reserve blocks
396
+ * from the reserve.
407397 *
408
- * Don't set the reserved flag here - we don't want to reserve
409
- * the extra reserve blocks from the reserve.....
398
+ * The desired reserve size can change after we drop the lock.
399
+ * Use mod_fdblocks to put the space into the reserve or into
400
+ * fdblocks as appropriate.
410401 */
402
+ fdblks_delta = min(free, delta);
411403 spin_unlock(&mp->m_sb_lock);
412404 error = xfs_mod_fdblocks(mp, -fdblks_delta, 0);
405
+ if (!error)
406
+ xfs_mod_fdblocks(mp, fdblks_delta, 0);
413407 spin_lock(&mp->m_sb_lock);
414
- } while (error == -ENOSPC);
415
-
416
- /*
417
- * Update the reserve counters if blocks have been successfully
418
- * allocated.
419
- */
420
- if (!error && fdblks_delta) {
421
- mp->m_resblks += fdblks_delta;
422
- mp->m_resblks_avail += fdblks_delta;
423408 }
424
-
425409 out:
426410 if (outval) {
427411 outval->resblks = mp->m_resblks;
....@@ -439,13 +423,10 @@
439423 {
440424 switch (inflags) {
441425 case XFS_FSOP_GOING_FLAGS_DEFAULT: {
442
- struct super_block *sb = freeze_bdev(mp->m_super->s_bdev);
443
-
444
- if (sb && !IS_ERR(sb)) {
426
+ if (!freeze_bdev(mp->m_super->s_bdev)) {
445427 xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
446
- thaw_bdev(sb->s_bdev, sb);
428
+ thaw_bdev(mp->m_super->s_bdev);
447429 }
448
-
449430 break;
450431 }
451432 case XFS_FSOP_GOING_FLAGS_LOGFLUSH:
....@@ -470,20 +451,13 @@
470451 */
471452 void
472453 xfs_do_force_shutdown(
473
- xfs_mount_t *mp,
454
+ struct xfs_mount *mp,
474455 int flags,
475456 char *fname,
476457 int lnnum)
477458 {
478
- int logerror;
459
+ bool logerror = flags & SHUTDOWN_LOG_IO_ERROR;
479460
480
- logerror = flags & SHUTDOWN_LOG_IO_ERROR;
481
-
482
- if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
483
- xfs_notice(mp,
484
- "%s(0x%x) called from line %d of file %s. Return address = "PTR_FMT,
485
- __func__, flags, lnnum, fname, __return_address);
486
- }
487461 /*
488462 * No need to duplicate efforts.
489463 */
....@@ -499,27 +473,31 @@
499473 if (xfs_log_force_umount(mp, logerror))
500474 return;
501475
476
+ if (flags & SHUTDOWN_FORCE_UMOUNT) {
477
+ xfs_alert(mp,
478
+"User initiated shutdown received. Shutting down filesystem");
479
+ return;
480
+ }
481
+
482
+ xfs_notice(mp,
483
+"%s(0x%x) called from line %d of file %s. Return address = "PTR_FMT,
484
+ __func__, flags, lnnum, fname, __return_address);
485
+
502486 if (flags & SHUTDOWN_CORRUPT_INCORE) {
503487 xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_CORRUPT,
504
- "Corruption of in-memory data detected. Shutting down filesystem");
488
+"Corruption of in-memory data detected. Shutting down filesystem");
505489 if (XFS_ERRLEVEL_HIGH <= xfs_error_level)
506490 xfs_stack_trace();
507
- } else if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
508
- if (logerror) {
509
- xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_LOGERROR,
510
- "Log I/O Error Detected. Shutting down filesystem");
511
- } else if (flags & SHUTDOWN_DEVICE_REQ) {
512
- xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_IOERROR,
513
- "All device paths lost. Shutting down filesystem");
514
- } else if (!(flags & SHUTDOWN_REMOTE_REQ)) {
515
- xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_IOERROR,
516
- "I/O Error Detected. Shutting down filesystem");
517
- }
491
+ } else if (logerror) {
492
+ xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_LOGERROR,
493
+ "Log I/O Error Detected. Shutting down filesystem");
494
+ } else {
495
+ xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_IOERROR,
496
+ "I/O Error Detected. Shutting down filesystem");
518497 }
519
- if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
520
- xfs_alert(mp,
521
- "Please umount the filesystem and rectify the problem(s)");
522
- }
498
+
499
+ xfs_alert(mp,
500
+ "Please unmount the filesystem and rectify the problem(s)");
523501 }
524502
525503 /*