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