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