]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxfs/xfs_mount.c
Flush out my xfsprogs backlog - bunch of I18N and sector size related
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_mount.c
1 /*
2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 #include <xfs.h>
34
35 /*
36 * Mount initialization code establishing various mount
37 * fields from the superblock associated with the given
38 * mount structure.
39 */
40 void
41 xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
42 {
43 int i;
44
45 mp->m_agfrotor = mp->m_agirotor = 0;
46 mp->m_maxagi = mp->m_sb.sb_agcount;
47 mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
48 mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
49 mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
50 mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
51 mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
52 mp->m_litino = sbp->sb_inodesize -
53 ((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t));
54 mp->m_blockmask = sbp->sb_blocksize - 1;
55 mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
56 mp->m_blockwmask = mp->m_blockwsize - 1;
57
58
59 if (XFS_SB_VERSION_HASLOGV2(sbp)) {
60 if (sbp->sb_logsunit <= 1) {
61 mp->m_lstripemask = 1;
62 } else {
63 mp->m_lstripemask =
64 1 << xfs_highbit32(sbp->sb_logsunit >> BBSHIFT);
65 }
66 }
67
68 /*
69 * Setup for attributes, in case they get created.
70 * This value is for inodes getting attributes for the first time,
71 * the per-inode value is for old attribute values.
72 */
73 ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048);
74 switch (sbp->sb_inodesize) {
75 case 256:
76 mp->m_attroffset = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(2);
77 break;
78 case 512:
79 case 1024:
80 case 2048:
81 mp->m_attroffset = XFS_BMDR_SPACE_CALC(12);
82 break;
83 default:
84 ASSERT(0);
85 }
86 ASSERT(mp->m_attroffset < XFS_LITINO(mp));
87
88 for (i = 0; i < 2; i++) {
89 mp->m_alloc_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,
90 xfs_alloc, i == 0);
91 mp->m_alloc_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,
92 xfs_alloc, i == 0);
93 }
94 for (i = 0; i < 2; i++) {
95 mp->m_bmap_dmxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,
96 xfs_bmbt, i == 0);
97 mp->m_bmap_dmnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,
98 xfs_bmbt, i == 0);
99 }
100 for (i = 0; i < 2; i++) {
101 mp->m_inobt_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,
102 xfs_inobt, i == 0);
103 mp->m_inobt_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,
104 xfs_inobt, i == 0);
105 }
106
107 mp->m_bsize = XFS_FSB_TO_BB(mp, 1);
108 mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK,
109 sbp->sb_inopblock);
110 mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog;
111 }
112
113 static struct {
114 short offset;
115 short type; /* 0 = integer
116 * 1 = binary / string (no translation)
117 */
118 } xfs_sb_info[] = {
119 { offsetof(xfs_sb_t, sb_magicnum), 0 },
120 { offsetof(xfs_sb_t, sb_blocksize), 0 },
121 { offsetof(xfs_sb_t, sb_dblocks), 0 },
122 { offsetof(xfs_sb_t, sb_rblocks), 0 },
123 { offsetof(xfs_sb_t, sb_rextents), 0 },
124 { offsetof(xfs_sb_t, sb_uuid), 1 },
125 { offsetof(xfs_sb_t, sb_logstart), 0 },
126 { offsetof(xfs_sb_t, sb_rootino), 0 },
127 { offsetof(xfs_sb_t, sb_rbmino), 0 },
128 { offsetof(xfs_sb_t, sb_rsumino), 0 },
129 { offsetof(xfs_sb_t, sb_rextsize), 0 },
130 { offsetof(xfs_sb_t, sb_agblocks), 0 },
131 { offsetof(xfs_sb_t, sb_agcount), 0 },
132 { offsetof(xfs_sb_t, sb_rbmblocks), 0 },
133 { offsetof(xfs_sb_t, sb_logblocks), 0 },
134 { offsetof(xfs_sb_t, sb_versionnum), 0 },
135 { offsetof(xfs_sb_t, sb_sectsize), 0 },
136 { offsetof(xfs_sb_t, sb_inodesize), 0 },
137 { offsetof(xfs_sb_t, sb_inopblock), 0 },
138 { offsetof(xfs_sb_t, sb_fname[0]), 1 },
139 { offsetof(xfs_sb_t, sb_blocklog), 0 },
140 { offsetof(xfs_sb_t, sb_sectlog), 0 },
141 { offsetof(xfs_sb_t, sb_inodelog), 0 },
142 { offsetof(xfs_sb_t, sb_inopblog), 0 },
143 { offsetof(xfs_sb_t, sb_agblklog), 0 },
144 { offsetof(xfs_sb_t, sb_rextslog), 0 },
145 { offsetof(xfs_sb_t, sb_inprogress), 0 },
146 { offsetof(xfs_sb_t, sb_imax_pct), 0 },
147 { offsetof(xfs_sb_t, sb_icount), 0 },
148 { offsetof(xfs_sb_t, sb_ifree), 0 },
149 { offsetof(xfs_sb_t, sb_fdblocks), 0 },
150 { offsetof(xfs_sb_t, sb_frextents), 0 },
151 { offsetof(xfs_sb_t, sb_uquotino), 0 },
152 { offsetof(xfs_sb_t, sb_gquotino), 0 },
153 { offsetof(xfs_sb_t, sb_qflags), 0 },
154 { offsetof(xfs_sb_t, sb_flags), 0 },
155 { offsetof(xfs_sb_t, sb_shared_vn), 0 },
156 { offsetof(xfs_sb_t, sb_inoalignmt), 0 },
157 { offsetof(xfs_sb_t, sb_unit), 0 },
158 { offsetof(xfs_sb_t, sb_width), 0 },
159 { offsetof(xfs_sb_t, sb_dirblklog), 0 },
160 { offsetof(xfs_sb_t, sb_logsectlog), 0 },
161 { offsetof(xfs_sb_t, sb_logsectsize),0 },
162 { offsetof(xfs_sb_t, sb_logsunit), 0 },
163 { sizeof(xfs_sb_t), 0 }
164 };
165
166 /*
167 * xfs_xlatesb
168 * data - on disk version of sb
169 * sb - a superblock
170 * dir - conversion direction: <0 - convert sb to buf
171 * >0 - convert buf to sb
172 * arch - architecture to read/write from/to buf
173 * fields - which fields to copy (bitmask)
174 */
175 void
176 xfs_xlatesb(
177 void *data,
178 xfs_sb_t *sb,
179 int dir,
180 xfs_arch_t arch,
181 __int64_t fields)
182 {
183 xfs_caddr_t buf_ptr;
184 xfs_caddr_t mem_ptr;
185 xfs_sb_field_t f;
186 int first;
187 int size;
188
189 ASSERT(dir);
190 ASSERT(fields);
191
192 if (!fields)
193 return;
194
195 buf_ptr = (xfs_caddr_t)data;
196 mem_ptr = (xfs_caddr_t)sb;
197
198 while (fields) {
199 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
200 first = xfs_sb_info[f].offset;
201 size = xfs_sb_info[f + 1].offset - first;
202
203 ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1);
204
205 if (arch == ARCH_NOCONVERT ||
206 size == 1 ||
207 xfs_sb_info[f].type == 1) {
208 if (dir > 0) {
209 memcpy(mem_ptr + first, buf_ptr + first, size);
210 } else {
211 memcpy(buf_ptr + first, mem_ptr + first, size);
212 }
213 } else {
214 switch (size) {
215 case 2:
216 INT_XLATE(*(__uint16_t*)(buf_ptr+first),
217 *(__uint16_t*)(mem_ptr+first),
218 dir, arch);
219 break;
220 case 4:
221 INT_XLATE(*(__uint32_t*)(buf_ptr+first),
222 *(__uint32_t*)(mem_ptr+first),
223 dir, arch);
224 break;
225 case 8:
226 INT_XLATE(*(__uint64_t*)(buf_ptr+first),
227 *(__uint64_t*)(mem_ptr+first), dir, arch);
228 break;
229 default:
230 ASSERT(0);
231 }
232 }
233
234 fields &= ~(1LL << f);
235 }
236 }
237
238 void
239 xfs_initialize_perag(xfs_mount_t *mp, int agcount)
240 {
241 int index, max_metadata;
242 xfs_perag_t *pag;
243 xfs_agino_t agino;
244 xfs_ino_t ino;
245 xfs_sb_t *sbp = &mp->m_sb;
246 xfs_ino_t max_inum = XFS_MAXINUMBER_32;
247
248 /* Check to see if the filesystem can overflow 32 bit inodes */
249 agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
250 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
251
252 /* Clear the mount flag if no inode can overflow 32 bits
253 * on this filesystem.
254 */
255 if (ino <= max_inum) {
256 mp->m_flags &= ~XFS_MOUNT_32BITINODES;
257 }
258
259 /* If we can overflow then setup the ag headers accordingly */
260 if (mp->m_flags & XFS_MOUNT_32BITINODES) {
261 /* Calculate how much should be reserved for inodes to
262 * meet the max inode percentage.
263 */
264 if (mp->m_maxicount) {
265 __uint64_t icount;
266
267 icount = sbp->sb_dblocks * sbp->sb_imax_pct;
268 do_div(icount, 100);
269 icount += sbp->sb_agblocks - 1;
270 do_div(icount, mp->m_ialloc_blks);
271 max_metadata = icount;
272 } else {
273 max_metadata = agcount;
274 }
275 for (index = 0; index < agcount; index++) {
276 ino = XFS_AGINO_TO_INO(mp, index, agino);
277 if (ino > max_inum) {
278 index++;
279 break;
280 }
281
282 /* This ag is prefered for inodes */
283 pag = &mp->m_perag[index];
284 pag->pagi_inodeok = 1;
285 if (index < max_metadata)
286 pag->pagf_metadata = 1;
287 }
288 } else {
289 /* Setup default behavior for smaller filesystems */
290 for (index = 0; index < agcount; index++) {
291 pag = &mp->m_perag[index];
292 pag->pagi_inodeok = 1;
293 }
294 }
295 mp->m_maxagi = index;
296 }
297