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