aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 23:42:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 23:42:58 -0400
commit60c7b4df82d0ec44fe10487eadec737abea55b34 (patch)
tree35c5b3cf5f9c9169e018a3527a14c558a10611bc /fs/xfs/xfs_super.c
parentaab174f0df5d72d31caccf281af5f614fa254578 (diff)
parent2ea0392983a82f7dc3055568ae0f2558724d119b (diff)
Merge tag 'for-linus-v3.7-rc1' of git://oss.sgi.com/xfs/xfs
Pull xfs update from Ben Myers: "Several enhancements and cleanups: - make inode32 and inode64 remountable options - SEEK_HOLE/SEEK_DATA enhancements - cleanup struct declarations in xfs_mount.h" * tag 'for-linus-v3.7-rc1' of git://oss.sgi.com/xfs/xfs: xfs: Make inode32 a remountable option xfs: add inode64->inode32 transition into xfs_set_inode32() xfs: Fix mp->m_maxagi update during inode64 remount xfs: reduce code duplication handling inode32/64 options xfs: make inode64 as the default allocation mode xfs: Fix m_agirotor reset during AG selection Make inode64 a remountable option xfs: stop the sync worker before xfs_unmountfs xfs: xfs_seek_hole() refinement with hole searching from page cache for unwritten extents xfs: xfs_seek_data() refinement with unwritten extents check up from page cache xfs: Introduce a helper routine to probe data or hole offset from page cache xfs: Remove type argument from xfs_seek_data()/xfs_seek_hole() xfs: fix race while discarding buffers [V4] xfs: check for possible overflow in xfs_ioc_trim xfs: unlock the AGI buffer when looping in xfs_dialloc xfs: kill struct declarations in xfs_mount.h xfs: fix uninitialised variable in xfs_rtbuf_get()
Diffstat (limited to 'fs/xfs/xfs_super.c')
-rw-r--r--fs/xfs/xfs_super.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index e0fd2734189e..26a09bd7f975 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -88,6 +88,8 @@ mempool_t *xfs_ioend_pool;
88 * unwritten extent conversion */ 88 * unwritten extent conversion */
89#define MNTOPT_NOBARRIER "nobarrier" /* .. disable */ 89#define MNTOPT_NOBARRIER "nobarrier" /* .. disable */
90#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ 90#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
91#define MNTOPT_32BITINODE "inode32" /* inode allocation limited to
92 * XFS_MAXINUMBER_32 */
91#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ 93#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
92#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ 94#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
93#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */ 95#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */
@@ -120,12 +122,18 @@ mempool_t *xfs_ioend_pool;
120 * in the future, too. 122 * in the future, too.
121 */ 123 */
122enum { 124enum {
123 Opt_barrier, Opt_nobarrier, Opt_err 125 Opt_barrier,
126 Opt_nobarrier,
127 Opt_inode64,
128 Opt_inode32,
129 Opt_err
124}; 130};
125 131
126static const match_table_t tokens = { 132static const match_table_t tokens = {
127 {Opt_barrier, "barrier"}, 133 {Opt_barrier, "barrier"},
128 {Opt_nobarrier, "nobarrier"}, 134 {Opt_nobarrier, "nobarrier"},
135 {Opt_inode64, "inode64"},
136 {Opt_inode32, "inode32"},
129 {Opt_err, NULL} 137 {Opt_err, NULL}
130}; 138};
131 139
@@ -197,7 +205,9 @@ xfs_parseargs(
197 */ 205 */
198 mp->m_flags |= XFS_MOUNT_BARRIER; 206 mp->m_flags |= XFS_MOUNT_BARRIER;
199 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; 207 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
208#if !XFS_BIG_INUMS
200 mp->m_flags |= XFS_MOUNT_SMALL_INUMS; 209 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
210#endif
201 211
202 /* 212 /*
203 * These can be overridden by the mount option parsing. 213 * These can be overridden by the mount option parsing.
@@ -294,6 +304,8 @@ xfs_parseargs(
294 return EINVAL; 304 return EINVAL;
295 } 305 }
296 dswidth = simple_strtoul(value, &eov, 10); 306 dswidth = simple_strtoul(value, &eov, 10);
307 } else if (!strcmp(this_char, MNTOPT_32BITINODE)) {
308 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
297 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { 309 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
298 mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; 310 mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
299#if !XFS_BIG_INUMS 311#if !XFS_BIG_INUMS
@@ -492,6 +504,7 @@ xfs_showargs(
492 { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, 504 { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM },
493 { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, 505 { XFS_MOUNT_GRPID, "," MNTOPT_GRPID },
494 { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, 506 { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD },
507 { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE },
495 { 0, NULL } 508 { 0, NULL }
496 }; 509 };
497 static struct proc_xfs_info xfs_info_unset[] = { 510 static struct proc_xfs_info xfs_info_unset[] = {
@@ -591,6 +604,80 @@ xfs_max_file_offset(
591 return (((__uint64_t)pagefactor) << bitshift) - 1; 604 return (((__uint64_t)pagefactor) << bitshift) - 1;
592} 605}
593 606
607xfs_agnumber_t
608xfs_set_inode32(struct xfs_mount *mp)
609{
610 xfs_agnumber_t index = 0;
611 xfs_agnumber_t maxagi = 0;
612 xfs_sb_t *sbp = &mp->m_sb;
613 xfs_agnumber_t max_metadata;
614 xfs_agino_t agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks -1, 0);
615 xfs_ino_t ino = XFS_AGINO_TO_INO(mp, sbp->sb_agcount -1, agino);
616 xfs_perag_t *pag;
617
618 /* Calculate how much should be reserved for inodes to meet
619 * the max inode percentage.
620 */
621 if (mp->m_maxicount) {
622 __uint64_t icount;
623
624 icount = sbp->sb_dblocks * sbp->sb_imax_pct;
625 do_div(icount, 100);
626 icount += sbp->sb_agblocks - 1;
627 do_div(icount, sbp->sb_agblocks);
628 max_metadata = icount;
629 } else {
630 max_metadata = sbp->sb_agcount;
631 }
632
633 for (index = 0; index < sbp->sb_agcount; index++) {
634 ino = XFS_AGINO_TO_INO(mp, index, agino);
635
636 if (ino > XFS_MAXINUMBER_32) {
637 pag = xfs_perag_get(mp, index);
638 pag->pagi_inodeok = 0;
639 pag->pagf_metadata = 0;
640 xfs_perag_put(pag);
641 continue;
642 }
643
644 pag = xfs_perag_get(mp, index);
645 pag->pagi_inodeok = 1;
646 maxagi++;
647 if (index < max_metadata)
648 pag->pagf_metadata = 1;
649 xfs_perag_put(pag);
650 }
651 mp->m_flags |= (XFS_MOUNT_32BITINODES |
652 XFS_MOUNT_SMALL_INUMS);
653
654 return maxagi;
655}
656
657xfs_agnumber_t
658xfs_set_inode64(struct xfs_mount *mp)
659{
660 xfs_agnumber_t index = 0;
661
662 for (index = 0; index < mp->m_sb.sb_agcount; index++) {
663 struct xfs_perag *pag;
664
665 pag = xfs_perag_get(mp, index);
666 pag->pagi_inodeok = 1;
667 pag->pagf_metadata = 0;
668 xfs_perag_put(pag);
669 }
670
671 /* There is no need for lock protection on m_flags,
672 * the rw_semaphore of the VFS superblock is locked
673 * during mount/umount/remount operations, so this is
674 * enough to avoid concurency on the m_flags field
675 */
676 mp->m_flags &= ~(XFS_MOUNT_32BITINODES |
677 XFS_MOUNT_SMALL_INUMS);
678 return index;
679}
680
594STATIC int 681STATIC int
595xfs_blkdev_get( 682xfs_blkdev_get(
596 xfs_mount_t *mp, 683 xfs_mount_t *mp,
@@ -1056,6 +1143,12 @@ xfs_fs_remount(
1056 case Opt_nobarrier: 1143 case Opt_nobarrier:
1057 mp->m_flags &= ~XFS_MOUNT_BARRIER; 1144 mp->m_flags &= ~XFS_MOUNT_BARRIER;
1058 break; 1145 break;
1146 case Opt_inode64:
1147 mp->m_maxagi = xfs_set_inode64(mp);
1148 break;
1149 case Opt_inode32:
1150 mp->m_maxagi = xfs_set_inode32(mp);
1151 break;
1059 default: 1152 default:
1060 /* 1153 /*
1061 * Logically we would return an error here to prevent 1154 * Logically we would return an error here to prevent