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