]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libxfs/xfs_mount.c
Update copyright dates
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_mount.c
CommitLineData
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 */
40void
41xfs_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
102static 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 */
162void
163xfs_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
218void
219xfs_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