aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_super.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-10-30 02:53:24 -0400
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-10-30 02:53:24 -0400
commit9d565ffa33d574c2a22442f9d95ca2bd0be7cc42 (patch)
tree6a90c653b264fa286525a24f5bd2ce2f2767252e /fs/xfs/linux-2.6/xfs_super.c
parent5a792c4579af8466246408e38fd4eff45d8493b8 (diff)
[XFS] kill struct xfs_mount_args
No need to parse the mount option into a structure before applying it to struct xfs_mount. The content of xfs_start_flags gets merged into xfs_parseargs. Calls inbetween don't care and can use mount members instead of the args struct. This patch uncovered that the mount option for shared filesystems wasn't ever exposed on Linux. The code to handle it is #if 0'ed in this patch pending a decision on this feature. I'll send a writeup about it to the list soon. SGI-PV: 987246 SGI-Modid: xfs-linux-melb:xfs-kern:32371a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Donald Douwsma <donaldd@sgi.com> Signed-off-by: David Chinner <david@fromorbit.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_super.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c499
1 files changed, 189 insertions, 310 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 655508ce2b73..5638a99fb741 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -18,7 +18,6 @@
18#include "xfs.h" 18#include "xfs.h"
19#include "xfs_bit.h" 19#include "xfs_bit.h"
20#include "xfs_log.h" 20#include "xfs_log.h"
21#include "xfs_clnt.h"
22#include "xfs_inum.h" 21#include "xfs_inum.h"
23#include "xfs_trans.h" 22#include "xfs_trans.h"
24#include "xfs_sb.h" 23#include "xfs_sb.h"
@@ -75,32 +74,6 @@ static struct super_operations xfs_super_operations;
75static kmem_zone_t *xfs_ioend_zone; 74static kmem_zone_t *xfs_ioend_zone;
76mempool_t *xfs_ioend_pool; 75mempool_t *xfs_ioend_pool;
77 76
78STATIC struct xfs_mount_args *
79xfs_args_allocate(
80 struct super_block *sb,
81 int silent)
82{
83 struct xfs_mount_args *args;
84
85 args = kzalloc(sizeof(struct xfs_mount_args), GFP_KERNEL);
86 if (!args)
87 return NULL;
88
89 args->logbufs = args->logbufsize = -1;
90 strncpy(args->fsname, sb->s_id, MAXNAMELEN);
91
92 /* Copy the already-parsed mount(2) flags we're interested in */
93 if (sb->s_flags & MS_DIRSYNC)
94 args->flags |= XFSMNT_DIRSYNC;
95 if (sb->s_flags & MS_SYNCHRONOUS)
96 args->flags |= XFSMNT_WSYNC;
97 if (silent)
98 args->flags |= XFSMNT_QUIET;
99 args->flags |= XFSMNT_32BITINODES;
100
101 return args;
102}
103
104#define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ 77#define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */
105#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ 78#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */
106#define MNTOPT_LOGDEV "logdev" /* log device */ 79#define MNTOPT_LOGDEV "logdev" /* log device */
@@ -189,26 +162,54 @@ suffix_strtoul(char *s, char **endp, unsigned int base)
189 return simple_strtoul((const char *)s, endp, base) << shift_left_factor; 162 return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
190} 163}
191 164
165/*
166 * This function fills in xfs_mount_t fields based on mount args.
167 * Note: the superblock has _not_ yet been read in.
168 *
169 * Note that this function leaks the various device name allocations on
170 * failure. The caller takes care of them.
171 */
192STATIC int 172STATIC int
193xfs_parseargs( 173xfs_parseargs(
194 struct xfs_mount *mp, 174 struct xfs_mount *mp,
195 char *options, 175 char *options,
196 struct xfs_mount_args *args, 176 char **mtpt)
197 int update)
198{ 177{
178 struct super_block *sb = mp->m_super;
199 char *this_char, *value, *eov; 179 char *this_char, *value, *eov;
200 int dsunit, dswidth, vol_dsunit, vol_dswidth; 180 int dsunit = 0;
201 int iosize; 181 int dswidth = 0;
182 int iosize = 0;
202 int dmapi_implies_ikeep = 1; 183 int dmapi_implies_ikeep = 1;
184 uchar_t iosizelog = 0;
185
186 /*
187 * Copy binary VFS mount flags we are interested in.
188 */
189 if (sb->s_flags & MS_RDONLY)
190 mp->m_flags |= XFS_MOUNT_RDONLY;
191 if (sb->s_flags & MS_DIRSYNC)
192 mp->m_flags |= XFS_MOUNT_DIRSYNC;
193 if (sb->s_flags & MS_SYNCHRONOUS)
194 mp->m_flags |= XFS_MOUNT_WSYNC;
195
196 /*
197 * Set some default flags that could be cleared by the mount option
198 * parsing.
199 */
200 mp->m_flags |= XFS_MOUNT_BARRIER;
201 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
202 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
203 203
204 args->flags |= XFSMNT_BARRIER; 204 /*
205 args->flags2 |= XFSMNT2_COMPAT_IOSIZE; 205 * These can be overridden by the mount option parsing.
206 */
207 mp->m_logbufs = -1;
208 mp->m_logbsize = -1;
206 209
207 if (!options) 210 if (!options)
208 goto done; 211 goto done;
209 212
210 iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;
211
212 while ((this_char = strsep(&options, ",")) != NULL) { 213 while ((this_char = strsep(&options, ",")) != NULL) {
213 if (!*this_char) 214 if (!*this_char)
214 continue; 215 continue;
@@ -222,7 +223,7 @@ xfs_parseargs(
222 this_char); 223 this_char);
223 return EINVAL; 224 return EINVAL;
224 } 225 }
225 args->logbufs = simple_strtoul(value, &eov, 10); 226 mp->m_logbufs = simple_strtoul(value, &eov, 10);
226 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { 227 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
227 if (!value || !*value) { 228 if (!value || !*value) {
228 cmn_err(CE_WARN, 229 cmn_err(CE_WARN,
@@ -230,7 +231,7 @@ xfs_parseargs(
230 this_char); 231 this_char);
231 return EINVAL; 232 return EINVAL;
232 } 233 }
233 args->logbufsize = suffix_strtoul(value, &eov, 10); 234 mp->m_logbsize = suffix_strtoul(value, &eov, 10);
234 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { 235 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
235 if (!value || !*value) { 236 if (!value || !*value) {
236 cmn_err(CE_WARN, 237 cmn_err(CE_WARN,
@@ -238,7 +239,9 @@ xfs_parseargs(
238 this_char); 239 this_char);
239 return EINVAL; 240 return EINVAL;
240 } 241 }
241 strncpy(args->logname, value, MAXNAMELEN); 242 mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
243 if (!mp->m_logname)
244 return ENOMEM;
242 } else if (!strcmp(this_char, MNTOPT_MTPT)) { 245 } else if (!strcmp(this_char, MNTOPT_MTPT)) {
243 if (!value || !*value) { 246 if (!value || !*value) {
244 cmn_err(CE_WARN, 247 cmn_err(CE_WARN,
@@ -246,7 +249,9 @@ xfs_parseargs(
246 this_char); 249 this_char);
247 return EINVAL; 250 return EINVAL;
248 } 251 }
249 strncpy(args->mtpt, value, MAXNAMELEN); 252 *mtpt = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
253 if (!*mtpt)
254 return ENOMEM;
250 } else if (!strcmp(this_char, MNTOPT_RTDEV)) { 255 } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
251 if (!value || !*value) { 256 if (!value || !*value) {
252 cmn_err(CE_WARN, 257 cmn_err(CE_WARN,
@@ -254,7 +259,9 @@ xfs_parseargs(
254 this_char); 259 this_char);
255 return EINVAL; 260 return EINVAL;
256 } 261 }
257 strncpy(args->rtname, value, MAXNAMELEN); 262 mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
263 if (!mp->m_rtname)
264 return ENOMEM;
258 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { 265 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
259 if (!value || !*value) { 266 if (!value || !*value) {
260 cmn_err(CE_WARN, 267 cmn_err(CE_WARN,
@@ -263,8 +270,7 @@ xfs_parseargs(
263 return EINVAL; 270 return EINVAL;
264 } 271 }
265 iosize = simple_strtoul(value, &eov, 10); 272 iosize = simple_strtoul(value, &eov, 10);
266 args->flags |= XFSMNT_IOSIZE; 273 iosizelog = (uint8_t) iosize;
267 args->iosizelog = (uint8_t) iosize;
268 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { 274 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
269 if (!value || !*value) { 275 if (!value || !*value) {
270 cmn_err(CE_WARN, 276 cmn_err(CE_WARN,
@@ -273,8 +279,7 @@ xfs_parseargs(
273 return EINVAL; 279 return EINVAL;
274 } 280 }
275 iosize = suffix_strtoul(value, &eov, 10); 281 iosize = suffix_strtoul(value, &eov, 10);
276 args->flags |= XFSMNT_IOSIZE; 282 iosizelog = ffs(iosize) - 1;
277 args->iosizelog = ffs(iosize) - 1;
278 } else if (!strcmp(this_char, MNTOPT_GRPID) || 283 } else if (!strcmp(this_char, MNTOPT_GRPID) ||
279 !strcmp(this_char, MNTOPT_BSDGROUPS)) { 284 !strcmp(this_char, MNTOPT_BSDGROUPS)) {
280 mp->m_flags |= XFS_MOUNT_GRPID; 285 mp->m_flags |= XFS_MOUNT_GRPID;
@@ -282,23 +287,25 @@ xfs_parseargs(
282 !strcmp(this_char, MNTOPT_SYSVGROUPS)) { 287 !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
283 mp->m_flags &= ~XFS_MOUNT_GRPID; 288 mp->m_flags &= ~XFS_MOUNT_GRPID;
284 } else if (!strcmp(this_char, MNTOPT_WSYNC)) { 289 } else if (!strcmp(this_char, MNTOPT_WSYNC)) {
285 args->flags |= XFSMNT_WSYNC; 290 mp->m_flags |= XFS_MOUNT_WSYNC;
286 } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { 291 } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
287 args->flags |= XFSMNT_OSYNCISOSYNC; 292 mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
288 } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { 293 } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
289 args->flags |= XFSMNT_NORECOVERY; 294 mp->m_flags |= XFS_MOUNT_NORECOVERY;
290 } else if (!strcmp(this_char, MNTOPT_INO64)) { 295 } else if (!strcmp(this_char, MNTOPT_INO64)) {
291 args->flags |= XFSMNT_INO64; 296#if XFS_BIG_INUMS
292#if !XFS_BIG_INUMS 297 mp->m_flags |= XFS_MOUNT_INO64;
298 mp->m_inoadd = XFS_INO64_OFFSET;
299#else
293 cmn_err(CE_WARN, 300 cmn_err(CE_WARN,
294 "XFS: %s option not allowed on this system", 301 "XFS: %s option not allowed on this system",
295 this_char); 302 this_char);
296 return EINVAL; 303 return EINVAL;
297#endif 304#endif
298 } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { 305 } else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
299 args->flags |= XFSMNT_NOALIGN; 306 mp->m_flags |= XFS_MOUNT_NOALIGN;
300 } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { 307 } else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
301 args->flags |= XFSMNT_SWALLOC; 308 mp->m_flags |= XFS_MOUNT_SWALLOC;
302 } else if (!strcmp(this_char, MNTOPT_SUNIT)) { 309 } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
303 if (!value || !*value) { 310 if (!value || !*value) {
304 cmn_err(CE_WARN, 311 cmn_err(CE_WARN,
@@ -316,7 +323,7 @@ xfs_parseargs(
316 } 323 }
317 dswidth = simple_strtoul(value, &eov, 10); 324 dswidth = simple_strtoul(value, &eov, 10);
318 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { 325 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
319 args->flags &= ~XFSMNT_32BITINODES; 326 mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
320#if !XFS_BIG_INUMS 327#if !XFS_BIG_INUMS
321 cmn_err(CE_WARN, 328 cmn_err(CE_WARN,
322 "XFS: %s option not allowed on this system", 329 "XFS: %s option not allowed on this system",
@@ -324,56 +331,60 @@ xfs_parseargs(
324 return EINVAL; 331 return EINVAL;
325#endif 332#endif
326 } else if (!strcmp(this_char, MNTOPT_NOUUID)) { 333 } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
327 args->flags |= XFSMNT_NOUUID; 334 mp->m_flags |= XFS_MOUNT_NOUUID;
328 } else if (!strcmp(this_char, MNTOPT_BARRIER)) { 335 } else if (!strcmp(this_char, MNTOPT_BARRIER)) {
329 args->flags |= XFSMNT_BARRIER; 336 mp->m_flags |= XFS_MOUNT_BARRIER;
330 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { 337 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
331 args->flags &= ~XFSMNT_BARRIER; 338 mp->m_flags &= ~XFS_MOUNT_BARRIER;
332 } else if (!strcmp(this_char, MNTOPT_IKEEP)) { 339 } else if (!strcmp(this_char, MNTOPT_IKEEP)) {
333 args->flags |= XFSMNT_IKEEP; 340 mp->m_flags |= XFS_MOUNT_IKEEP;
334 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { 341 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
335 dmapi_implies_ikeep = 0; 342 dmapi_implies_ikeep = 0;
336 args->flags &= ~XFSMNT_IKEEP; 343 mp->m_flags &= ~XFS_MOUNT_IKEEP;
337 } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { 344 } else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
338 args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE; 345 mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
339 } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { 346 } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
340 args->flags2 |= XFSMNT2_COMPAT_IOSIZE; 347 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
341 } else if (!strcmp(this_char, MNTOPT_ATTR2)) { 348 } else if (!strcmp(this_char, MNTOPT_ATTR2)) {
342 args->flags |= XFSMNT_ATTR2; 349 mp->m_flags |= XFS_MOUNT_ATTR2;
343 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { 350 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
344 args->flags &= ~XFSMNT_ATTR2; 351 mp->m_flags &= ~XFS_MOUNT_ATTR2;
345 args->flags |= XFSMNT_NOATTR2; 352 mp->m_flags |= XFS_MOUNT_NOATTR2;
346 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { 353 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
347 args->flags2 |= XFSMNT2_FILESTREAMS; 354 mp->m_flags |= XFS_MOUNT_FILESTREAMS;
348 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { 355 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
349 args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA); 356 mp->m_qflags &= ~(XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
350 args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA); 357 XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
358 XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD);
351 } else if (!strcmp(this_char, MNTOPT_QUOTA) || 359 } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
352 !strcmp(this_char, MNTOPT_UQUOTA) || 360 !strcmp(this_char, MNTOPT_UQUOTA) ||
353 !strcmp(this_char, MNTOPT_USRQUOTA)) { 361 !strcmp(this_char, MNTOPT_USRQUOTA)) {
354 args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF; 362 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
363 XFS_UQUOTA_ENFD);
355 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || 364 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
356 !strcmp(this_char, MNTOPT_UQUOTANOENF)) { 365 !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
357 args->flags |= XFSMNT_UQUOTA; 366 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
358 args->flags &= ~XFSMNT_UQUOTAENF; 367 mp->m_qflags &= ~XFS_UQUOTA_ENFD;
359 } else if (!strcmp(this_char, MNTOPT_PQUOTA) || 368 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
360 !strcmp(this_char, MNTOPT_PRJQUOTA)) { 369 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
361 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF; 370 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
371 XFS_OQUOTA_ENFD);
362 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { 372 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
363 args->flags |= XFSMNT_PQUOTA; 373 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
364 args->flags &= ~XFSMNT_PQUOTAENF; 374 mp->m_qflags &= ~XFS_OQUOTA_ENFD;
365 } else if (!strcmp(this_char, MNTOPT_GQUOTA) || 375 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
366 !strcmp(this_char, MNTOPT_GRPQUOTA)) { 376 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
367 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; 377 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
378 XFS_OQUOTA_ENFD);
368 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { 379 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
369 args->flags |= XFSMNT_GQUOTA; 380 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
370 args->flags &= ~XFSMNT_GQUOTAENF; 381 mp->m_qflags &= ~XFS_OQUOTA_ENFD;
371 } else if (!strcmp(this_char, MNTOPT_DMAPI)) { 382 } else if (!strcmp(this_char, MNTOPT_DMAPI)) {
372 args->flags |= XFSMNT_DMAPI; 383 mp->m_flags |= XFS_MOUNT_DMAPI;
373 } else if (!strcmp(this_char, MNTOPT_XDSM)) { 384 } else if (!strcmp(this_char, MNTOPT_XDSM)) {
374 args->flags |= XFSMNT_DMAPI; 385 mp->m_flags |= XFS_MOUNT_DMAPI;
375 } else if (!strcmp(this_char, MNTOPT_DMI)) { 386 } else if (!strcmp(this_char, MNTOPT_DMI)) {
376 args->flags |= XFSMNT_DMAPI; 387 mp->m_flags |= XFS_MOUNT_DMAPI;
377 } else if (!strcmp(this_char, "ihashsize")) { 388 } else if (!strcmp(this_char, "ihashsize")) {
378 cmn_err(CE_WARN, 389 cmn_err(CE_WARN,
379 "XFS: ihashsize no longer used, option is deprecated."); 390 "XFS: ihashsize no longer used, option is deprecated.");
@@ -391,27 +402,29 @@ xfs_parseargs(
391 } 402 }
392 } 403 }
393 404
394 if (args->flags & XFSMNT_NORECOVERY) { 405 /*
395 if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) { 406 * no recovery flag requires a read-only mount
396 cmn_err(CE_WARN, 407 */
397 "XFS: no-recovery mounts must be read-only."); 408 if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
398 return EINVAL; 409 !(mp->m_flags & XFS_MOUNT_RDONLY)) {
399 } 410 cmn_err(CE_WARN, "XFS: no-recovery mounts must be read-only.");
411 return EINVAL;
400 } 412 }
401 413
402 if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) { 414 if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) {
403 cmn_err(CE_WARN, 415 cmn_err(CE_WARN,
404 "XFS: sunit and swidth options incompatible with the noalign option"); 416 "XFS: sunit and swidth options incompatible with the noalign option");
405 return EINVAL; 417 return EINVAL;
406 } 418 }
407 419
408 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) { 420 if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) &&
421 (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) {
409 cmn_err(CE_WARN, 422 cmn_err(CE_WARN,
410 "XFS: cannot mount with both project and group quota"); 423 "XFS: cannot mount with both project and group quota");
411 return EINVAL; 424 return EINVAL;
412 } 425 }
413 426
414 if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') { 427 if ((mp->m_flags & XFS_MOUNT_DMAPI) && (!*mtpt || *mtpt[0] == '\0')) {
415 printk("XFS: %s option needs the mount point option as well\n", 428 printk("XFS: %s option needs the mount point option as well\n",
416 MNTOPT_DMAPI); 429 MNTOPT_DMAPI);
417 return EINVAL; 430 return EINVAL;
@@ -439,27 +452,66 @@ xfs_parseargs(
439 * Note that if "ikeep" or "noikeep" mount options are 452 * Note that if "ikeep" or "noikeep" mount options are
440 * supplied, then they are honored. 453 * supplied, then they are honored.
441 */ 454 */
442 if ((args->flags & XFSMNT_DMAPI) && dmapi_implies_ikeep) 455 if ((mp->m_flags & XFS_MOUNT_DMAPI) && dmapi_implies_ikeep)
443 args->flags |= XFSMNT_IKEEP; 456 mp->m_flags |= XFS_MOUNT_IKEEP;
444 457
445 if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { 458done:
459 if (!(mp->m_flags & XFS_MOUNT_NOALIGN)) {
460 /*
461 * At this point the superblock has not been read
462 * in, therefore we do not know the block size.
463 * Before the mount call ends we will convert
464 * these to FSBs.
465 */
446 if (dsunit) { 466 if (dsunit) {
447 args->sunit = dsunit; 467 mp->m_dalign = dsunit;
448 args->flags |= XFSMNT_RETERR; 468 mp->m_flags |= XFS_MOUNT_RETERR;
449 } else {
450 args->sunit = vol_dsunit;
451 } 469 }
452 dswidth ? (args->swidth = dswidth) : 470
453 (args->swidth = vol_dswidth); 471 if (dswidth)
454 } else { 472 mp->m_swidth = dswidth;
455 args->sunit = args->swidth = 0; 473 }
474
475 if (mp->m_logbufs != -1 &&
476 mp->m_logbufs != 0 &&
477 (mp->m_logbufs < XLOG_MIN_ICLOGS ||
478 mp->m_logbufs > XLOG_MAX_ICLOGS)) {
479 cmn_err(CE_WARN,
480 "XFS: invalid logbufs value: %d [not %d-%d]",
481 mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
482 return XFS_ERROR(EINVAL);
483 }
484 if (mp->m_logbsize != -1 &&
485 mp->m_logbsize != 0 &&
486 (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE ||
487 mp->m_logbsize > XLOG_MAX_RECORD_BSIZE ||
488 !is_power_of_2(mp->m_logbsize))) {
489 cmn_err(CE_WARN,
490 "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
491 mp->m_logbsize);
492 return XFS_ERROR(EINVAL);
493 }
494
495 mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL);
496 if (!mp->m_fsname)
497 return ENOMEM;
498 mp->m_fsname_len = strlen(mp->m_fsname) + 1;
499
500 if (iosizelog) {
501 if (iosizelog > XFS_MAX_IO_LOG ||
502 iosizelog < XFS_MIN_IO_LOG) {
503 cmn_err(CE_WARN,
504 "XFS: invalid log iosize: %d [not %d-%d]",
505 iosizelog, XFS_MIN_IO_LOG,
506 XFS_MAX_IO_LOG);
507 return XFS_ERROR(EINVAL);
508 }
509
510 mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
511 mp->m_readio_log = iosizelog;
512 mp->m_writeio_log = iosizelog;
456 } 513 }
457 514
458done:
459 if (args->flags & XFSMNT_32BITINODES)
460 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
461 if (args->flags2)
462 args->flags |= XFSMNT_FLAGS2;
463 return 0; 515 return 0;
464} 516}
465 517
@@ -705,8 +757,7 @@ xfs_close_devices(
705 */ 757 */
706STATIC int 758STATIC int
707xfs_open_devices( 759xfs_open_devices(
708 struct xfs_mount *mp, 760 struct xfs_mount *mp)
709 struct xfs_mount_args *args)
710{ 761{
711 struct block_device *ddev = mp->m_super->s_bdev; 762 struct block_device *ddev = mp->m_super->s_bdev;
712 struct block_device *logdev = NULL, *rtdev = NULL; 763 struct block_device *logdev = NULL, *rtdev = NULL;
@@ -715,14 +766,14 @@ xfs_open_devices(
715 /* 766 /*
716 * Open real time and log devices - order is important. 767 * Open real time and log devices - order is important.
717 */ 768 */
718 if (args->logname[0]) { 769 if (mp->m_logname) {
719 error = xfs_blkdev_get(mp, args->logname, &logdev); 770 error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
720 if (error) 771 if (error)
721 goto out; 772 goto out;
722 } 773 }
723 774
724 if (args->rtname[0]) { 775 if (mp->m_rtname) {
725 error = xfs_blkdev_get(mp, args->rtname, &rtdev); 776 error = xfs_blkdev_get(mp, mp->m_rtname, &rtdev);
726 if (error) 777 if (error)
727 goto out_close_logdev; 778 goto out_close_logdev;
728 779
@@ -1288,175 +1339,28 @@ xfs_fs_setxquota(
1288 1339
1289/* 1340/*
1290 * This function fills in xfs_mount_t fields based on mount args. 1341 * This function fills in xfs_mount_t fields based on mount args.
1291 * Note: the superblock has _not_ yet been read in.
1292 */
1293STATIC int
1294xfs_start_flags(
1295 struct xfs_mount_args *ap,
1296 struct xfs_mount *mp)
1297{
1298 int error;
1299
1300 /* Values are in BBs */
1301 if ((ap->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
1302 /*
1303 * At this point the superblock has not been read
1304 * in, therefore we do not know the block size.
1305 * Before the mount call ends we will convert
1306 * these to FSBs.
1307 */
1308 mp->m_dalign = ap->sunit;
1309 mp->m_swidth = ap->swidth;
1310 }
1311
1312 if (ap->logbufs != -1 &&
1313 ap->logbufs != 0 &&
1314 (ap->logbufs < XLOG_MIN_ICLOGS ||
1315 ap->logbufs > XLOG_MAX_ICLOGS)) {
1316 cmn_err(CE_WARN,
1317 "XFS: invalid logbufs value: %d [not %d-%d]",
1318 ap->logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
1319 return XFS_ERROR(EINVAL);
1320 }
1321 mp->m_logbufs = ap->logbufs;
1322 if (ap->logbufsize != -1 &&
1323 ap->logbufsize != 0 &&
1324 (ap->logbufsize < XLOG_MIN_RECORD_BSIZE ||
1325 ap->logbufsize > XLOG_MAX_RECORD_BSIZE ||
1326 !is_power_of_2(ap->logbufsize))) {
1327 cmn_err(CE_WARN,
1328 "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
1329 ap->logbufsize);
1330 return XFS_ERROR(EINVAL);
1331 }
1332
1333 error = ENOMEM;
1334
1335 mp->m_logbsize = ap->logbufsize;
1336 mp->m_fsname_len = strlen(ap->fsname) + 1;
1337
1338 mp->m_fsname = kstrdup(ap->fsname, GFP_KERNEL);
1339 if (!mp->m_fsname)
1340 goto out;
1341
1342 if (ap->rtname[0]) {
1343 mp->m_rtname = kstrdup(ap->rtname, GFP_KERNEL);
1344 if (!mp->m_rtname)
1345 goto out_free_fsname;
1346
1347 }
1348
1349 if (ap->logname[0]) {
1350 mp->m_logname = kstrdup(ap->logname, GFP_KERNEL);
1351 if (!mp->m_logname)
1352 goto out_free_rtname;
1353 }
1354
1355 if (ap->flags & XFSMNT_WSYNC)
1356 mp->m_flags |= XFS_MOUNT_WSYNC;
1357#if XFS_BIG_INUMS
1358 if (ap->flags & XFSMNT_INO64) {
1359 mp->m_flags |= XFS_MOUNT_INO64;
1360 mp->m_inoadd = XFS_INO64_OFFSET;
1361 }
1362#endif
1363 if (ap->flags & XFSMNT_RETERR)
1364 mp->m_flags |= XFS_MOUNT_RETERR;
1365 if (ap->flags & XFSMNT_NOALIGN)
1366 mp->m_flags |= XFS_MOUNT_NOALIGN;
1367 if (ap->flags & XFSMNT_SWALLOC)
1368 mp->m_flags |= XFS_MOUNT_SWALLOC;
1369 if (ap->flags & XFSMNT_OSYNCISOSYNC)
1370 mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
1371 if (ap->flags & XFSMNT_32BITINODES)
1372 mp->m_flags |= XFS_MOUNT_32BITINODES;
1373
1374 if (ap->flags & XFSMNT_IOSIZE) {
1375 if (ap->iosizelog > XFS_MAX_IO_LOG ||
1376 ap->iosizelog < XFS_MIN_IO_LOG) {
1377 cmn_err(CE_WARN,
1378 "XFS: invalid log iosize: %d [not %d-%d]",
1379 ap->iosizelog, XFS_MIN_IO_LOG,
1380 XFS_MAX_IO_LOG);
1381 return XFS_ERROR(EINVAL);
1382 }
1383
1384 mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
1385 mp->m_readio_log = mp->m_writeio_log = ap->iosizelog;
1386 }
1387
1388 if (ap->flags & XFSMNT_IKEEP)
1389 mp->m_flags |= XFS_MOUNT_IKEEP;
1390 if (ap->flags & XFSMNT_DIRSYNC)
1391 mp->m_flags |= XFS_MOUNT_DIRSYNC;
1392 if (ap->flags & XFSMNT_ATTR2)
1393 mp->m_flags |= XFS_MOUNT_ATTR2;
1394 if (ap->flags & XFSMNT_NOATTR2)
1395 mp->m_flags |= XFS_MOUNT_NOATTR2;
1396
1397 if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE)
1398 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
1399
1400 /*
1401 * no recovery flag requires a read-only mount
1402 */
1403 if (ap->flags & XFSMNT_NORECOVERY) {
1404 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
1405 cmn_err(CE_WARN,
1406 "XFS: tried to mount a FS read-write without recovery!");
1407 return XFS_ERROR(EINVAL);
1408 }
1409 mp->m_flags |= XFS_MOUNT_NORECOVERY;
1410 }
1411
1412 if (ap->flags & XFSMNT_NOUUID)
1413 mp->m_flags |= XFS_MOUNT_NOUUID;
1414 if (ap->flags & XFSMNT_BARRIER)
1415 mp->m_flags |= XFS_MOUNT_BARRIER;
1416 else
1417 mp->m_flags &= ~XFS_MOUNT_BARRIER;
1418
1419 if (ap->flags2 & XFSMNT2_FILESTREAMS)
1420 mp->m_flags |= XFS_MOUNT_FILESTREAMS;
1421
1422 if (ap->flags & XFSMNT_DMAPI)
1423 mp->m_flags |= XFS_MOUNT_DMAPI;
1424 return 0;
1425
1426
1427 out_free_rtname:
1428 kfree(mp->m_rtname);
1429 out_free_fsname:
1430 kfree(mp->m_fsname);
1431 out:
1432 return error;
1433}
1434
1435/*
1436 * This function fills in xfs_mount_t fields based on mount args.
1437 * Note: the superblock _has_ now been read in. 1342 * Note: the superblock _has_ now been read in.
1438 */ 1343 */
1439STATIC int 1344STATIC int
1440xfs_finish_flags( 1345xfs_finish_flags(
1441 struct xfs_mount_args *ap,
1442 struct xfs_mount *mp) 1346 struct xfs_mount *mp)
1443{ 1347{
1444 int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); 1348 int ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
1445 1349
1446 /* Fail a mount where the logbuf is smaller then the log stripe */ 1350 /* Fail a mount where the logbuf is smaller then the log stripe */
1447 if (xfs_sb_version_haslogv2(&mp->m_sb)) { 1351 if (xfs_sb_version_haslogv2(&mp->m_sb)) {
1448 if ((ap->logbufsize <= 0) && 1352 if (mp->m_logbsize <= 0 &&
1449 (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) { 1353 mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) {
1450 mp->m_logbsize = mp->m_sb.sb_logsunit; 1354 mp->m_logbsize = mp->m_sb.sb_logsunit;
1451 } else if (ap->logbufsize > 0 && 1355 } else if (mp->m_logbsize > 0 &&
1452 ap->logbufsize < mp->m_sb.sb_logsunit) { 1356 mp->m_logbsize < mp->m_sb.sb_logsunit) {
1453 cmn_err(CE_WARN, 1357 cmn_err(CE_WARN,
1454 "XFS: logbuf size must be greater than or equal to log stripe size"); 1358 "XFS: logbuf size must be greater than or equal to log stripe size");
1455 return XFS_ERROR(EINVAL); 1359 return XFS_ERROR(EINVAL);
1456 } 1360 }
1457 } else { 1361 } else {
1458 /* Fail a mount if the logbuf is larger than 32K */ 1362 /* Fail a mount if the logbuf is larger than 32K */
1459 if (ap->logbufsize > XLOG_BIG_RECORD_BSIZE) { 1363 if (mp->m_logbsize > XLOG_BIG_RECORD_BSIZE) {
1460 cmn_err(CE_WARN, 1364 cmn_err(CE_WARN,
1461 "XFS: logbuf size for version 1 logs must be 16K or 32K"); 1365 "XFS: logbuf size for version 1 logs must be 16K or 32K");
1462 return XFS_ERROR(EINVAL); 1366 return XFS_ERROR(EINVAL);
@@ -1468,7 +1372,7 @@ xfs_finish_flags(
1468 * told by noattr2 to turn it off 1372 * told by noattr2 to turn it off
1469 */ 1373 */
1470 if (xfs_sb_version_hasattr2(&mp->m_sb) && 1374 if (xfs_sb_version_hasattr2(&mp->m_sb) &&
1471 !(ap->flags & XFSMNT_NOATTR2)) 1375 !(mp->m_flags & XFS_MOUNT_NOATTR2))
1472 mp->m_flags |= XFS_MOUNT_ATTR2; 1376 mp->m_flags |= XFS_MOUNT_ATTR2;
1473 1377
1474 /* 1378 /*
@@ -1480,6 +1384,7 @@ xfs_finish_flags(
1480 return XFS_ERROR(EROFS); 1384 return XFS_ERROR(EROFS);
1481 } 1385 }
1482 1386
1387#if 0 /* shared mounts were never supported on Linux */
1483 /* 1388 /*
1484 * check for shared mount. 1389 * check for shared mount.
1485 */ 1390 */
@@ -1502,25 +1407,11 @@ xfs_finish_flags(
1502 /* 1407 /*
1503 * Shared XFS V0 can't deal with DMI. Return EINVAL. 1408 * Shared XFS V0 can't deal with DMI. Return EINVAL.
1504 */ 1409 */
1505 if (mp->m_sb.sb_shared_vn == 0 && (ap->flags & XFSMNT_DMAPI)) 1410 if (mp->m_sb.sb_shared_vn == 0 &&
1411 (mp->m_flags & XFS_MOUNT_DMAPI))
1506 return XFS_ERROR(EINVAL); 1412 return XFS_ERROR(EINVAL);
1507 } 1413 }
1508 1414#endif
1509 if (ap->flags & XFSMNT_UQUOTA) {
1510 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
1511 if (ap->flags & XFSMNT_UQUOTAENF)
1512 mp->m_qflags |= XFS_UQUOTA_ENFD;
1513 }
1514
1515 if (ap->flags & XFSMNT_GQUOTA) {
1516 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
1517 if (ap->flags & XFSMNT_GQUOTAENF)
1518 mp->m_qflags |= XFS_OQUOTA_ENFD;
1519 } else if (ap->flags & XFSMNT_PQUOTA) {
1520 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
1521 if (ap->flags & XFSMNT_PQUOTAENF)
1522 mp->m_qflags |= XFS_OQUOTA_ENFD;
1523 }
1524 1415
1525 return 0; 1416 return 0;
1526} 1417}
@@ -1533,16 +1424,12 @@ xfs_fs_fill_super(
1533{ 1424{
1534 struct inode *root; 1425 struct inode *root;
1535 struct xfs_mount *mp = NULL; 1426 struct xfs_mount *mp = NULL;
1536 struct xfs_mount_args *args;
1537 int flags = 0, error = ENOMEM; 1427 int flags = 0, error = ENOMEM;
1538 1428 char *mtpt = NULL;
1539 args = xfs_args_allocate(sb, silent);
1540 if (!args)
1541 return -ENOMEM;
1542 1429
1543 mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); 1430 mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL);
1544 if (!mp) 1431 if (!mp)
1545 goto out_free_args; 1432 goto out;
1546 1433
1547 spin_lock_init(&mp->m_sb_lock); 1434 spin_lock_init(&mp->m_sb_lock);
1548 mutex_init(&mp->m_growlock); 1435 mutex_init(&mp->m_growlock);
@@ -1554,12 +1441,9 @@ xfs_fs_fill_super(
1554 mp->m_super = sb; 1441 mp->m_super = sb;
1555 sb->s_fs_info = mp; 1442 sb->s_fs_info = mp;
1556 1443
1557 if (sb->s_flags & MS_RDONLY) 1444 error = xfs_parseargs(mp, (char *)data, &mtpt);
1558 mp->m_flags |= XFS_MOUNT_RDONLY;
1559
1560 error = xfs_parseargs(mp, (char *)data, args, 0);
1561 if (error) 1445 if (error)
1562 goto out_free_mp; 1446 goto out_free_fsname;
1563 1447
1564 sb_min_blocksize(sb, BBSIZE); 1448 sb_min_blocksize(sb, BBSIZE);
1565 sb->s_xattr = xfs_xattr_handlers; 1449 sb->s_xattr = xfs_xattr_handlers;
@@ -1567,33 +1451,28 @@ xfs_fs_fill_super(
1567 sb->s_qcop = &xfs_quotactl_operations; 1451 sb->s_qcop = &xfs_quotactl_operations;
1568 sb->s_op = &xfs_super_operations; 1452 sb->s_op = &xfs_super_operations;
1569 1453
1570 error = xfs_dmops_get(mp, args); 1454 error = xfs_dmops_get(mp);
1571 if (error) 1455 if (error)
1572 goto out_free_mp; 1456 goto out_free_fsname;
1573 error = xfs_qmops_get(mp, args); 1457 error = xfs_qmops_get(mp);
1574 if (error) 1458 if (error)
1575 goto out_put_dmops; 1459 goto out_put_dmops;
1576 1460
1577 if (args->flags & XFSMNT_QUIET) 1461 if (silent)
1578 flags |= XFS_MFSI_QUIET; 1462 flags |= XFS_MFSI_QUIET;
1579 1463
1580 error = xfs_open_devices(mp, args); 1464 error = xfs_open_devices(mp);
1581 if (error) 1465 if (error)
1582 goto out_put_qmops; 1466 goto out_put_qmops;
1583 1467
1584 if (xfs_icsb_init_counters(mp)) 1468 if (xfs_icsb_init_counters(mp))
1585 mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; 1469 mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB;
1586 1470
1587 /*
1588 * Setup flags based on mount(2) options and then the superblock
1589 */
1590 error = xfs_start_flags(args, mp);
1591 if (error)
1592 goto out_free_fsname;
1593 error = xfs_readsb(mp, flags); 1471 error = xfs_readsb(mp, flags);
1594 if (error) 1472 if (error)
1595 goto out_free_fsname; 1473 goto out_destroy_counters;
1596 error = xfs_finish_flags(args, mp); 1474
1475 error = xfs_finish_flags(mp);
1597 if (error) 1476 if (error)
1598 goto out_free_sb; 1477 goto out_free_sb;
1599 1478
@@ -1612,7 +1491,7 @@ xfs_fs_fill_super(
1612 if (error) 1491 if (error)
1613 goto out_filestream_unmount; 1492 goto out_filestream_unmount;
1614 1493
1615 XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname); 1494 XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, mtpt, mp->m_fsname);
1616 1495
1617 sb->s_dirt = 1; 1496 sb->s_dirt = 1;
1618 sb->s_magic = XFS_SB_MAGIC; 1497 sb->s_magic = XFS_SB_MAGIC;
@@ -1641,27 +1520,27 @@ xfs_fs_fill_super(
1641 if (error) 1520 if (error)
1642 goto fail_vnrele; 1521 goto fail_vnrele;
1643 1522
1644 xfs_itrace_exit(XFS_I(sb->s_root->d_inode)); 1523 kfree(mtpt);
1645 1524
1646 kfree(args); 1525 xfs_itrace_exit(XFS_I(sb->s_root->d_inode));
1647 return 0; 1526 return 0;
1648 1527
1649 out_filestream_unmount: 1528 out_filestream_unmount:
1650 xfs_filestream_unmount(mp); 1529 xfs_filestream_unmount(mp);
1651 out_free_sb: 1530 out_free_sb:
1652 xfs_freesb(mp); 1531 xfs_freesb(mp);
1653 out_free_fsname: 1532 out_destroy_counters:
1654 xfs_free_fsname(mp);
1655 xfs_icsb_destroy_counters(mp); 1533 xfs_icsb_destroy_counters(mp);
1656 xfs_close_devices(mp); 1534 xfs_close_devices(mp);
1657 out_put_qmops: 1535 out_put_qmops:
1658 xfs_qmops_put(mp); 1536 xfs_qmops_put(mp);
1659 out_put_dmops: 1537 out_put_dmops:
1660 xfs_dmops_put(mp); 1538 xfs_dmops_put(mp);
1661 out_free_mp: 1539 out_free_fsname:
1540 xfs_free_fsname(mp);
1541 kfree(mtpt);
1662 kfree(mp); 1542 kfree(mp);
1663 out_free_args: 1543 out:
1664 kfree(args);
1665 return -error; 1544 return -error;
1666 1545
1667 fail_vnrele: 1546 fail_vnrele: