1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_shared.h"
21#include "xfs_format.h"
22#include "xfs_log_format.h"
23#include "xfs_trans_resv.h"
24#include "xfs_bit.h"
25#include "xfs_sb.h"
26#include "xfs_mount.h"
27#include "xfs_da_format.h"
28#include "xfs_da_btree.h"
29#include "xfs_inode.h"
30#include "xfs_dir2.h"
31#include "xfs_ialloc.h"
32#include "xfs_alloc.h"
33#include "xfs_rtalloc.h"
34#include "xfs_bmap.h"
35#include "xfs_trans.h"
36#include "xfs_trans_priv.h"
37#include "xfs_log.h"
38#include "xfs_error.h"
39#include "xfs_quota.h"
40#include "xfs_fsops.h"
41#include "xfs_trace.h"
42#include "xfs_icache.h"
43#include "xfs_sysfs.h"
44
45
46#ifdef HAVE_PERCPU_SB
47STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t,
48 int);
49STATIC void xfs_icsb_balance_counter_locked(xfs_mount_t *, xfs_sb_field_t,
50 int);
51STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t);
52#else
53
54#define xfs_icsb_balance_counter(mp, a, b) do { } while (0)
55#define xfs_icsb_balance_counter_locked(mp, a, b) do { } while (0)
56#endif
57
58static DEFINE_MUTEX(xfs_uuid_table_mutex);
59static int xfs_uuid_table_size;
60static uuid_t *xfs_uuid_table;
61
62
63
64
65
66STATIC int
67xfs_uuid_mount(
68 struct xfs_mount *mp)
69{
70 uuid_t *uuid = &mp->m_sb.sb_uuid;
71 int hole, i;
72
73 if (mp->m_flags & XFS_MOUNT_NOUUID)
74 return 0;
75
76 if (uuid_is_nil(uuid)) {
77 xfs_warn(mp, "Filesystem has nil UUID - can't mount");
78 return -EINVAL;
79 }
80
81 mutex_lock(&xfs_uuid_table_mutex);
82 for (i = 0, hole = -1; i < xfs_uuid_table_size; i++) {
83 if (uuid_is_nil(&xfs_uuid_table[i])) {
84 hole = i;
85 continue;
86 }
87 if (uuid_equal(uuid, &xfs_uuid_table[i]))
88 goto out_duplicate;
89 }
90
91 if (hole < 0) {
92 xfs_uuid_table = kmem_realloc(xfs_uuid_table,
93 (xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table),
94 xfs_uuid_table_size * sizeof(*xfs_uuid_table),
95 KM_SLEEP);
96 hole = xfs_uuid_table_size++;
97 }
98 xfs_uuid_table[hole] = *uuid;
99 mutex_unlock(&xfs_uuid_table_mutex);
100
101 return 0;
102
103 out_duplicate:
104 mutex_unlock(&xfs_uuid_table_mutex);
105 xfs_warn(mp, "Filesystem has duplicate UUID %pU - can't mount", uuid);
106 return -EINVAL;
107}
108
109STATIC void
110xfs_uuid_unmount(
111 struct xfs_mount *mp)
112{
113 uuid_t *uuid = &mp->m_sb.sb_uuid;
114 int i;
115
116 if (mp->m_flags & XFS_MOUNT_NOUUID)
117 return;
118
119 mutex_lock(&xfs_uuid_table_mutex);
120 for (i = 0; i < xfs_uuid_table_size; i++) {
121 if (uuid_is_nil(&xfs_uuid_table[i]))
122 continue;
123 if (!uuid_equal(uuid, &xfs_uuid_table[i]))
124 continue;
125 memset(&xfs_uuid_table[i], 0, sizeof(uuid_t));
126 break;
127 }
128 ASSERT(i < xfs_uuid_table_size);
129 mutex_unlock(&xfs_uuid_table_mutex);
130}
131
132
133STATIC void
134__xfs_free_perag(
135 struct rcu_head *head)
136{
137 struct xfs_perag *pag = container_of(head, struct xfs_perag, rcu_head);
138
139 ASSERT(atomic_read(&pag->pag_ref) == 0);
140 kmem_free(pag);
141}
142
143
144
145
146STATIC void
147xfs_free_perag(
148 xfs_mount_t *mp)
149{
150 xfs_agnumber_t agno;
151 struct xfs_perag *pag;
152
153 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
154 spin_lock(&mp->m_perag_lock);
155 pag = radix_tree_delete(&mp->m_perag_tree, agno);
156 spin_unlock(&mp->m_perag_lock);
157 ASSERT(pag);
158 ASSERT(atomic_read(&pag->pag_ref) == 0);
159 call_rcu(&pag->rcu_head, __xfs_free_perag);
160 }
161}
162
163
164
165
166
167int
168xfs_sb_validate_fsb_count(
169 xfs_sb_t *sbp,
170 __uint64_t nblocks)
171{
172 ASSERT(PAGE_SHIFT >= sbp->sb_blocklog);
173 ASSERT(sbp->sb_blocklog >= BBSHIFT);
174
175
176 if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX)
177 return -EFBIG;
178 return 0;
179}
180
181int
182xfs_initialize_perag(
183 xfs_mount_t *mp,
184 xfs_agnumber_t agcount,
185 xfs_agnumber_t *maxagi)
186{
187 xfs_agnumber_t index;
188 xfs_agnumber_t first_initialised = 0;
189 xfs_perag_t *pag;
190 xfs_agino_t agino;
191 xfs_ino_t ino;
192 xfs_sb_t *sbp = &mp->m_sb;
193 int error = -ENOMEM;
194
195
196
197
198
199
200 for (index = 0; index < agcount; index++) {
201 pag = xfs_perag_get(mp, index);
202 if (pag) {
203 xfs_perag_put(pag);
204 continue;
205 }
206 if (!first_initialised)
207 first_initialised = index;
208
209 pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL);
210 if (!pag)
211 goto out_unwind;
212 pag->pag_agno = index;
213 pag->pag_mount = mp;
214 spin_lock_init(&pag->pag_ici_lock);
215 mutex_init(&pag->pag_ici_reclaim_lock);
216 INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
217 spin_lock_init(&pag->pag_buf_lock);
218 pag->pag_buf_tree = RB_ROOT;
219
220 if (radix_tree_preload(GFP_NOFS))
221 goto out_unwind;
222
223 spin_lock(&mp->m_perag_lock);
224 if (radix_tree_insert(&mp->m_perag_tree, index, pag)) {
225 BUG();
226 spin_unlock(&mp->m_perag_lock);
227 radix_tree_preload_end();
228 error = -EEXIST;
229 goto out_unwind;
230 }
231 spin_unlock(&mp->m_perag_lock);
232 radix_tree_preload_end();
233 }
234
235
236
237
238
239 agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
240 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
241
242 if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
243 mp->m_flags |= XFS_MOUNT_32BITINODES;
244 else
245 mp->m_flags &= ~XFS_MOUNT_32BITINODES;
246
247 if (mp->m_flags & XFS_MOUNT_32BITINODES)
248 index = xfs_set_inode32(mp, agcount);
249 else
250 index = xfs_set_inode64(mp, agcount);
251
252 if (maxagi)
253 *maxagi = index;
254 return 0;
255
256out_unwind:
257 kmem_free(pag);
258 for (; index > first_initialised; index--) {
259 pag = radix_tree_delete(&mp->m_perag_tree, index);
260 kmem_free(pag);
261 }
262 return error;
263}
264
265
266
267
268
269
270int
271xfs_readsb(
272 struct xfs_mount *mp,
273 int flags)
274{
275 unsigned int sector_size;
276 struct xfs_buf *bp;
277 struct xfs_sb *sbp = &mp->m_sb;
278 int error;
279 int loud = !(flags & XFS_MFSI_QUIET);
280 const struct xfs_buf_ops *buf_ops;
281
282 ASSERT(mp->m_sb_bp == NULL);
283 ASSERT(mp->m_ddev_targp != NULL);
284
285
286
287
288
289
290
291
292 sector_size = xfs_getsize_buftarg(mp->m_ddev_targp);
293 buf_ops = NULL;
294
295
296
297
298
299
300reread:
301 error = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR,
302 BTOBB(sector_size), 0, &bp, buf_ops);
303 if (error) {
304 if (loud)
305 xfs_warn(mp, "SB validate failed with error %d.", error);
306
307 if (error == -EFSBADCRC)
308 error = -EFSCORRUPTED;
309 return error;
310 }
311
312
313
314
315 xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp));
316
317
318
319
320
321 if (sbp->sb_magicnum != XFS_SB_MAGIC) {
322 if (loud)
323 xfs_warn(mp, "Invalid superblock magic number");
324 error = -EINVAL;
325 goto release_buf;
326 }
327
328
329
330
331 if (sector_size > sbp->sb_sectsize) {
332 if (loud)
333 xfs_warn(mp, "device supports %u byte sectors (not %u)",
334 sector_size, sbp->sb_sectsize);
335 error = -ENOSYS;
336 goto release_buf;
337 }
338
339 if (buf_ops == NULL) {
340
341
342
343
344 xfs_buf_relse(bp);
345 sector_size = sbp->sb_sectsize;
346 buf_ops = loud ? &xfs_sb_buf_ops : &xfs_sb_quiet_buf_ops;
347 goto reread;
348 }
349
350
351 xfs_icsb_reinit_counters(mp);
352
353
354 bp->b_ops = &xfs_sb_buf_ops;
355
356 mp->m_sb_bp = bp;
357 xfs_buf_unlock(bp);
358 return 0;
359
360release_buf:
361 xfs_buf_relse(bp);
362 return error;
363}
364
365
366
367
368STATIC int
369xfs_update_alignment(xfs_mount_t *mp)
370{
371 xfs_sb_t *sbp = &(mp->m_sb);
372
373 if (mp->m_dalign) {
374
375
376
377
378 if ((BBTOB(mp->m_dalign) & mp->m_blockmask) ||
379 (BBTOB(mp->m_swidth) & mp->m_blockmask)) {
380 xfs_warn(mp,
381 "alignment check failed: sunit/swidth vs. blocksize(%d)",
382 sbp->sb_blocksize);
383 return -EINVAL;
384 } else {
385
386
387
388 mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign);
389 if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) {
390 xfs_warn(mp,
391 "alignment check failed: sunit/swidth vs. agsize(%d)",
392 sbp->sb_agblocks);
393 return -EINVAL;
394 } else if (mp->m_dalign) {
395 mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth);
396 } else {
397 xfs_warn(mp,
398 "alignment check failed: sunit(%d) less than bsize(%d)",
399 mp->m_dalign, sbp->sb_blocksize);
400 return -EINVAL;
401 }
402 }
403
404
405
406
407
408 if (xfs_sb_version_hasdalign(sbp)) {
409 if (sbp->sb_unit != mp->m_dalign) {
410 sbp->sb_unit = mp->m_dalign;
411 mp->m_update_sb = true;
412 }
413 if (sbp->sb_width != mp->m_swidth) {
414 sbp->sb_width = mp->m_swidth;
415 mp->m_update_sb = true;
416 }
417 } else {
418 xfs_warn(mp,
419 "cannot change alignment: superblock does not support data alignment");
420 return -EINVAL;
421 }
422 } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
423 xfs_sb_version_hasdalign(&mp->m_sb)) {
424 mp->m_dalign = sbp->sb_unit;
425 mp->m_swidth = sbp->sb_width;
426 }
427
428 return 0;
429}
430
431
432
433
434STATIC void
435xfs_set_maxicount(xfs_mount_t *mp)
436{
437 xfs_sb_t *sbp = &(mp->m_sb);
438 __uint64_t icount;
439
440 if (sbp->sb_imax_pct) {
441
442
443
444
445 icount = sbp->sb_dblocks * sbp->sb_imax_pct;
446 do_div(icount, 100);
447 do_div(icount, mp->m_ialloc_blks);
448 mp->m_maxicount = (icount * mp->m_ialloc_blks) <<
449 sbp->sb_inopblog;
450 } else {
451 mp->m_maxicount = 0;
452 }
453}
454
455
456
457
458
459
460
461STATIC void
462xfs_set_rw_sizes(xfs_mount_t *mp)
463{
464 xfs_sb_t *sbp = &(mp->m_sb);
465 int readio_log, writeio_log;
466
467 if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) {
468 if (mp->m_flags & XFS_MOUNT_WSYNC) {
469 readio_log = XFS_WSYNC_READIO_LOG;
470 writeio_log = XFS_WSYNC_WRITEIO_LOG;
471 } else {
472 readio_log = XFS_READIO_LOG_LARGE;
473 writeio_log = XFS_WRITEIO_LOG_LARGE;
474 }
475 } else {
476 readio_log = mp->m_readio_log;
477 writeio_log = mp->m_writeio_log;
478 }
479
480 if (sbp->sb_blocklog > readio_log) {
481 mp->m_readio_log = sbp->sb_blocklog;
482 } else {
483 mp->m_readio_log = readio_log;
484 }
485 mp->m_readio_blocks = 1 << (mp->m_readio_log - sbp->sb_blocklog);
486 if (sbp->sb_blocklog > writeio_log) {
487 mp->m_writeio_log = sbp->sb_blocklog;
488 } else {
489 mp->m_writeio_log = writeio_log;
490 }
491 mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog);
492}
493
494
495
496
497void
498xfs_set_low_space_thresholds(
499 struct xfs_mount *mp)
500{
501 int i;
502
503 for (i = 0; i < XFS_LOWSP_MAX; i++) {
504 __uint64_t space = mp->m_sb.sb_dblocks;
505
506 do_div(space, 100);
507 mp->m_low_space[i] = space * (i + 1);
508 }
509}
510
511
512
513
514
515STATIC void
516xfs_set_inoalignment(xfs_mount_t *mp)
517{
518 if (xfs_sb_version_hasalign(&mp->m_sb) &&
519 mp->m_sb.sb_inoalignmt >=
520 XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
521 mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
522 else
523 mp->m_inoalign_mask = 0;
524
525
526
527
528 if (mp->m_dalign && mp->m_inoalign_mask &&
529 !(mp->m_dalign & mp->m_inoalign_mask))
530 mp->m_sinoalign = mp->m_dalign;
531 else
532 mp->m_sinoalign = 0;
533}
534
535
536
537
538STATIC int
539xfs_check_sizes(
540 struct xfs_mount *mp)
541{
542 struct xfs_buf *bp;
543 xfs_daddr_t d;
544 int error;
545
546 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
547 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
548 xfs_warn(mp, "filesystem size mismatch detected");
549 return -EFBIG;
550 }
551 error = xfs_buf_read_uncached(mp->m_ddev_targp,
552 d - XFS_FSS_TO_BB(mp, 1),
553 XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL);
554 if (error) {
555 xfs_warn(mp, "last sector read failed");
556 return error;
557 }
558 xfs_buf_relse(bp);
559
560 if (mp->m_logdev_targp == mp->m_ddev_targp)
561 return 0;
562
563 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
564 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) {
565 xfs_warn(mp, "log size mismatch detected");
566 return -EFBIG;
567 }
568 error = xfs_buf_read_uncached(mp->m_logdev_targp,
569 d - XFS_FSB_TO_BB(mp, 1),
570 XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
571 if (error) {
572 xfs_warn(mp, "log device read failed");
573 return error;
574 }
575 xfs_buf_relse(bp);
576 return 0;
577}
578
579
580
581
582int
583xfs_mount_reset_sbqflags(
584 struct xfs_mount *mp)
585{
586 mp->m_qflags = 0;
587
588
589 if (mp->m_sb.sb_qflags == 0)
590 return 0;
591 spin_lock(&mp->m_sb_lock);
592 mp->m_sb.sb_qflags = 0;
593 spin_unlock(&mp->m_sb_lock);
594
595 if (!xfs_fs_writable(mp, SB_FREEZE_WRITE))
596 return 0;
597
598 return xfs_sync_sb(mp, false);
599}
600
601__uint64_t
602xfs_default_resblks(xfs_mount_t *mp)
603{
604 __uint64_t resblks;
605
606
607
608
609
610
611
612
613 resblks = mp->m_sb.sb_dblocks;
614 do_div(resblks, 20);
615 resblks = min_t(__uint64_t, resblks, 8192);
616 return resblks;
617}
618
619
620
621
622
623
624
625
626
627
628
629int
630xfs_mountfs(
631 xfs_mount_t *mp)
632{
633 xfs_sb_t *sbp = &(mp->m_sb);
634 xfs_inode_t *rip;
635 __uint64_t resblks;
636 uint quotamount = 0;
637 uint quotaflags = 0;
638 int error = 0;
639
640 xfs_sb_mount_common(mp, sbp);
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658 if (xfs_sb_has_mismatched_features2(sbp)) {
659 xfs_warn(mp, "correcting sb_features alignment problem");
660 sbp->sb_features2 |= sbp->sb_bad_features2;
661 mp->m_update_sb = true;
662
663
664
665
666
667 if (xfs_sb_version_hasattr2(&mp->m_sb) &&
668 !(mp->m_flags & XFS_MOUNT_NOATTR2))
669 mp->m_flags |= XFS_MOUNT_ATTR2;
670 }
671
672 if (xfs_sb_version_hasattr2(&mp->m_sb) &&
673 (mp->m_flags & XFS_MOUNT_NOATTR2)) {
674 xfs_sb_version_removeattr2(&mp->m_sb);
675 mp->m_update_sb = true;
676
677
678 if (!sbp->sb_features2)
679 mp->m_update_sb = true;
680 }
681
682
683 if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) {
684 mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT;
685 mp->m_update_sb = true;
686 }
687
688
689
690
691
692
693
694 error = xfs_update_alignment(mp);
695 if (error)
696 goto out;
697
698 xfs_alloc_compute_maxlevels(mp);
699 xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
700 xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
701 xfs_ialloc_compute_maxlevels(mp);
702
703 xfs_set_maxicount(mp);
704
705 error = xfs_sysfs_init(&mp->m_kobj, &xfs_mp_ktype, NULL, mp->m_fsname);
706 if (error)
707 goto out;
708
709 error = xfs_uuid_mount(mp);
710 if (error)
711 goto out_remove_sysfs;
712
713
714
715
716 xfs_set_rw_sizes(mp);
717
718
719 xfs_set_low_space_thresholds(mp);
720
721
722
723
724
725
726
727
728
729
730
731 mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
732 if (xfs_sb_version_hascrc(&mp->m_sb)) {
733 int new_size = mp->m_inode_cluster_size;
734
735 new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE;
736 if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size))
737 mp->m_inode_cluster_size = new_size;
738 }
739
740
741
742
743 xfs_set_inoalignment(mp);
744
745
746
747
748 error = xfs_check_sizes(mp);
749 if (error)
750 goto out_remove_uuid;
751
752
753
754
755 error = xfs_rtmount_init(mp);
756 if (error) {
757 xfs_warn(mp, "RT mount failed");
758 goto out_remove_uuid;
759 }
760
761
762
763
764
765 uuid_getnodeuniq(&sbp->sb_uuid, mp->m_fixedfsid);
766
767 mp->m_dmevmask = 0;
768
769 error = xfs_da_mount(mp);
770 if (error) {
771 xfs_warn(mp, "Failed dir/attr init: %d", error);
772 goto out_remove_uuid;
773 }
774
775
776
777
778 xfs_trans_init(mp);
779
780
781
782
783 spin_lock_init(&mp->m_perag_lock);
784 INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);
785 error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
786 if (error) {
787 xfs_warn(mp, "Failed per-ag init: %d", error);
788 goto out_free_dir;
789 }
790
791 if (!sbp->sb_logblocks) {
792 xfs_warn(mp, "no log defined");
793 XFS_ERROR_REPORT("xfs_mountfs", XFS_ERRLEVEL_LOW, mp);
794 error = -EFSCORRUPTED;
795 goto out_free_perag;
796 }
797
798
799
800
801 error = xfs_log_mount(mp, mp->m_logdev_targp,
802 XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
803 XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
804 if (error) {
805 xfs_warn(mp, "log mount failed");
806 goto out_fail_wait;
807 }
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828 if (xfs_sb_version_haslazysbcount(&mp->m_sb) &&
829 !XFS_LAST_UNMOUNT_WAS_CLEAN(mp) &&
830 !mp->m_sb.sb_inprogress) {
831 error = xfs_initialize_perag_data(mp, sbp->sb_agcount);
832 if (error)
833 goto out_log_dealloc;
834 }
835
836
837
838
839
840 error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip);
841 if (error) {
842 xfs_warn(mp, "failed to read root inode");
843 goto out_log_dealloc;
844 }
845
846 ASSERT(rip != NULL);
847
848 if (unlikely(!S_ISDIR(rip->i_d.di_mode))) {
849 xfs_warn(mp, "corrupted root inode %llu: not a directory",
850 (unsigned long long)rip->i_ino);
851 xfs_iunlock(rip, XFS_ILOCK_EXCL);
852 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
853 mp);
854 error = -EFSCORRUPTED;
855 goto out_rele_rip;
856 }
857 mp->m_rootip = rip;
858
859 xfs_iunlock(rip, XFS_ILOCK_EXCL);
860
861
862
863
864 error = xfs_rtmount_inodes(mp);
865 if (error) {
866
867
868
869 xfs_warn(mp, "failed to read RT inodes");
870 goto out_rele_rip;
871 }
872
873
874
875
876
877
878 if (mp->m_update_sb && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
879 error = xfs_sync_sb(mp, false);
880 if (error) {
881 xfs_warn(mp, "failed to write sb changes");
882 goto out_rtunmount;
883 }
884 }
885
886
887
888
889 if (XFS_IS_QUOTA_RUNNING(mp)) {
890 error = xfs_qm_newmount(mp, "amount, "aflags);
891 if (error)
892 goto out_rtunmount;
893 } else {
894 ASSERT(!XFS_IS_QUOTA_ON(mp));
895
896
897
898
899
900
901 if (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT) {
902 xfs_notice(mp, "resetting quota flags");
903 error = xfs_mount_reset_sbqflags(mp);
904 if (error)
905 goto out_rtunmount;
906 }
907 }
908
909
910
911
912
913
914 error = xfs_log_mount_finish(mp);
915 if (error) {
916 xfs_warn(mp, "log mount finish failed");
917 goto out_rtunmount;
918 }
919
920
921
922
923 if (quotamount) {
924 ASSERT(mp->m_qflags == 0);
925 mp->m_qflags = quotaflags;
926
927 xfs_qm_mount_quotas(mp);
928 }
929
930
931
932
933
934
935
936
937
938
939
940
941 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
942 resblks = xfs_default_resblks(mp);
943 error = xfs_reserve_blocks(mp, &resblks, NULL);
944 if (error)
945 xfs_warn(mp,
946 "Unable to allocate reserve blocks. Continuing without reserve pool.");
947 }
948
949 return 0;
950
951 out_rtunmount:
952 xfs_rtunmount_inodes(mp);
953 out_rele_rip:
954 IRELE(rip);
955 out_log_dealloc:
956 xfs_log_unmount(mp);
957 out_fail_wait:
958 if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp)
959 xfs_wait_buftarg(mp->m_logdev_targp);
960 xfs_wait_buftarg(mp->m_ddev_targp);
961 out_free_perag:
962 xfs_free_perag(mp);
963 out_free_dir:
964 xfs_da_unmount(mp);
965 out_remove_uuid:
966 xfs_uuid_unmount(mp);
967 out_remove_sysfs:
968 xfs_sysfs_del(&mp->m_kobj);
969 out:
970 return error;
971}
972
973
974
975
976
977void
978xfs_unmountfs(
979 struct xfs_mount *mp)
980{
981 __uint64_t resblks;
982 int error;
983
984 cancel_delayed_work_sync(&mp->m_eofblocks_work);
985
986 xfs_qm_unmount_quotas(mp);
987 xfs_rtunmount_inodes(mp);
988 IRELE(mp->m_rootip);
989
990
991
992
993
994
995
996
997
998
999
1000 xfs_log_force(mp, XFS_LOG_SYNC);
1001
1002
1003
1004
1005 xfs_ail_push_all_sync(mp->m_ail);
1006
1007
1008
1009
1010
1011
1012
1013 cancel_delayed_work_sync(&mp->m_reclaim_work);
1014 xfs_reclaim_inodes(mp, SYNC_WAIT);
1015
1016 xfs_qm_unmount(mp);
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032 resblks = 0;
1033 error = xfs_reserve_blocks(mp, &resblks, NULL);
1034 if (error)
1035 xfs_warn(mp, "Unable to free reserved block pool. "
1036 "Freespace may not be correct on next mount.");
1037
1038 error = xfs_log_sbcount(mp);
1039 if (error)
1040 xfs_warn(mp, "Unable to update superblock counters. "
1041 "Freespace may not be correct on next mount.");
1042
1043 xfs_log_unmount(mp);
1044 xfs_da_unmount(mp);
1045 xfs_uuid_unmount(mp);
1046
1047#if defined(DEBUG)
1048 xfs_errortag_clearall(mp, 0);
1049#endif
1050 xfs_free_perag(mp);
1051
1052 xfs_sysfs_del(&mp->m_kobj);
1053}
1054
1055
1056
1057
1058
1059
1060
1061bool
1062xfs_fs_writable(
1063 struct xfs_mount *mp,
1064 int level)
1065{
1066 ASSERT(level > SB_UNFROZEN);
1067 if ((mp->m_super->s_writers.frozen >= level) ||
1068 XFS_FORCED_SHUTDOWN(mp) || (mp->m_flags & XFS_MOUNT_RDONLY))
1069 return false;
1070
1071 return true;
1072}
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083int
1084xfs_log_sbcount(xfs_mount_t *mp)
1085{
1086
1087 if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE))
1088 return 0;
1089
1090 xfs_icsb_sync_counters(mp, 0);
1091
1092
1093
1094
1095
1096 if (!xfs_sb_version_haslazysbcount(&mp->m_sb))
1097 return 0;
1098
1099 return xfs_sync_sb(mp, true);
1100}
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111STATIC int
1112xfs_mod_incore_sb_unlocked(
1113 xfs_mount_t *mp,
1114 xfs_sb_field_t field,
1115 int64_t delta,
1116 int rsvd)
1117{
1118 int scounter;
1119 long long lcounter;
1120 long long res_used, rem;
1121
1122
1123
1124
1125
1126
1127
1128 switch (field) {
1129 case XFS_SBS_ICOUNT:
1130 lcounter = (long long)mp->m_sb.sb_icount;
1131 lcounter += delta;
1132 if (lcounter < 0) {
1133 ASSERT(0);
1134 return -EINVAL;
1135 }
1136 mp->m_sb.sb_icount = lcounter;
1137 return 0;
1138 case XFS_SBS_IFREE:
1139 lcounter = (long long)mp->m_sb.sb_ifree;
1140 lcounter += delta;
1141 if (lcounter < 0) {
1142 ASSERT(0);
1143 return -EINVAL;
1144 }
1145 mp->m_sb.sb_ifree = lcounter;
1146 return 0;
1147 case XFS_SBS_FDBLOCKS:
1148 lcounter = (long long)
1149 mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
1150 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
1151
1152 if (delta > 0) {
1153 if (res_used > delta) {
1154 mp->m_resblks_avail += delta;
1155 } else {
1156 rem = delta - res_used;
1157 mp->m_resblks_avail = mp->m_resblks;
1158 lcounter += rem;
1159 }
1160 } else {
1161 lcounter += delta;
1162 if (lcounter >= 0) {
1163 mp->m_sb.sb_fdblocks = lcounter +
1164 XFS_ALLOC_SET_ASIDE(mp);
1165 return 0;
1166 }
1167
1168
1169
1170
1171
1172 if (!rsvd)
1173 return -ENOSPC;
1174
1175 lcounter = (long long)mp->m_resblks_avail + delta;
1176 if (lcounter >= 0) {
1177 mp->m_resblks_avail = lcounter;
1178 return 0;
1179 }
1180 printk_once(KERN_WARNING
1181 "Filesystem \"%s\": reserve blocks depleted! "
1182 "Consider increasing reserve pool size.",
1183 mp->m_fsname);
1184 return -ENOSPC;
1185 }
1186
1187 mp->m_sb.sb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp);
1188 return 0;
1189 case XFS_SBS_FREXTENTS:
1190 lcounter = (long long)mp->m_sb.sb_frextents;
1191 lcounter += delta;
1192 if (lcounter < 0) {
1193 return -ENOSPC;
1194 }
1195 mp->m_sb.sb_frextents = lcounter;
1196 return 0;
1197 case XFS_SBS_DBLOCKS:
1198 lcounter = (long long)mp->m_sb.sb_dblocks;
1199 lcounter += delta;
1200 if (lcounter < 0) {
1201 ASSERT(0);
1202 return -EINVAL;
1203 }
1204 mp->m_sb.sb_dblocks = lcounter;
1205 return 0;
1206 case XFS_SBS_AGCOUNT:
1207 scounter = mp->m_sb.sb_agcount;
1208 scounter += delta;
1209 if (scounter < 0) {
1210 ASSERT(0);
1211 return -EINVAL;
1212 }
1213 mp->m_sb.sb_agcount = scounter;
1214 return 0;
1215 case XFS_SBS_IMAX_PCT:
1216 scounter = mp->m_sb.sb_imax_pct;
1217 scounter += delta;
1218 if (scounter < 0) {
1219 ASSERT(0);
1220 return -EINVAL;
1221 }
1222 mp->m_sb.sb_imax_pct = scounter;
1223 return 0;
1224 case XFS_SBS_REXTSIZE:
1225 scounter = mp->m_sb.sb_rextsize;
1226 scounter += delta;
1227 if (scounter < 0) {
1228 ASSERT(0);
1229 return -EINVAL;
1230 }
1231 mp->m_sb.sb_rextsize = scounter;
1232 return 0;
1233 case XFS_SBS_RBMBLOCKS:
1234 scounter = mp->m_sb.sb_rbmblocks;
1235 scounter += delta;
1236 if (scounter < 0) {
1237 ASSERT(0);
1238 return -EINVAL;
1239 }
1240 mp->m_sb.sb_rbmblocks = scounter;
1241 return 0;
1242 case XFS_SBS_RBLOCKS:
1243 lcounter = (long long)mp->m_sb.sb_rblocks;
1244 lcounter += delta;
1245 if (lcounter < 0) {
1246 ASSERT(0);
1247 return -EINVAL;
1248 }
1249 mp->m_sb.sb_rblocks = lcounter;
1250 return 0;
1251 case XFS_SBS_REXTENTS:
1252 lcounter = (long long)mp->m_sb.sb_rextents;
1253 lcounter += delta;
1254 if (lcounter < 0) {
1255 ASSERT(0);
1256 return -EINVAL;
1257 }
1258 mp->m_sb.sb_rextents = lcounter;
1259 return 0;
1260 case XFS_SBS_REXTSLOG:
1261 scounter = mp->m_sb.sb_rextslog;
1262 scounter += delta;
1263 if (scounter < 0) {
1264 ASSERT(0);
1265 return -EINVAL;
1266 }
1267 mp->m_sb.sb_rextslog = scounter;
1268 return 0;
1269 default:
1270 ASSERT(0);
1271 return -EINVAL;
1272 }
1273}
1274
1275
1276
1277
1278
1279
1280
1281int
1282xfs_mod_incore_sb(
1283 struct xfs_mount *mp,
1284 xfs_sb_field_t field,
1285 int64_t delta,
1286 int rsvd)
1287{
1288 int status;
1289
1290#ifdef HAVE_PERCPU_SB
1291 ASSERT(field < XFS_SBS_ICOUNT || field > XFS_SBS_FDBLOCKS);
1292#endif
1293 spin_lock(&mp->m_sb_lock);
1294 status = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd);
1295 spin_unlock(&mp->m_sb_lock);
1296
1297 return status;
1298}
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312int
1313xfs_mod_incore_sb_batch(
1314 struct xfs_mount *mp,
1315 xfs_mod_sb_t *msb,
1316 uint nmsb,
1317 int rsvd)
1318{
1319 xfs_mod_sb_t *msbp;
1320 int error = 0;
1321
1322
1323
1324
1325
1326
1327
1328 spin_lock(&mp->m_sb_lock);
1329 for (msbp = msb; msbp < (msb + nmsb); msbp++) {
1330 ASSERT(msbp->msb_field < XFS_SBS_ICOUNT ||
1331 msbp->msb_field > XFS_SBS_FDBLOCKS);
1332
1333 error = xfs_mod_incore_sb_unlocked(mp, msbp->msb_field,
1334 msbp->msb_delta, rsvd);
1335 if (error)
1336 goto unwind;
1337 }
1338 spin_unlock(&mp->m_sb_lock);
1339 return 0;
1340
1341unwind:
1342 while (--msbp >= msb) {
1343 error = xfs_mod_incore_sb_unlocked(mp, msbp->msb_field,
1344 -msbp->msb_delta, rsvd);
1345 ASSERT(error == 0);
1346 }
1347 spin_unlock(&mp->m_sb_lock);
1348 return error;
1349}
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360struct xfs_buf *
1361xfs_getsb(
1362 struct xfs_mount *mp,
1363 int flags)
1364{
1365 struct xfs_buf *bp = mp->m_sb_bp;
1366
1367 if (!xfs_buf_trylock(bp)) {
1368 if (flags & XBF_TRYLOCK)
1369 return NULL;
1370 xfs_buf_lock(bp);
1371 }
1372
1373 xfs_buf_hold(bp);
1374 ASSERT(XFS_BUF_ISDONE(bp));
1375 return bp;
1376}
1377
1378
1379
1380
1381void
1382xfs_freesb(
1383 struct xfs_mount *mp)
1384{
1385 struct xfs_buf *bp = mp->m_sb_bp;
1386
1387 xfs_buf_lock(bp);
1388 mp->m_sb_bp = NULL;
1389 xfs_buf_relse(bp);
1390}
1391
1392
1393
1394
1395
1396int
1397xfs_dev_is_read_only(
1398 struct xfs_mount *mp,
1399 char *message)
1400{
1401 if (xfs_readonly_buftarg(mp->m_ddev_targp) ||
1402 xfs_readonly_buftarg(mp->m_logdev_targp) ||
1403 (mp->m_rtdev_targp && xfs_readonly_buftarg(mp->m_rtdev_targp))) {
1404 xfs_notice(mp, "%s required on read-only device.", message);
1405 xfs_notice(mp, "write access unavailable, cannot proceed.");
1406 return -EROFS;
1407 }
1408 return 0;
1409}
1410
1411#ifdef HAVE_PERCPU_SB
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464#ifdef CONFIG_HOTPLUG_CPU
1465
1466
1467
1468
1469
1470
1471
1472
1473STATIC int
1474xfs_icsb_cpu_notify(
1475 struct notifier_block *nfb,
1476 unsigned long action,
1477 void *hcpu)
1478{
1479 xfs_icsb_cnts_t *cntp;
1480 xfs_mount_t *mp;
1481
1482 mp = (xfs_mount_t *)container_of(nfb, xfs_mount_t, m_icsb_notifier);
1483 cntp = (xfs_icsb_cnts_t *)
1484 per_cpu_ptr(mp->m_sb_cnts, (unsigned long)hcpu);
1485 switch (action) {
1486 case CPU_UP_PREPARE:
1487 case CPU_UP_PREPARE_FROZEN:
1488
1489
1490 memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
1491 break;
1492 case CPU_ONLINE:
1493 case CPU_ONLINE_FROZEN:
1494 xfs_icsb_lock(mp);
1495 xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0);
1496 xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0);
1497 xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0);
1498 xfs_icsb_unlock(mp);
1499 break;
1500 case CPU_DEAD:
1501 case CPU_DEAD_FROZEN:
1502
1503
1504
1505 xfs_icsb_lock(mp);
1506 spin_lock(&mp->m_sb_lock);
1507 xfs_icsb_disable_counter(mp, XFS_SBS_ICOUNT);
1508 xfs_icsb_disable_counter(mp, XFS_SBS_IFREE);
1509 xfs_icsb_disable_counter(mp, XFS_SBS_FDBLOCKS);
1510
1511 mp->m_sb.sb_icount += cntp->icsb_icount;
1512 mp->m_sb.sb_ifree += cntp->icsb_ifree;
1513 mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks;
1514
1515 memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
1516
1517 xfs_icsb_balance_counter_locked(mp, XFS_SBS_ICOUNT, 0);
1518 xfs_icsb_balance_counter_locked(mp, XFS_SBS_IFREE, 0);
1519 xfs_icsb_balance_counter_locked(mp, XFS_SBS_FDBLOCKS, 0);
1520 spin_unlock(&mp->m_sb_lock);
1521 xfs_icsb_unlock(mp);
1522 break;
1523 }
1524
1525 return NOTIFY_OK;
1526}
1527#endif
1528
1529int
1530xfs_icsb_init_counters(
1531 xfs_mount_t *mp)
1532{
1533 xfs_icsb_cnts_t *cntp;
1534 int i;
1535
1536 mp->m_sb_cnts = alloc_percpu(xfs_icsb_cnts_t);
1537 if (mp->m_sb_cnts == NULL)
1538 return -ENOMEM;
1539
1540 for_each_online_cpu(i) {
1541 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
1542 memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
1543 }
1544
1545 mutex_init(&mp->m_icsb_mutex);
1546
1547
1548
1549
1550
1551 mp->m_icsb_counters = -1;
1552
1553#ifdef CONFIG_HOTPLUG_CPU
1554 mp->m_icsb_notifier.notifier_call = xfs_icsb_cpu_notify;
1555 mp->m_icsb_notifier.priority = 0;
1556 register_hotcpu_notifier(&mp->m_icsb_notifier);
1557#endif
1558
1559 return 0;
1560}
1561
1562void
1563xfs_icsb_reinit_counters(
1564 xfs_mount_t *mp)
1565{
1566 xfs_icsb_lock(mp);
1567
1568
1569
1570
1571 mp->m_icsb_counters = -1;
1572 xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0);
1573 xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0);
1574 xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0);
1575 xfs_icsb_unlock(mp);
1576}
1577
1578void
1579xfs_icsb_destroy_counters(
1580 xfs_mount_t *mp)
1581{
1582 if (mp->m_sb_cnts) {
1583 unregister_hotcpu_notifier(&mp->m_icsb_notifier);
1584 free_percpu(mp->m_sb_cnts);
1585 }
1586 mutex_destroy(&mp->m_icsb_mutex);
1587}
1588
1589STATIC void
1590xfs_icsb_lock_cntr(
1591 xfs_icsb_cnts_t *icsbp)
1592{
1593 while (test_and_set_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags)) {
1594 ndelay(1000);
1595 }
1596}
1597
1598STATIC void
1599xfs_icsb_unlock_cntr(
1600 xfs_icsb_cnts_t *icsbp)
1601{
1602 clear_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags);
1603}
1604
1605
1606STATIC void
1607xfs_icsb_lock_all_counters(
1608 xfs_mount_t *mp)
1609{
1610 xfs_icsb_cnts_t *cntp;
1611 int i;
1612
1613 for_each_online_cpu(i) {
1614 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
1615 xfs_icsb_lock_cntr(cntp);
1616 }
1617}
1618
1619STATIC void
1620xfs_icsb_unlock_all_counters(
1621 xfs_mount_t *mp)
1622{
1623 xfs_icsb_cnts_t *cntp;
1624 int i;
1625
1626 for_each_online_cpu(i) {
1627 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
1628 xfs_icsb_unlock_cntr(cntp);
1629 }
1630}
1631
1632STATIC void
1633xfs_icsb_count(
1634 xfs_mount_t *mp,
1635 xfs_icsb_cnts_t *cnt,
1636 int flags)
1637{
1638 xfs_icsb_cnts_t *cntp;
1639 int i;
1640
1641 memset(cnt, 0, sizeof(xfs_icsb_cnts_t));
1642
1643 if (!(flags & XFS_ICSB_LAZY_COUNT))
1644 xfs_icsb_lock_all_counters(mp);
1645
1646 for_each_online_cpu(i) {
1647 cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
1648 cnt->icsb_icount += cntp->icsb_icount;
1649 cnt->icsb_ifree += cntp->icsb_ifree;
1650 cnt->icsb_fdblocks += cntp->icsb_fdblocks;
1651 }
1652
1653 if (!(flags & XFS_ICSB_LAZY_COUNT))
1654 xfs_icsb_unlock_all_counters(mp);
1655}
1656
1657STATIC int
1658xfs_icsb_counter_disabled(
1659 xfs_mount_t *mp,
1660 xfs_sb_field_t field)
1661{
1662 ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS));
1663 return test_bit(field, &mp->m_icsb_counters);
1664}
1665
1666STATIC void
1667xfs_icsb_disable_counter(
1668 xfs_mount_t *mp,
1669 xfs_sb_field_t field)
1670{
1671 xfs_icsb_cnts_t cnt;
1672
1673 ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS));
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683 if (xfs_icsb_counter_disabled(mp, field))
1684 return;
1685
1686 xfs_icsb_lock_all_counters(mp);
1687 if (!test_and_set_bit(field, &mp->m_icsb_counters)) {
1688
1689
1690 xfs_icsb_count(mp, &cnt, XFS_ICSB_LAZY_COUNT);
1691 switch(field) {
1692 case XFS_SBS_ICOUNT:
1693 mp->m_sb.sb_icount = cnt.icsb_icount;
1694 break;
1695 case XFS_SBS_IFREE:
1696 mp->m_sb.sb_ifree = cnt.icsb_ifree;
1697 break;
1698 case XFS_SBS_FDBLOCKS:
1699 mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks;
1700 break;
1701 default:
1702 BUG();
1703 }
1704 }
1705
1706 xfs_icsb_unlock_all_counters(mp);
1707}
1708
1709STATIC void
1710xfs_icsb_enable_counter(
1711 xfs_mount_t *mp,
1712 xfs_sb_field_t field,
1713 uint64_t count,
1714 uint64_t resid)
1715{
1716 xfs_icsb_cnts_t *cntp;
1717 int i;
1718
1719 ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS));
1720
1721 xfs_icsb_lock_all_counters(mp);
1722 for_each_online_cpu(i) {
1723 cntp = per_cpu_ptr(mp->m_sb_cnts, i);
1724 switch (field) {
1725 case XFS_SBS_ICOUNT:
1726 cntp->icsb_icount = count + resid;
1727 break;
1728 case XFS_SBS_IFREE:
1729 cntp->icsb_ifree = count + resid;
1730 break;
1731 case XFS_SBS_FDBLOCKS:
1732 cntp->icsb_fdblocks = count + resid;
1733 break;
1734 default:
1735 BUG();
1736 break;
1737 }
1738 resid = 0;
1739 }
1740 clear_bit(field, &mp->m_icsb_counters);
1741 xfs_icsb_unlock_all_counters(mp);
1742}
1743
1744void
1745xfs_icsb_sync_counters_locked(
1746 xfs_mount_t *mp,
1747 int flags)
1748{
1749 xfs_icsb_cnts_t cnt;
1750
1751 xfs_icsb_count(mp, &cnt, flags);
1752
1753 if (!xfs_icsb_counter_disabled(mp, XFS_SBS_ICOUNT))
1754 mp->m_sb.sb_icount = cnt.icsb_icount;
1755 if (!xfs_icsb_counter_disabled(mp, XFS_SBS_IFREE))
1756 mp->m_sb.sb_ifree = cnt.icsb_ifree;
1757 if (!xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS))
1758 mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks;
1759}
1760
1761
1762
1763
1764void
1765xfs_icsb_sync_counters(
1766 xfs_mount_t *mp,
1767 int flags)
1768{
1769 spin_lock(&mp->m_sb_lock);
1770 xfs_icsb_sync_counters_locked(mp, flags);
1771 spin_unlock(&mp->m_sb_lock);
1772}
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790#define XFS_ICSB_INO_CNTR_REENABLE (uint64_t)64
1791#define XFS_ICSB_FDBLK_CNTR_REENABLE(mp) \
1792 (uint64_t)(512 + XFS_ALLOC_SET_ASIDE(mp))
1793STATIC void
1794xfs_icsb_balance_counter_locked(
1795 xfs_mount_t *mp,
1796 xfs_sb_field_t field,
1797 int min_per_cpu)
1798{
1799 uint64_t count, resid;
1800 int weight = num_online_cpus();
1801 uint64_t min = (uint64_t)min_per_cpu;
1802
1803
1804 xfs_icsb_disable_counter(mp, field);
1805
1806
1807 switch (field) {
1808 case XFS_SBS_ICOUNT:
1809 count = mp->m_sb.sb_icount;
1810 resid = do_div(count, weight);
1811 if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE))
1812 return;
1813 break;
1814 case XFS_SBS_IFREE:
1815 count = mp->m_sb.sb_ifree;
1816 resid = do_div(count, weight);
1817 if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE))
1818 return;
1819 break;
1820 case XFS_SBS_FDBLOCKS:
1821 count = mp->m_sb.sb_fdblocks;
1822 resid = do_div(count, weight);
1823 if (count < max(min, XFS_ICSB_FDBLK_CNTR_REENABLE(mp)))
1824 return;
1825 break;
1826 default:
1827 BUG();
1828 count = resid = 0;
1829 break;
1830 }
1831
1832 xfs_icsb_enable_counter(mp, field, count, resid);
1833}
1834
1835STATIC void
1836xfs_icsb_balance_counter(
1837 xfs_mount_t *mp,
1838 xfs_sb_field_t fields,
1839 int min_per_cpu)
1840{
1841 spin_lock(&mp->m_sb_lock);
1842 xfs_icsb_balance_counter_locked(mp, fields, min_per_cpu);
1843 spin_unlock(&mp->m_sb_lock);
1844}
1845
1846int
1847xfs_icsb_modify_counters(
1848 xfs_mount_t *mp,
1849 xfs_sb_field_t field,
1850 int64_t delta,
1851 int rsvd)
1852{
1853 xfs_icsb_cnts_t *icsbp;
1854 long long lcounter;
1855 int ret = 0;
1856
1857 might_sleep();
1858again:
1859 preempt_disable();
1860 icsbp = this_cpu_ptr(mp->m_sb_cnts);
1861
1862
1863
1864
1865 if (unlikely(xfs_icsb_counter_disabled(mp, field)))
1866 goto slow_path;
1867 xfs_icsb_lock_cntr(icsbp);
1868 if (unlikely(xfs_icsb_counter_disabled(mp, field))) {
1869 xfs_icsb_unlock_cntr(icsbp);
1870 goto slow_path;
1871 }
1872
1873 switch (field) {
1874 case XFS_SBS_ICOUNT:
1875 lcounter = icsbp->icsb_icount;
1876 lcounter += delta;
1877 if (unlikely(lcounter < 0))
1878 goto balance_counter;
1879 icsbp->icsb_icount = lcounter;
1880 break;
1881
1882 case XFS_SBS_IFREE:
1883 lcounter = icsbp->icsb_ifree;
1884 lcounter += delta;
1885 if (unlikely(lcounter < 0))
1886 goto balance_counter;
1887 icsbp->icsb_ifree = lcounter;
1888 break;
1889
1890 case XFS_SBS_FDBLOCKS:
1891 BUG_ON((mp->m_resblks - mp->m_resblks_avail) != 0);
1892
1893 lcounter = icsbp->icsb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
1894 lcounter += delta;
1895 if (unlikely(lcounter < 0))
1896 goto balance_counter;
1897 icsbp->icsb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp);
1898 break;
1899 default:
1900 BUG();
1901 break;
1902 }
1903 xfs_icsb_unlock_cntr(icsbp);
1904 preempt_enable();
1905 return 0;
1906
1907slow_path:
1908 preempt_enable();
1909
1910
1911
1912
1913
1914
1915 xfs_icsb_lock(mp);
1916
1917
1918
1919
1920
1921
1922
1923 if (!(xfs_icsb_counter_disabled(mp, field))) {
1924 xfs_icsb_unlock(mp);
1925 goto again;
1926 }
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939 spin_lock(&mp->m_sb_lock);
1940 ret = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd);
1941 spin_unlock(&mp->m_sb_lock);
1942
1943
1944
1945
1946
1947
1948
1949 if (ret != -ENOSPC)
1950 xfs_icsb_balance_counter(mp, field, 0);
1951 xfs_icsb_unlock(mp);
1952 return ret;
1953
1954balance_counter:
1955 xfs_icsb_unlock_cntr(icsbp);
1956 preempt_enable();
1957
1958
1959
1960
1961
1962
1963
1964 xfs_icsb_lock(mp);
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974 xfs_icsb_balance_counter(mp, field, delta);
1975 xfs_icsb_unlock(mp);
1976 goto again;
1977}
1978
1979#endif
1980