]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxfs/xfs_mount.c
583293158fdf9fb5ffd091b9e694d1d2f5c08597
2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 * Mount initialization code establishing various mount
23 * fields from the superblock associated with the given
27 xfs_mount_common(xfs_mount_t
*mp
, xfs_sb_t
*sbp
)
31 mp
->m_agfrotor
= mp
->m_agirotor
= 0;
32 spinlock_init(&mp
->m_agirotor_lock
, "m_agirotor_lock");
33 mp
->m_maxagi
= mp
->m_sb
.sb_agcount
;
34 mp
->m_blkbit_log
= sbp
->sb_blocklog
+ XFS_NBBYLOG
;
35 mp
->m_blkbb_log
= sbp
->sb_blocklog
- BBSHIFT
;
36 mp
->m_sectbb_log
= sbp
->sb_sectlog
- BBSHIFT
;
37 mp
->m_agno_log
= xfs_highbit32(sbp
->sb_agcount
- 1) + 1;
38 mp
->m_agino_log
= sbp
->sb_inopblog
+ sbp
->sb_agblklog
;
39 mp
->m_litino
= sbp
->sb_inodesize
-
40 ((uint
)sizeof(xfs_dinode_core_t
) + (uint
)sizeof(xfs_agino_t
));
41 mp
->m_blockmask
= sbp
->sb_blocksize
- 1;
42 mp
->m_blockwsize
= sbp
->sb_blocksize
>> XFS_WORDLOG
;
43 mp
->m_blockwmask
= mp
->m_blockwsize
- 1;
44 INIT_LIST_HEAD(&mp
->m_del_inodes
);
47 * Setup for attributes, in case they get created.
48 * This value is for inodes getting attributes for the first time,
49 * the per-inode value is for old attribute values.
51 ASSERT(sbp
->sb_inodesize
>= 256 && sbp
->sb_inodesize
<= 2048);
52 switch (sbp
->sb_inodesize
) {
54 mp
->m_attroffset
= XFS_LITINO(mp
) -
55 XFS_BMDR_SPACE_CALC(MINABTPTRS
);
60 mp
->m_attroffset
= XFS_BMDR_SPACE_CALC(6 * MINABTPTRS
);
65 ASSERT(mp
->m_attroffset
< XFS_LITINO(mp
));
67 for (i
= 0; i
< 2; i
++) {
68 mp
->m_alloc_mxr
[i
] = XFS_BTREE_BLOCK_MAXRECS(sbp
->sb_blocksize
,
70 mp
->m_alloc_mnr
[i
] = XFS_BTREE_BLOCK_MINRECS(sbp
->sb_blocksize
,
73 for (i
= 0; i
< 2; i
++) {
74 mp
->m_bmap_dmxr
[i
] = XFS_BTREE_BLOCK_MAXRECS(sbp
->sb_blocksize
,
76 mp
->m_bmap_dmnr
[i
] = XFS_BTREE_BLOCK_MINRECS(sbp
->sb_blocksize
,
79 for (i
= 0; i
< 2; i
++) {
80 mp
->m_inobt_mxr
[i
] = XFS_BTREE_BLOCK_MAXRECS(sbp
->sb_blocksize
,
82 mp
->m_inobt_mnr
[i
] = XFS_BTREE_BLOCK_MINRECS(sbp
->sb_blocksize
,
86 mp
->m_bsize
= XFS_FSB_TO_BB(mp
, 1);
87 mp
->m_ialloc_inos
= (int)MAX((__uint16_t
)XFS_INODES_PER_CHUNK
,
89 mp
->m_ialloc_blks
= mp
->m_ialloc_inos
>> sbp
->sb_inopblog
;
94 short type
; /* 0 = integer
95 * 1 = binary / string (no translation)
98 { offsetof(xfs_sb_t
, sb_magicnum
), 0 },
99 { offsetof(xfs_sb_t
, sb_blocksize
), 0 },
100 { offsetof(xfs_sb_t
, sb_dblocks
), 0 },
101 { offsetof(xfs_sb_t
, sb_rblocks
), 0 },
102 { offsetof(xfs_sb_t
, sb_rextents
), 0 },
103 { offsetof(xfs_sb_t
, sb_uuid
), 1 },
104 { offsetof(xfs_sb_t
, sb_logstart
), 0 },
105 { offsetof(xfs_sb_t
, sb_rootino
), 0 },
106 { offsetof(xfs_sb_t
, sb_rbmino
), 0 },
107 { offsetof(xfs_sb_t
, sb_rsumino
), 0 },
108 { offsetof(xfs_sb_t
, sb_rextsize
), 0 },
109 { offsetof(xfs_sb_t
, sb_agblocks
), 0 },
110 { offsetof(xfs_sb_t
, sb_agcount
), 0 },
111 { offsetof(xfs_sb_t
, sb_rbmblocks
), 0 },
112 { offsetof(xfs_sb_t
, sb_logblocks
), 0 },
113 { offsetof(xfs_sb_t
, sb_versionnum
), 0 },
114 { offsetof(xfs_sb_t
, sb_sectsize
), 0 },
115 { offsetof(xfs_sb_t
, sb_inodesize
), 0 },
116 { offsetof(xfs_sb_t
, sb_inopblock
), 0 },
117 { offsetof(xfs_sb_t
, sb_fname
[0]), 1 },
118 { offsetof(xfs_sb_t
, sb_blocklog
), 0 },
119 { offsetof(xfs_sb_t
, sb_sectlog
), 0 },
120 { offsetof(xfs_sb_t
, sb_inodelog
), 0 },
121 { offsetof(xfs_sb_t
, sb_inopblog
), 0 },
122 { offsetof(xfs_sb_t
, sb_agblklog
), 0 },
123 { offsetof(xfs_sb_t
, sb_rextslog
), 0 },
124 { offsetof(xfs_sb_t
, sb_inprogress
), 0 },
125 { offsetof(xfs_sb_t
, sb_imax_pct
), 0 },
126 { offsetof(xfs_sb_t
, sb_icount
), 0 },
127 { offsetof(xfs_sb_t
, sb_ifree
), 0 },
128 { offsetof(xfs_sb_t
, sb_fdblocks
), 0 },
129 { offsetof(xfs_sb_t
, sb_frextents
), 0 },
130 { offsetof(xfs_sb_t
, sb_uquotino
), 0 },
131 { offsetof(xfs_sb_t
, sb_gquotino
), 0 },
132 { offsetof(xfs_sb_t
, sb_qflags
), 0 },
133 { offsetof(xfs_sb_t
, sb_flags
), 0 },
134 { offsetof(xfs_sb_t
, sb_shared_vn
), 0 },
135 { offsetof(xfs_sb_t
, sb_inoalignmt
), 0 },
136 { offsetof(xfs_sb_t
, sb_unit
), 0 },
137 { offsetof(xfs_sb_t
, sb_width
), 0 },
138 { offsetof(xfs_sb_t
, sb_dirblklog
), 0 },
139 { offsetof(xfs_sb_t
, sb_logsectlog
), 0 },
140 { offsetof(xfs_sb_t
, sb_logsectsize
),0 },
141 { offsetof(xfs_sb_t
, sb_logsunit
), 0 },
142 { offsetof(xfs_sb_t
, sb_features2
), 0 },
143 { sizeof(xfs_sb_t
), 0 }
148 * data - on disk version of sb
150 * dir - conversion direction: <0 - convert sb to buf
151 * >0 - convert buf to sb
152 * arch - architecture to read/write from/to buf
153 * fields - which fields to copy (bitmask)
174 buf_ptr
= (xfs_caddr_t
)data
;
175 mem_ptr
= (xfs_caddr_t
)sb
;
178 f
= (xfs_sb_field_t
)xfs_lowbit64((__uint64_t
)fields
);
179 first
= xfs_sb_info
[f
].offset
;
180 size
= xfs_sb_info
[f
+ 1].offset
- first
;
182 ASSERT(xfs_sb_info
[f
].type
== 0 || xfs_sb_info
[f
].type
== 1);
184 if (size
== 1 || xfs_sb_info
[f
].type
== 1) {
186 memcpy(mem_ptr
+ first
, buf_ptr
+ first
, size
);
188 memcpy(buf_ptr
+ first
, mem_ptr
+ first
, size
);
193 INT_XLATE(*(__uint16_t
*)(buf_ptr
+first
),
194 *(__uint16_t
*)(mem_ptr
+first
),
198 INT_XLATE(*(__uint32_t
*)(buf_ptr
+first
),
199 *(__uint32_t
*)(mem_ptr
+first
),
203 INT_XLATE(*(__uint64_t
*)(buf_ptr
+first
),
204 *(__uint64_t
*)(mem_ptr
+first
), dir
, ARCH_CONVERT
);
211 fields
&= ~(1LL << f
);
216 * xfs_mod_sb() can be used to copy arbitrary changes to the
217 * in-core superblock into the superblock buffer to be logged.
218 * It does not provide the higher level of locking that is
219 * needed to protect the in-core superblock from concurrent
223 xfs_mod_sb(xfs_trans_t
*tp
, __int64_t fields
)
236 bp
= xfs_trans_getsb(tp
, mp
, 0);
237 sbp
= XFS_BUF_TO_SBP(bp
);
238 first
= sizeof(xfs_sb_t
);
242 xfs_xlatesb(XFS_BUF_PTR(bp
), &(mp
->m_sb
), -1, fields
);
244 /* find modified range */
245 f
= (xfs_sb_field_t
)xfs_lowbit64((__uint64_t
)fields
);
246 ASSERT((1LL << f
) & XFS_SB_MOD_BITS
);
247 first
= xfs_sb_info
[f
].offset
;
248 f
= (xfs_sb_field_t
)xfs_highbit64((__uint64_t
)fields
);
249 ASSERT((1LL << f
) & XFS_SB_MOD_BITS
);
250 last
= xfs_sb_info
[f
+ 1].offset
- 1;
252 xfs_trans_log_buf(tp
, bp
, first
, last
);
256 xfs_initialize_perag(xfs_mount_t
*mp
, xfs_agnumber_t agcount
)
258 xfs_agnumber_t index
, max_metadata
;
262 xfs_sb_t
*sbp
= &mp
->m_sb
;
263 xfs_ino_t max_inum
= XFS_MAXINUMBER_32
;
265 /* Check to see if the filesystem can overflow 32 bit inodes */
266 agino
= XFS_OFFBNO_TO_AGINO(mp
, sbp
->sb_agblocks
- 1, 0);
267 ino
= XFS_AGINO_TO_INO(mp
, agcount
- 1, agino
);
269 /* Clear the mount flag if no inode can overflow 32 bits
270 * on this filesystem, or if specifically requested..
272 if ((mp
->m_flags
& XFS_MOUNT_32BITINOOPT
) && ino
> max_inum
) {
273 mp
->m_flags
|= XFS_MOUNT_32BITINODES
;
275 mp
->m_flags
&= ~XFS_MOUNT_32BITINODES
;
278 /* If we can overflow then setup the ag headers accordingly */
279 if (mp
->m_flags
& XFS_MOUNT_32BITINODES
) {
280 /* Calculate how much should be reserved for inodes to
281 * meet the max inode percentage.
283 if (mp
->m_maxicount
) {
286 icount
= sbp
->sb_dblocks
* sbp
->sb_imax_pct
;
288 icount
+= sbp
->sb_agblocks
- 1;
289 do_div(icount
, sbp
->sb_agblocks
);
290 max_metadata
= icount
;
292 max_metadata
= agcount
;
294 for (index
= 0; index
< agcount
; index
++) {
295 ino
= XFS_AGINO_TO_INO(mp
, index
, agino
);
296 if (ino
> max_inum
) {
301 /* This ag is prefered for inodes */
302 pag
= &mp
->m_perag
[index
];
303 pag
->pagi_inodeok
= 1;
304 if (index
< max_metadata
)
305 pag
->pagf_metadata
= 1;
308 /* Setup default behavior for smaller filesystems */
309 for (index
= 0; index
< agcount
; index
++) {
310 pag
= &mp
->m_perag
[index
];
311 pag
->pagi_inodeok
= 1;