diff options
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 242 |
1 files changed, 118 insertions, 124 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index a66b39805176..ebdb76da527c 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -139,7 +139,7 @@ xfs_mount_init(void) | |||
139 | AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail"); | 139 | AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail"); |
140 | spinlock_init(&mp->m_sb_lock, "xfs_sb"); | 140 | spinlock_init(&mp->m_sb_lock, "xfs_sb"); |
141 | mutex_init(&mp->m_ilock); | 141 | mutex_init(&mp->m_ilock); |
142 | initnsema(&mp->m_growlock, 1, "xfs_grow"); | 142 | mutex_init(&mp->m_growlock); |
143 | /* | 143 | /* |
144 | * Initialize the AIL. | 144 | * Initialize the AIL. |
145 | */ | 145 | */ |
@@ -157,14 +157,8 @@ xfs_mount_init(void) | |||
157 | */ | 157 | */ |
158 | void | 158 | void |
159 | xfs_mount_free( | 159 | xfs_mount_free( |
160 | xfs_mount_t *mp, | 160 | xfs_mount_t *mp) |
161 | int remove_bhv) | ||
162 | { | 161 | { |
163 | if (mp->m_ihash) | ||
164 | xfs_ihash_free(mp); | ||
165 | if (mp->m_chash) | ||
166 | xfs_chash_free(mp); | ||
167 | |||
168 | if (mp->m_perag) { | 162 | if (mp->m_perag) { |
169 | int agno; | 163 | int agno; |
170 | 164 | ||
@@ -180,7 +174,7 @@ xfs_mount_free( | |||
180 | AIL_LOCK_DESTROY(&mp->m_ail_lock); | 174 | AIL_LOCK_DESTROY(&mp->m_ail_lock); |
181 | spinlock_destroy(&mp->m_sb_lock); | 175 | spinlock_destroy(&mp->m_sb_lock); |
182 | mutex_destroy(&mp->m_ilock); | 176 | mutex_destroy(&mp->m_ilock); |
183 | freesema(&mp->m_growlock); | 177 | mutex_destroy(&mp->m_growlock); |
184 | if (mp->m_quotainfo) | 178 | if (mp->m_quotainfo) |
185 | XFS_QM_DONE(mp); | 179 | XFS_QM_DONE(mp); |
186 | 180 | ||
@@ -191,15 +185,7 @@ xfs_mount_free( | |||
191 | if (mp->m_logname != NULL) | 185 | if (mp->m_logname != NULL) |
192 | kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); | 186 | kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); |
193 | 187 | ||
194 | if (remove_bhv) { | ||
195 | struct bhv_vfs *vfsp = XFS_MTOVFS(mp); | ||
196 | |||
197 | bhv_remove_all_vfsops(vfsp, 0); | ||
198 | VFS_REMOVEBHV(vfsp, &mp->m_bhv); | ||
199 | } | ||
200 | |||
201 | xfs_icsb_destroy_counters(mp); | 188 | xfs_icsb_destroy_counters(mp); |
202 | kmem_free(mp, sizeof(xfs_mount_t)); | ||
203 | } | 189 | } |
204 | 190 | ||
205 | /* | 191 | /* |
@@ -342,9 +328,19 @@ xfs_mount_validate_sb( | |||
342 | return 0; | 328 | return 0; |
343 | } | 329 | } |
344 | 330 | ||
331 | STATIC void | ||
332 | xfs_initialize_perag_icache( | ||
333 | xfs_perag_t *pag) | ||
334 | { | ||
335 | if (!pag->pag_ici_init) { | ||
336 | rwlock_init(&pag->pag_ici_lock); | ||
337 | INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); | ||
338 | pag->pag_ici_init = 1; | ||
339 | } | ||
340 | } | ||
341 | |||
345 | xfs_agnumber_t | 342 | xfs_agnumber_t |
346 | xfs_initialize_perag( | 343 | xfs_initialize_perag( |
347 | bhv_vfs_t *vfs, | ||
348 | xfs_mount_t *mp, | 344 | xfs_mount_t *mp, |
349 | xfs_agnumber_t agcount) | 345 | xfs_agnumber_t agcount) |
350 | { | 346 | { |
@@ -362,7 +358,7 @@ xfs_initialize_perag( | |||
362 | /* Clear the mount flag if no inode can overflow 32 bits | 358 | /* Clear the mount flag if no inode can overflow 32 bits |
363 | * on this filesystem, or if specifically requested.. | 359 | * on this filesystem, or if specifically requested.. |
364 | */ | 360 | */ |
365 | if ((vfs->vfs_flag & VFS_32BITINODES) && ino > max_inum) { | 361 | if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) { |
366 | mp->m_flags |= XFS_MOUNT_32BITINODES; | 362 | mp->m_flags |= XFS_MOUNT_32BITINODES; |
367 | } else { | 363 | } else { |
368 | mp->m_flags &= ~XFS_MOUNT_32BITINODES; | 364 | mp->m_flags &= ~XFS_MOUNT_32BITINODES; |
@@ -396,48 +392,92 @@ xfs_initialize_perag( | |||
396 | pag->pagi_inodeok = 1; | 392 | pag->pagi_inodeok = 1; |
397 | if (index < max_metadata) | 393 | if (index < max_metadata) |
398 | pag->pagf_metadata = 1; | 394 | pag->pagf_metadata = 1; |
395 | xfs_initialize_perag_icache(pag); | ||
399 | } | 396 | } |
400 | } else { | 397 | } else { |
401 | /* Setup default behavior for smaller filesystems */ | 398 | /* Setup default behavior for smaller filesystems */ |
402 | for (index = 0; index < agcount; index++) { | 399 | for (index = 0; index < agcount; index++) { |
403 | pag = &mp->m_perag[index]; | 400 | pag = &mp->m_perag[index]; |
404 | pag->pagi_inodeok = 1; | 401 | pag->pagi_inodeok = 1; |
402 | xfs_initialize_perag_icache(pag); | ||
405 | } | 403 | } |
406 | } | 404 | } |
407 | return index; | 405 | return index; |
408 | } | 406 | } |
409 | 407 | ||
408 | void | ||
409 | xfs_sb_from_disk( | ||
410 | xfs_sb_t *to, | ||
411 | xfs_dsb_t *from) | ||
412 | { | ||
413 | to->sb_magicnum = be32_to_cpu(from->sb_magicnum); | ||
414 | to->sb_blocksize = be32_to_cpu(from->sb_blocksize); | ||
415 | to->sb_dblocks = be64_to_cpu(from->sb_dblocks); | ||
416 | to->sb_rblocks = be64_to_cpu(from->sb_rblocks); | ||
417 | to->sb_rextents = be64_to_cpu(from->sb_rextents); | ||
418 | memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid)); | ||
419 | to->sb_logstart = be64_to_cpu(from->sb_logstart); | ||
420 | to->sb_rootino = be64_to_cpu(from->sb_rootino); | ||
421 | to->sb_rbmino = be64_to_cpu(from->sb_rbmino); | ||
422 | to->sb_rsumino = be64_to_cpu(from->sb_rsumino); | ||
423 | to->sb_rextsize = be32_to_cpu(from->sb_rextsize); | ||
424 | to->sb_agblocks = be32_to_cpu(from->sb_agblocks); | ||
425 | to->sb_agcount = be32_to_cpu(from->sb_agcount); | ||
426 | to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks); | ||
427 | to->sb_logblocks = be32_to_cpu(from->sb_logblocks); | ||
428 | to->sb_versionnum = be16_to_cpu(from->sb_versionnum); | ||
429 | to->sb_sectsize = be16_to_cpu(from->sb_sectsize); | ||
430 | to->sb_inodesize = be16_to_cpu(from->sb_inodesize); | ||
431 | to->sb_inopblock = be16_to_cpu(from->sb_inopblock); | ||
432 | memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname)); | ||
433 | to->sb_blocklog = from->sb_blocklog; | ||
434 | to->sb_sectlog = from->sb_sectlog; | ||
435 | to->sb_inodelog = from->sb_inodelog; | ||
436 | to->sb_inopblog = from->sb_inopblog; | ||
437 | to->sb_agblklog = from->sb_agblklog; | ||
438 | to->sb_rextslog = from->sb_rextslog; | ||
439 | to->sb_inprogress = from->sb_inprogress; | ||
440 | to->sb_imax_pct = from->sb_imax_pct; | ||
441 | to->sb_icount = be64_to_cpu(from->sb_icount); | ||
442 | to->sb_ifree = be64_to_cpu(from->sb_ifree); | ||
443 | to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks); | ||
444 | to->sb_frextents = be64_to_cpu(from->sb_frextents); | ||
445 | to->sb_uquotino = be64_to_cpu(from->sb_uquotino); | ||
446 | to->sb_gquotino = be64_to_cpu(from->sb_gquotino); | ||
447 | to->sb_qflags = be16_to_cpu(from->sb_qflags); | ||
448 | to->sb_flags = from->sb_flags; | ||
449 | to->sb_shared_vn = from->sb_shared_vn; | ||
450 | to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt); | ||
451 | to->sb_unit = be32_to_cpu(from->sb_unit); | ||
452 | to->sb_width = be32_to_cpu(from->sb_width); | ||
453 | to->sb_dirblklog = from->sb_dirblklog; | ||
454 | to->sb_logsectlog = from->sb_logsectlog; | ||
455 | to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); | ||
456 | to->sb_logsunit = be32_to_cpu(from->sb_logsunit); | ||
457 | to->sb_features2 = be32_to_cpu(from->sb_features2); | ||
458 | } | ||
459 | |||
410 | /* | 460 | /* |
411 | * xfs_xlatesb | 461 | * Copy in core superblock to ondisk one. |
412 | * | 462 | * |
413 | * data - on disk version of sb | 463 | * The fields argument is mask of superblock fields to copy. |
414 | * sb - a superblock | ||
415 | * dir - conversion direction: <0 - convert sb to buf | ||
416 | * >0 - convert buf to sb | ||
417 | * fields - which fields to copy (bitmask) | ||
418 | */ | 464 | */ |
419 | void | 465 | void |
420 | xfs_xlatesb( | 466 | xfs_sb_to_disk( |
421 | void *data, | 467 | xfs_dsb_t *to, |
422 | xfs_sb_t *sb, | 468 | xfs_sb_t *from, |
423 | int dir, | ||
424 | __int64_t fields) | 469 | __int64_t fields) |
425 | { | 470 | { |
426 | xfs_caddr_t buf_ptr; | 471 | xfs_caddr_t to_ptr = (xfs_caddr_t)to; |
427 | xfs_caddr_t mem_ptr; | 472 | xfs_caddr_t from_ptr = (xfs_caddr_t)from; |
428 | xfs_sb_field_t f; | 473 | xfs_sb_field_t f; |
429 | int first; | 474 | int first; |
430 | int size; | 475 | int size; |
431 | 476 | ||
432 | ASSERT(dir); | ||
433 | ASSERT(fields); | 477 | ASSERT(fields); |
434 | |||
435 | if (!fields) | 478 | if (!fields) |
436 | return; | 479 | return; |
437 | 480 | ||
438 | buf_ptr = (xfs_caddr_t)data; | ||
439 | mem_ptr = (xfs_caddr_t)sb; | ||
440 | |||
441 | while (fields) { | 481 | while (fields) { |
442 | f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); | 482 | f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); |
443 | first = xfs_sb_info[f].offset; | 483 | first = xfs_sb_info[f].offset; |
@@ -446,26 +486,20 @@ xfs_xlatesb( | |||
446 | ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); | 486 | ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); |
447 | 487 | ||
448 | if (size == 1 || xfs_sb_info[f].type == 1) { | 488 | if (size == 1 || xfs_sb_info[f].type == 1) { |
449 | if (dir > 0) { | 489 | memcpy(to_ptr + first, from_ptr + first, size); |
450 | memcpy(mem_ptr + first, buf_ptr + first, size); | ||
451 | } else { | ||
452 | memcpy(buf_ptr + first, mem_ptr + first, size); | ||
453 | } | ||
454 | } else { | 490 | } else { |
455 | switch (size) { | 491 | switch (size) { |
456 | case 2: | 492 | case 2: |
457 | INT_XLATE(*(__uint16_t*)(buf_ptr+first), | 493 | *(__be16 *)(to_ptr + first) = |
458 | *(__uint16_t*)(mem_ptr+first), | 494 | cpu_to_be16(*(__u16 *)(from_ptr + first)); |
459 | dir, ARCH_CONVERT); | ||
460 | break; | 495 | break; |
461 | case 4: | 496 | case 4: |
462 | INT_XLATE(*(__uint32_t*)(buf_ptr+first), | 497 | *(__be32 *)(to_ptr + first) = |
463 | *(__uint32_t*)(mem_ptr+first), | 498 | cpu_to_be32(*(__u32 *)(from_ptr + first)); |
464 | dir, ARCH_CONVERT); | ||
465 | break; | 499 | break; |
466 | case 8: | 500 | case 8: |
467 | INT_XLATE(*(__uint64_t*)(buf_ptr+first), | 501 | *(__be64 *)(to_ptr + first) = |
468 | *(__uint64_t*)(mem_ptr+first), dir, ARCH_CONVERT); | 502 | cpu_to_be64(*(__u64 *)(from_ptr + first)); |
469 | break; | 503 | break; |
470 | default: | 504 | default: |
471 | ASSERT(0); | 505 | ASSERT(0); |
@@ -487,7 +521,6 @@ xfs_readsb(xfs_mount_t *mp, int flags) | |||
487 | unsigned int sector_size; | 521 | unsigned int sector_size; |
488 | unsigned int extra_flags; | 522 | unsigned int extra_flags; |
489 | xfs_buf_t *bp; | 523 | xfs_buf_t *bp; |
490 | xfs_sb_t *sbp; | ||
491 | int error; | 524 | int error; |
492 | 525 | ||
493 | ASSERT(mp->m_sb_bp == NULL); | 526 | ASSERT(mp->m_sb_bp == NULL); |
@@ -515,8 +548,7 @@ xfs_readsb(xfs_mount_t *mp, int flags) | |||
515 | * Initialize the mount structure from the superblock. | 548 | * Initialize the mount structure from the superblock. |
516 | * But first do some basic consistency checking. | 549 | * But first do some basic consistency checking. |
517 | */ | 550 | */ |
518 | sbp = XFS_BUF_TO_SBP(bp); | 551 | xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp)); |
519 | xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, XFS_SB_ALL_BITS); | ||
520 | 552 | ||
521 | error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags); | 553 | error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags); |
522 | if (error) { | 554 | if (error) { |
@@ -715,7 +747,6 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) | |||
715 | */ | 747 | */ |
716 | int | 748 | int |
717 | xfs_mountfs( | 749 | xfs_mountfs( |
718 | bhv_vfs_t *vfsp, | ||
719 | xfs_mount_t *mp, | 750 | xfs_mount_t *mp, |
720 | int mfsi_flags) | 751 | int mfsi_flags) |
721 | { | 752 | { |
@@ -842,14 +873,11 @@ xfs_mountfs( | |||
842 | */ | 873 | */ |
843 | if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && | 874 | if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && |
844 | (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { | 875 | (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { |
845 | __uint64_t ret64; | ||
846 | if (xfs_uuid_mount(mp)) { | 876 | if (xfs_uuid_mount(mp)) { |
847 | error = XFS_ERROR(EINVAL); | 877 | error = XFS_ERROR(EINVAL); |
848 | goto error1; | 878 | goto error1; |
849 | } | 879 | } |
850 | uuid_mounted=1; | 880 | uuid_mounted=1; |
851 | ret64 = uuid_hash64(&sbp->sb_uuid); | ||
852 | memcpy(&vfsp->vfs_fsid, &ret64, sizeof(ret64)); | ||
853 | } | 881 | } |
854 | 882 | ||
855 | /* | 883 | /* |
@@ -871,16 +899,6 @@ xfs_mountfs( | |||
871 | writeio_log = mp->m_writeio_log; | 899 | writeio_log = mp->m_writeio_log; |
872 | } | 900 | } |
873 | 901 | ||
874 | /* | ||
875 | * Set the number of readahead buffers to use based on | ||
876 | * physical memory size. | ||
877 | */ | ||
878 | if (xfs_physmem <= 4096) /* <= 16MB */ | ||
879 | mp->m_nreadaheads = XFS_RW_NREADAHEAD_16MB; | ||
880 | else if (xfs_physmem <= 8192) /* <= 32MB */ | ||
881 | mp->m_nreadaheads = XFS_RW_NREADAHEAD_32MB; | ||
882 | else | ||
883 | mp->m_nreadaheads = XFS_RW_NREADAHEAD_K32; | ||
884 | if (sbp->sb_blocklog > readio_log) { | 902 | if (sbp->sb_blocklog > readio_log) { |
885 | mp->m_readio_log = sbp->sb_blocklog; | 903 | mp->m_readio_log = sbp->sb_blocklog; |
886 | } else { | 904 | } else { |
@@ -895,15 +913,12 @@ xfs_mountfs( | |||
895 | mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog); | 913 | mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog); |
896 | 914 | ||
897 | /* | 915 | /* |
898 | * Set the inode cluster size based on the physical memory | 916 | * Set the inode cluster size. |
899 | * size. This may still be overridden by the file system | 917 | * This may still be overridden by the file system |
900 | * block size if it is larger than the chosen cluster size. | 918 | * block size if it is larger than the chosen cluster size. |
901 | */ | 919 | */ |
902 | if (xfs_physmem <= btoc(32 * 1024 * 1024)) { /* <= 32 MB */ | 920 | mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; |
903 | mp->m_inode_cluster_size = XFS_INODE_SMALL_CLUSTER_SIZE; | 921 | |
904 | } else { | ||
905 | mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; | ||
906 | } | ||
907 | /* | 922 | /* |
908 | * Set whether we're using inode alignment. | 923 | * Set whether we're using inode alignment. |
909 | */ | 924 | */ |
@@ -987,16 +1002,6 @@ xfs_mountfs( | |||
987 | */ | 1002 | */ |
988 | uuid_getnodeuniq(&sbp->sb_uuid, mp->m_fixedfsid); | 1003 | uuid_getnodeuniq(&sbp->sb_uuid, mp->m_fixedfsid); |
989 | 1004 | ||
990 | /* | ||
991 | * The vfs structure needs to have a file system independent | ||
992 | * way of checking for the invariant file system ID. Since it | ||
993 | * can't look at mount structures it has a pointer to the data | ||
994 | * in the mount structure. | ||
995 | * | ||
996 | * File systems that don't support user level file handles (i.e. | ||
997 | * all of them except for XFS) will leave vfs_altfsid as NULL. | ||
998 | */ | ||
999 | vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid; | ||
1000 | mp->m_dmevmask = 0; /* not persistent; set after each mount */ | 1005 | mp->m_dmevmask = 0; /* not persistent; set after each mount */ |
1001 | 1006 | ||
1002 | xfs_dir_mount(mp); | 1007 | xfs_dir_mount(mp); |
@@ -1012,20 +1017,13 @@ xfs_mountfs( | |||
1012 | xfs_trans_init(mp); | 1017 | xfs_trans_init(mp); |
1013 | 1018 | ||
1014 | /* | 1019 | /* |
1015 | * Allocate and initialize the inode hash table for this | ||
1016 | * file system. | ||
1017 | */ | ||
1018 | xfs_ihash_init(mp); | ||
1019 | xfs_chash_init(mp); | ||
1020 | |||
1021 | /* | ||
1022 | * Allocate and initialize the per-ag data. | 1020 | * Allocate and initialize the per-ag data. |
1023 | */ | 1021 | */ |
1024 | init_rwsem(&mp->m_peraglock); | 1022 | init_rwsem(&mp->m_peraglock); |
1025 | mp->m_perag = | 1023 | mp->m_perag = |
1026 | kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP); | 1024 | kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP); |
1027 | 1025 | ||
1028 | mp->m_maxagi = xfs_initialize_perag(vfsp, mp, sbp->sb_agcount); | 1026 | mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount); |
1029 | 1027 | ||
1030 | /* | 1028 | /* |
1031 | * log's mount-time initialization. Perform 1st part recovery if needed | 1029 | * log's mount-time initialization. Perform 1st part recovery if needed |
@@ -1116,7 +1114,7 @@ xfs_mountfs( | |||
1116 | * If fs is not mounted readonly, then update the superblock | 1114 | * If fs is not mounted readonly, then update the superblock |
1117 | * unit and width changes. | 1115 | * unit and width changes. |
1118 | */ | 1116 | */ |
1119 | if (update_flags && !(vfsp->vfs_flag & VFS_RDONLY)) | 1117 | if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) |
1120 | xfs_mount_log_sbunit(mp, update_flags); | 1118 | xfs_mount_log_sbunit(mp, update_flags); |
1121 | 1119 | ||
1122 | /* | 1120 | /* |
@@ -1169,8 +1167,6 @@ xfs_mountfs( | |||
1169 | error3: | 1167 | error3: |
1170 | xfs_log_unmount_dealloc(mp); | 1168 | xfs_log_unmount_dealloc(mp); |
1171 | error2: | 1169 | error2: |
1172 | xfs_ihash_free(mp); | ||
1173 | xfs_chash_free(mp); | ||
1174 | for (agno = 0; agno < sbp->sb_agcount; agno++) | 1170 | for (agno = 0; agno < sbp->sb_agcount; agno++) |
1175 | if (mp->m_perag[agno].pagb_list) | 1171 | if (mp->m_perag[agno].pagb_list) |
1176 | kmem_free(mp->m_perag[agno].pagb_list, | 1172 | kmem_free(mp->m_perag[agno].pagb_list, |
@@ -1194,10 +1190,6 @@ xfs_mountfs( | |||
1194 | int | 1190 | int |
1195 | xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | 1191 | xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) |
1196 | { | 1192 | { |
1197 | struct bhv_vfs *vfsp = XFS_MTOVFS(mp); | ||
1198 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) | ||
1199 | int64_t fsid; | ||
1200 | #endif | ||
1201 | __uint64_t resblks; | 1193 | __uint64_t resblks; |
1202 | 1194 | ||
1203 | /* | 1195 | /* |
@@ -1261,21 +1253,17 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1261 | xfs_uuid_unmount(mp); | 1253 | xfs_uuid_unmount(mp); |
1262 | 1254 | ||
1263 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) | 1255 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) |
1264 | /* | 1256 | xfs_errortag_clearall(mp, 0); |
1265 | * clear all error tags on this filesystem | ||
1266 | */ | ||
1267 | memcpy(&fsid, &vfsp->vfs_fsid, sizeof(int64_t)); | ||
1268 | xfs_errortag_clearall_umount(fsid, mp->m_fsname, 0); | ||
1269 | #endif | 1257 | #endif |
1270 | XFS_IODONE(vfsp); | 1258 | XFS_IODONE(mp); |
1271 | xfs_mount_free(mp, 1); | 1259 | xfs_mount_free(mp); |
1272 | return 0; | 1260 | return 0; |
1273 | } | 1261 | } |
1274 | 1262 | ||
1275 | void | 1263 | void |
1276 | xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr) | 1264 | xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr) |
1277 | { | 1265 | { |
1278 | if (mp->m_logdev_targp != mp->m_ddev_targp) | 1266 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) |
1279 | xfs_free_buftarg(mp->m_logdev_targp, 1); | 1267 | xfs_free_buftarg(mp->m_logdev_targp, 1); |
1280 | if (mp->m_rtdev_targp) | 1268 | if (mp->m_rtdev_targp) |
1281 | xfs_free_buftarg(mp->m_rtdev_targp, 1); | 1269 | xfs_free_buftarg(mp->m_rtdev_targp, 1); |
@@ -1295,10 +1283,8 @@ xfs_unmountfs_wait(xfs_mount_t *mp) | |||
1295 | int | 1283 | int |
1296 | xfs_fs_writable(xfs_mount_t *mp) | 1284 | xfs_fs_writable(xfs_mount_t *mp) |
1297 | { | 1285 | { |
1298 | bhv_vfs_t *vfsp = XFS_MTOVFS(mp); | 1286 | return !(xfs_test_for_freeze(mp) || XFS_FORCED_SHUTDOWN(mp) || |
1299 | 1287 | (mp->m_flags & XFS_MOUNT_RDONLY)); | |
1300 | return !(vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) || | ||
1301 | (vfsp->vfs_flag & VFS_RDONLY)); | ||
1302 | } | 1288 | } |
1303 | 1289 | ||
1304 | /* | 1290 | /* |
@@ -1348,34 +1334,44 @@ xfs_log_sbcount( | |||
1348 | return 0; | 1334 | return 0; |
1349 | } | 1335 | } |
1350 | 1336 | ||
1337 | STATIC void | ||
1338 | xfs_mark_shared_ro( | ||
1339 | xfs_mount_t *mp, | ||
1340 | xfs_buf_t *bp) | ||
1341 | { | ||
1342 | xfs_dsb_t *sb = XFS_BUF_TO_SBP(bp); | ||
1343 | __uint16_t version; | ||
1344 | |||
1345 | if (!(sb->sb_flags & XFS_SBF_READONLY)) | ||
1346 | sb->sb_flags |= XFS_SBF_READONLY; | ||
1347 | |||
1348 | version = be16_to_cpu(sb->sb_versionnum); | ||
1349 | if ((version & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4 || | ||
1350 | !(version & XFS_SB_VERSION_SHAREDBIT)) | ||
1351 | version |= XFS_SB_VERSION_SHAREDBIT; | ||
1352 | sb->sb_versionnum = cpu_to_be16(version); | ||
1353 | } | ||
1354 | |||
1351 | int | 1355 | int |
1352 | xfs_unmountfs_writesb(xfs_mount_t *mp) | 1356 | xfs_unmountfs_writesb(xfs_mount_t *mp) |
1353 | { | 1357 | { |
1354 | xfs_buf_t *sbp; | 1358 | xfs_buf_t *sbp; |
1355 | xfs_sb_t *sb; | ||
1356 | int error = 0; | 1359 | int error = 0; |
1357 | 1360 | ||
1358 | /* | 1361 | /* |
1359 | * skip superblock write if fs is read-only, or | 1362 | * skip superblock write if fs is read-only, or |
1360 | * if we are doing a forced umount. | 1363 | * if we are doing a forced umount. |
1361 | */ | 1364 | */ |
1362 | if (!(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY || | 1365 | if (!((mp->m_flags & XFS_MOUNT_RDONLY) || |
1363 | XFS_FORCED_SHUTDOWN(mp))) { | 1366 | XFS_FORCED_SHUTDOWN(mp))) { |
1364 | 1367 | ||
1365 | sbp = xfs_getsb(mp, 0); | 1368 | sbp = xfs_getsb(mp, 0); |
1366 | sb = XFS_BUF_TO_SBP(sbp); | ||
1367 | 1369 | ||
1368 | /* | 1370 | /* |
1369 | * mark shared-readonly if desired | 1371 | * mark shared-readonly if desired |
1370 | */ | 1372 | */ |
1371 | if (mp->m_mk_sharedro) { | 1373 | if (mp->m_mk_sharedro) |
1372 | if (!(sb->sb_flags & XFS_SBF_READONLY)) | 1374 | xfs_mark_shared_ro(mp, sbp); |
1373 | sb->sb_flags |= XFS_SBF_READONLY; | ||
1374 | if (!XFS_SB_VERSION_HASSHARED(sb)) | ||
1375 | XFS_SB_VERSION_ADDSHARED(sb); | ||
1376 | xfs_fs_cmn_err(CE_NOTE, mp, | ||
1377 | "Unmounting, marking shared read-only"); | ||
1378 | } | ||
1379 | 1375 | ||
1380 | XFS_BUF_UNDONE(sbp); | 1376 | XFS_BUF_UNDONE(sbp); |
1381 | XFS_BUF_UNREAD(sbp); | 1377 | XFS_BUF_UNREAD(sbp); |
@@ -1410,7 +1406,6 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) | |||
1410 | int first; | 1406 | int first; |
1411 | int last; | 1407 | int last; |
1412 | xfs_mount_t *mp; | 1408 | xfs_mount_t *mp; |
1413 | xfs_sb_t *sbp; | ||
1414 | xfs_sb_field_t f; | 1409 | xfs_sb_field_t f; |
1415 | 1410 | ||
1416 | ASSERT(fields); | 1411 | ASSERT(fields); |
@@ -1418,13 +1413,12 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) | |||
1418 | return; | 1413 | return; |
1419 | mp = tp->t_mountp; | 1414 | mp = tp->t_mountp; |
1420 | bp = xfs_trans_getsb(tp, mp, 0); | 1415 | bp = xfs_trans_getsb(tp, mp, 0); |
1421 | sbp = XFS_BUF_TO_SBP(bp); | ||
1422 | first = sizeof(xfs_sb_t); | 1416 | first = sizeof(xfs_sb_t); |
1423 | last = 0; | 1417 | last = 0; |
1424 | 1418 | ||
1425 | /* translate/copy */ | 1419 | /* translate/copy */ |
1426 | 1420 | ||
1427 | xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), -1, fields); | 1421 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); |
1428 | 1422 | ||
1429 | /* find modified range */ | 1423 | /* find modified range */ |
1430 | 1424 | ||