]>
Commit | Line | Data |
---|---|---|
2bd0ea18 | 1 | /* |
0d3e0b37 | 2 | * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. |
2bd0ea18 NS |
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 | |
5000d01d | 14 | * or the like. Any license provided herein, whether implied or |
2bd0ea18 NS |
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; | |
321717ae | 46 | spinlock_init(&mp->m_agirotor_lock, "m_agirotor_lock"); |
34317449 | 47 | mp->m_maxagi = mp->m_sb.sb_agcount; |
2bd0ea18 NS |
48 | mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG; |
49 | mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT; | |
9440d84d | 50 | mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; |
2bd0ea18 NS |
51 | mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; |
52 | mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog; | |
53 | mp->m_litino = sbp->sb_inodesize - | |
54 | ((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t)); | |
55 | mp->m_blockmask = sbp->sb_blocksize - 1; | |
56 | mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; | |
57 | mp->m_blockwmask = mp->m_blockwsize - 1; | |
58 | ||
73bf5988 SL |
59 | |
60 | if (XFS_SB_VERSION_HASLOGV2(sbp)) { | |
61 | if (sbp->sb_logsunit <= 1) { | |
62 | mp->m_lstripemask = 1; | |
63 | } else { | |
64 | mp->m_lstripemask = | |
65 | 1 << xfs_highbit32(sbp->sb_logsunit >> BBSHIFT); | |
66 | } | |
67 | } | |
68 | ||
2bd0ea18 NS |
69 | /* |
70 | * Setup for attributes, in case they get created. | |
71 | * This value is for inodes getting attributes for the first time, | |
72 | * the per-inode value is for old attribute values. | |
73 | */ | |
74 | ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048); | |
75 | switch (sbp->sb_inodesize) { | |
76 | case 256: | |
77 | mp->m_attroffset = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(2); | |
78 | break; | |
79 | case 512: | |
80 | case 1024: | |
81 | case 2048: | |
82 | mp->m_attroffset = XFS_BMDR_SPACE_CALC(12); | |
83 | break; | |
84 | default: | |
85 | ASSERT(0); | |
86 | } | |
87 | ASSERT(mp->m_attroffset < XFS_LITINO(mp)); | |
88 | ||
89 | for (i = 0; i < 2; i++) { | |
90 | mp->m_alloc_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize, | |
91 | xfs_alloc, i == 0); | |
92 | mp->m_alloc_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize, | |
93 | xfs_alloc, i == 0); | |
94 | } | |
95 | for (i = 0; i < 2; i++) { | |
96 | mp->m_bmap_dmxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize, | |
97 | xfs_bmbt, i == 0); | |
98 | mp->m_bmap_dmnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize, | |
99 | xfs_bmbt, i == 0); | |
100 | } | |
101 | for (i = 0; i < 2; i++) { | |
102 | mp->m_inobt_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize, | |
103 | xfs_inobt, i == 0); | |
104 | mp->m_inobt_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize, | |
105 | xfs_inobt, i == 0); | |
106 | } | |
107 | ||
108 | mp->m_bsize = XFS_FSB_TO_BB(mp, 1); | |
7dcc1612 NS |
109 | mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK, |
110 | sbp->sb_inopblock); | |
2bd0ea18 NS |
111 | mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog; |
112 | } | |
113 | ||
114 | static struct { | |
115 | short offset; | |
5000d01d SL |
116 | short type; /* 0 = integer |
117 | * 1 = binary / string (no translation) | |
118 | */ | |
2bd0ea18 | 119 | } xfs_sb_info[] = { |
5000d01d SL |
120 | { offsetof(xfs_sb_t, sb_magicnum), 0 }, |
121 | { offsetof(xfs_sb_t, sb_blocksize), 0 }, | |
122 | { offsetof(xfs_sb_t, sb_dblocks), 0 }, | |
123 | { offsetof(xfs_sb_t, sb_rblocks), 0 }, | |
124 | { offsetof(xfs_sb_t, sb_rextents), 0 }, | |
125 | { offsetof(xfs_sb_t, sb_uuid), 1 }, | |
126 | { offsetof(xfs_sb_t, sb_logstart), 0 }, | |
127 | { offsetof(xfs_sb_t, sb_rootino), 0 }, | |
128 | { offsetof(xfs_sb_t, sb_rbmino), 0 }, | |
129 | { offsetof(xfs_sb_t, sb_rsumino), 0 }, | |
130 | { offsetof(xfs_sb_t, sb_rextsize), 0 }, | |
131 | { offsetof(xfs_sb_t, sb_agblocks), 0 }, | |
132 | { offsetof(xfs_sb_t, sb_agcount), 0 }, | |
133 | { offsetof(xfs_sb_t, sb_rbmblocks), 0 }, | |
134 | { offsetof(xfs_sb_t, sb_logblocks), 0 }, | |
2bd0ea18 | 135 | { offsetof(xfs_sb_t, sb_versionnum), 0 }, |
5000d01d SL |
136 | { offsetof(xfs_sb_t, sb_sectsize), 0 }, |
137 | { offsetof(xfs_sb_t, sb_inodesize), 0 }, | |
138 | { offsetof(xfs_sb_t, sb_inopblock), 0 }, | |
139 | { offsetof(xfs_sb_t, sb_fname[0]), 1 }, | |
140 | { offsetof(xfs_sb_t, sb_blocklog), 0 }, | |
141 | { offsetof(xfs_sb_t, sb_sectlog), 0 }, | |
142 | { offsetof(xfs_sb_t, sb_inodelog), 0 }, | |
143 | { offsetof(xfs_sb_t, sb_inopblog), 0 }, | |
144 | { offsetof(xfs_sb_t, sb_agblklog), 0 }, | |
145 | { offsetof(xfs_sb_t, sb_rextslog), 0 }, | |
2bd0ea18 | 146 | { offsetof(xfs_sb_t, sb_inprogress), 0 }, |
5000d01d SL |
147 | { offsetof(xfs_sb_t, sb_imax_pct), 0 }, |
148 | { offsetof(xfs_sb_t, sb_icount), 0 }, | |
149 | { offsetof(xfs_sb_t, sb_ifree), 0 }, | |
150 | { offsetof(xfs_sb_t, sb_fdblocks), 0 }, | |
151 | { offsetof(xfs_sb_t, sb_frextents), 0 }, | |
152 | { offsetof(xfs_sb_t, sb_uquotino), 0 }, | |
153 | { offsetof(xfs_sb_t, sb_gquotino), 0 }, | |
154 | { offsetof(xfs_sb_t, sb_qflags), 0 }, | |
155 | { offsetof(xfs_sb_t, sb_flags), 0 }, | |
156 | { offsetof(xfs_sb_t, sb_shared_vn), 0 }, | |
2bd0ea18 | 157 | { offsetof(xfs_sb_t, sb_inoalignmt), 0 }, |
5000d01d SL |
158 | { offsetof(xfs_sb_t, sb_unit), 0 }, |
159 | { offsetof(xfs_sb_t, sb_width), 0 }, | |
160 | { offsetof(xfs_sb_t, sb_dirblklog), 0 }, | |
9440d84d NS |
161 | { offsetof(xfs_sb_t, sb_logsectlog), 0 }, |
162 | { offsetof(xfs_sb_t, sb_logsectsize),0 }, | |
5000d01d SL |
163 | { offsetof(xfs_sb_t, sb_logsunit), 0 }, |
164 | { sizeof(xfs_sb_t), 0 } | |
2bd0ea18 NS |
165 | }; |
166 | ||
167 | /* | |
168 | * xfs_xlatesb | |
5000d01d SL |
169 | * data - on disk version of sb |
170 | * sb - a superblock | |
171 | * dir - conversion direction: <0 - convert sb to buf | |
172 | * >0 - convert buf to sb | |
173 | * arch - architecture to read/write from/to buf | |
174 | * fields - which fields to copy (bitmask) | |
2bd0ea18 NS |
175 | */ |
176 | void | |
b391b7cd NS |
177 | xfs_xlatesb( |
178 | void *data, | |
179 | xfs_sb_t *sb, | |
180 | int dir, | |
181 | xfs_arch_t arch, | |
182 | __int64_t fields) | |
2bd0ea18 | 183 | { |
b391b7cd NS |
184 | xfs_caddr_t buf_ptr; |
185 | xfs_caddr_t mem_ptr; | |
186 | xfs_sb_field_t f; | |
187 | int first; | |
188 | int size; | |
5000d01d | 189 | |
b391b7cd NS |
190 | ASSERT(dir); |
191 | ASSERT(fields); | |
2bd0ea18 | 192 | |
b391b7cd NS |
193 | if (!fields) |
194 | return; | |
5000d01d | 195 | |
b391b7cd NS |
196 | buf_ptr = (xfs_caddr_t)data; |
197 | mem_ptr = (xfs_caddr_t)sb; | |
5000d01d | 198 | |
b391b7cd NS |
199 | while (fields) { |
200 | f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); | |
201 | first = xfs_sb_info[f].offset; | |
202 | size = xfs_sb_info[f + 1].offset - first; | |
2bd0ea18 | 203 | |
b391b7cd | 204 | ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); |
5000d01d | 205 | |
b391b7cd NS |
206 | if (arch == ARCH_NOCONVERT || |
207 | size == 1 || | |
208 | xfs_sb_info[f].type == 1) { | |
209 | if (dir > 0) { | |
32181a02 | 210 | memcpy(mem_ptr + first, buf_ptr + first, size); |
b391b7cd | 211 | } else { |
32181a02 | 212 | memcpy(buf_ptr + first, mem_ptr + first, size); |
b391b7cd NS |
213 | } |
214 | } else { | |
215 | switch (size) { | |
216 | case 2: | |
217 | INT_XLATE(*(__uint16_t*)(buf_ptr+first), | |
218 | *(__uint16_t*)(mem_ptr+first), | |
219 | dir, arch); | |
220 | break; | |
221 | case 4: | |
222 | INT_XLATE(*(__uint32_t*)(buf_ptr+first), | |
223 | *(__uint32_t*)(mem_ptr+first), | |
224 | dir, arch); | |
225 | break; | |
226 | case 8: | |
227 | INT_XLATE(*(__uint64_t*)(buf_ptr+first), | |
228 | *(__uint64_t*)(mem_ptr+first), dir, arch); | |
229 | break; | |
230 | default: | |
231 | ASSERT(0); | |
232 | } | |
233 | } | |
234 | ||
235 | fields &= ~(1LL << f); | |
236 | } | |
2bd0ea18 | 237 | } |
a33a9e62 NS |
238 | |
239 | void | |
240 | xfs_initialize_perag(xfs_mount_t *mp, int agcount) | |
241 | { | |
242 | int index, max_metadata; | |
243 | xfs_perag_t *pag; | |
244 | xfs_agino_t agino; | |
245 | xfs_ino_t ino; | |
246 | xfs_sb_t *sbp = &mp->m_sb; | |
247 | xfs_ino_t max_inum = XFS_MAXINUMBER_32; | |
248 | ||
249 | /* Check to see if the filesystem can overflow 32 bit inodes */ | |
250 | agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); | |
251 | ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); | |
252 | ||
253 | /* Clear the mount flag if no inode can overflow 32 bits | |
254 | * on this filesystem. | |
255 | */ | |
256 | if (ino <= max_inum) { | |
257 | mp->m_flags &= ~XFS_MOUNT_32BITINODES; | |
258 | } | |
259 | ||
260 | /* If we can overflow then setup the ag headers accordingly */ | |
261 | if (mp->m_flags & XFS_MOUNT_32BITINODES) { | |
262 | /* Calculate how much should be reserved for inodes to | |
263 | * meet the max inode percentage. | |
264 | */ | |
265 | if (mp->m_maxicount) { | |
266 | __uint64_t icount; | |
267 | ||
268 | icount = sbp->sb_dblocks * sbp->sb_imax_pct; | |
269 | do_div(icount, 100); | |
270 | icount += sbp->sb_agblocks - 1; | |
271 | do_div(icount, mp->m_ialloc_blks); | |
272 | max_metadata = icount; | |
273 | } else { | |
274 | max_metadata = agcount; | |
275 | } | |
276 | for (index = 0; index < agcount; index++) { | |
277 | ino = XFS_AGINO_TO_INO(mp, index, agino); | |
278 | if (ino > max_inum) { | |
279 | index++; | |
280 | break; | |
281 | } | |
282 | ||
283 | /* This ag is prefered for inodes */ | |
284 | pag = &mp->m_perag[index]; | |
285 | pag->pagi_inodeok = 1; | |
286 | if (index < max_metadata) | |
287 | pag->pagf_metadata = 1; | |
288 | } | |
289 | } else { | |
290 | /* Setup default behavior for smaller filesystems */ | |
291 | for (index = 0; index < agcount; index++) { | |
292 | pag = &mp->m_perag[index]; | |
293 | pag->pagi_inodeok = 1; | |
294 | } | |
295 | } | |
296 | mp->m_maxagi = index; | |
297 | } | |
298 |