diff options
author | Christoph Hellwig <hch@infradead.org> | 2008-05-19 21:30:59 -0400 |
---|---|---|
committer | Niv Sardi <xaiki@debian.org> | 2008-07-28 02:58:21 -0400 |
commit | f8f15e42b408edce6ca9e9d8bd0d0e2078a39efd (patch) | |
tree | f54b232eff9f335f4dae890cf0fa72eead07b585 /fs/xfs/xfs_vfsops.c | |
parent | e48ad3160e5c5f5b952c7a7ed814f6f289a60100 (diff) |
[XFS] merge xfs_mount into xfs_fs_fill_super
xfs_mount is already pretty linux-specific so merge it into
xfs_fs_fill_super to allow for a more structured mount code in the next
patches. xfs_start_flags and xfs_finish_flags also move to xfs_super.c.
SGI-PV: 981951
SGI-Modid: xfs-linux-melb:xfs-kern:31189a
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_vfsops.c')
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 369 |
1 files changed, 0 insertions, 369 deletions
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index bc34f90e7eea..8b5a3376c2f7 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -189,375 +189,6 @@ xfs_cleanup(void) | |||
189 | kmem_zone_destroy(xfs_log_ticket_zone); | 189 | kmem_zone_destroy(xfs_log_ticket_zone); |
190 | } | 190 | } |
191 | 191 | ||
192 | /* | ||
193 | * xfs_start_flags | ||
194 | * | ||
195 | * This function fills in xfs_mount_t fields based on mount args. | ||
196 | * Note: the superblock has _not_ yet been read in. | ||
197 | */ | ||
198 | STATIC int | ||
199 | xfs_start_flags( | ||
200 | struct xfs_mount_args *ap, | ||
201 | struct xfs_mount *mp) | ||
202 | { | ||
203 | /* Values are in BBs */ | ||
204 | if ((ap->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { | ||
205 | /* | ||
206 | * At this point the superblock has not been read | ||
207 | * in, therefore we do not know the block size. | ||
208 | * Before the mount call ends we will convert | ||
209 | * these to FSBs. | ||
210 | */ | ||
211 | mp->m_dalign = ap->sunit; | ||
212 | mp->m_swidth = ap->swidth; | ||
213 | } | ||
214 | |||
215 | if (ap->logbufs != -1 && | ||
216 | ap->logbufs != 0 && | ||
217 | (ap->logbufs < XLOG_MIN_ICLOGS || | ||
218 | ap->logbufs > XLOG_MAX_ICLOGS)) { | ||
219 | cmn_err(CE_WARN, | ||
220 | "XFS: invalid logbufs value: %d [not %d-%d]", | ||
221 | ap->logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); | ||
222 | return XFS_ERROR(EINVAL); | ||
223 | } | ||
224 | mp->m_logbufs = ap->logbufs; | ||
225 | if (ap->logbufsize != -1 && | ||
226 | ap->logbufsize != 0 && | ||
227 | (ap->logbufsize < XLOG_MIN_RECORD_BSIZE || | ||
228 | ap->logbufsize > XLOG_MAX_RECORD_BSIZE || | ||
229 | !is_power_of_2(ap->logbufsize))) { | ||
230 | cmn_err(CE_WARN, | ||
231 | "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", | ||
232 | ap->logbufsize); | ||
233 | return XFS_ERROR(EINVAL); | ||
234 | } | ||
235 | mp->m_logbsize = ap->logbufsize; | ||
236 | mp->m_fsname_len = strlen(ap->fsname) + 1; | ||
237 | mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP); | ||
238 | strcpy(mp->m_fsname, ap->fsname); | ||
239 | if (ap->rtname[0]) { | ||
240 | mp->m_rtname = kmem_alloc(strlen(ap->rtname) + 1, KM_SLEEP); | ||
241 | strcpy(mp->m_rtname, ap->rtname); | ||
242 | } | ||
243 | if (ap->logname[0]) { | ||
244 | mp->m_logname = kmem_alloc(strlen(ap->logname) + 1, KM_SLEEP); | ||
245 | strcpy(mp->m_logname, ap->logname); | ||
246 | } | ||
247 | |||
248 | if (ap->flags & XFSMNT_WSYNC) | ||
249 | mp->m_flags |= XFS_MOUNT_WSYNC; | ||
250 | #if XFS_BIG_INUMS | ||
251 | if (ap->flags & XFSMNT_INO64) { | ||
252 | mp->m_flags |= XFS_MOUNT_INO64; | ||
253 | mp->m_inoadd = XFS_INO64_OFFSET; | ||
254 | } | ||
255 | #endif | ||
256 | if (ap->flags & XFSMNT_RETERR) | ||
257 | mp->m_flags |= XFS_MOUNT_RETERR; | ||
258 | if (ap->flags & XFSMNT_NOALIGN) | ||
259 | mp->m_flags |= XFS_MOUNT_NOALIGN; | ||
260 | if (ap->flags & XFSMNT_SWALLOC) | ||
261 | mp->m_flags |= XFS_MOUNT_SWALLOC; | ||
262 | if (ap->flags & XFSMNT_OSYNCISOSYNC) | ||
263 | mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC; | ||
264 | if (ap->flags & XFSMNT_32BITINODES) | ||
265 | mp->m_flags |= XFS_MOUNT_32BITINODES; | ||
266 | |||
267 | if (ap->flags & XFSMNT_IOSIZE) { | ||
268 | if (ap->iosizelog > XFS_MAX_IO_LOG || | ||
269 | ap->iosizelog < XFS_MIN_IO_LOG) { | ||
270 | cmn_err(CE_WARN, | ||
271 | "XFS: invalid log iosize: %d [not %d-%d]", | ||
272 | ap->iosizelog, XFS_MIN_IO_LOG, | ||
273 | XFS_MAX_IO_LOG); | ||
274 | return XFS_ERROR(EINVAL); | ||
275 | } | ||
276 | |||
277 | mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; | ||
278 | mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; | ||
279 | } | ||
280 | |||
281 | if (ap->flags & XFSMNT_IKEEP) | ||
282 | mp->m_flags |= XFS_MOUNT_IKEEP; | ||
283 | if (ap->flags & XFSMNT_DIRSYNC) | ||
284 | mp->m_flags |= XFS_MOUNT_DIRSYNC; | ||
285 | if (ap->flags & XFSMNT_ATTR2) | ||
286 | mp->m_flags |= XFS_MOUNT_ATTR2; | ||
287 | if (ap->flags & XFSMNT_NOATTR2) | ||
288 | mp->m_flags |= XFS_MOUNT_NOATTR2; | ||
289 | |||
290 | if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE) | ||
291 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | ||
292 | |||
293 | /* | ||
294 | * no recovery flag requires a read-only mount | ||
295 | */ | ||
296 | if (ap->flags & XFSMNT_NORECOVERY) { | ||
297 | if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { | ||
298 | cmn_err(CE_WARN, | ||
299 | "XFS: tried to mount a FS read-write without recovery!"); | ||
300 | return XFS_ERROR(EINVAL); | ||
301 | } | ||
302 | mp->m_flags |= XFS_MOUNT_NORECOVERY; | ||
303 | } | ||
304 | |||
305 | if (ap->flags & XFSMNT_NOUUID) | ||
306 | mp->m_flags |= XFS_MOUNT_NOUUID; | ||
307 | if (ap->flags & XFSMNT_BARRIER) | ||
308 | mp->m_flags |= XFS_MOUNT_BARRIER; | ||
309 | else | ||
310 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
311 | |||
312 | if (ap->flags2 & XFSMNT2_FILESTREAMS) | ||
313 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; | ||
314 | |||
315 | if (ap->flags & XFSMNT_DMAPI) | ||
316 | mp->m_flags |= XFS_MOUNT_DMAPI; | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | /* | ||
321 | * This function fills in xfs_mount_t fields based on mount args. | ||
322 | * Note: the superblock _has_ now been read in. | ||
323 | */ | ||
324 | STATIC int | ||
325 | xfs_finish_flags( | ||
326 | struct xfs_mount_args *ap, | ||
327 | struct xfs_mount *mp) | ||
328 | { | ||
329 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); | ||
330 | |||
331 | /* Fail a mount where the logbuf is smaller then the log stripe */ | ||
332 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { | ||
333 | if ((ap->logbufsize <= 0) && | ||
334 | (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) { | ||
335 | mp->m_logbsize = mp->m_sb.sb_logsunit; | ||
336 | } else if (ap->logbufsize > 0 && | ||
337 | ap->logbufsize < mp->m_sb.sb_logsunit) { | ||
338 | cmn_err(CE_WARN, | ||
339 | "XFS: logbuf size must be greater than or equal to log stripe size"); | ||
340 | return XFS_ERROR(EINVAL); | ||
341 | } | ||
342 | } else { | ||
343 | /* Fail a mount if the logbuf is larger than 32K */ | ||
344 | if (ap->logbufsize > XLOG_BIG_RECORD_BSIZE) { | ||
345 | cmn_err(CE_WARN, | ||
346 | "XFS: logbuf size for version 1 logs must be 16K or 32K"); | ||
347 | return XFS_ERROR(EINVAL); | ||
348 | } | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | * mkfs'ed attr2 will turn on attr2 mount unless explicitly | ||
353 | * told by noattr2 to turn it off | ||
354 | */ | ||
355 | if (xfs_sb_version_hasattr2(&mp->m_sb) && | ||
356 | !(ap->flags & XFSMNT_NOATTR2)) | ||
357 | mp->m_flags |= XFS_MOUNT_ATTR2; | ||
358 | |||
359 | /* | ||
360 | * prohibit r/w mounts of read-only filesystems | ||
361 | */ | ||
362 | if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) { | ||
363 | cmn_err(CE_WARN, | ||
364 | "XFS: cannot mount a read-only filesystem as read-write"); | ||
365 | return XFS_ERROR(EROFS); | ||
366 | } | ||
367 | |||
368 | /* | ||
369 | * check for shared mount. | ||
370 | */ | ||
371 | if (ap->flags & XFSMNT_SHARED) { | ||
372 | if (!xfs_sb_version_hasshared(&mp->m_sb)) | ||
373 | return XFS_ERROR(EINVAL); | ||
374 | |||
375 | /* | ||
376 | * For IRIX 6.5, shared mounts must have the shared | ||
377 | * version bit set, have the persistent readonly | ||
378 | * field set, must be version 0 and can only be mounted | ||
379 | * read-only. | ||
380 | */ | ||
381 | if (!ronly || !(mp->m_sb.sb_flags & XFS_SBF_READONLY) || | ||
382 | (mp->m_sb.sb_shared_vn != 0)) | ||
383 | return XFS_ERROR(EINVAL); | ||
384 | |||
385 | mp->m_flags |= XFS_MOUNT_SHARED; | ||
386 | |||
387 | /* | ||
388 | * Shared XFS V0 can't deal with DMI. Return EINVAL. | ||
389 | */ | ||
390 | if (mp->m_sb.sb_shared_vn == 0 && (ap->flags & XFSMNT_DMAPI)) | ||
391 | return XFS_ERROR(EINVAL); | ||
392 | } | ||
393 | |||
394 | if (ap->flags & XFSMNT_UQUOTA) { | ||
395 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); | ||
396 | if (ap->flags & XFSMNT_UQUOTAENF) | ||
397 | mp->m_qflags |= XFS_UQUOTA_ENFD; | ||
398 | } | ||
399 | |||
400 | if (ap->flags & XFSMNT_GQUOTA) { | ||
401 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | ||
402 | if (ap->flags & XFSMNT_GQUOTAENF) | ||
403 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
404 | } else if (ap->flags & XFSMNT_PQUOTA) { | ||
405 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); | ||
406 | if (ap->flags & XFSMNT_PQUOTAENF) | ||
407 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
408 | } | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | /* | ||
414 | * xfs_mount | ||
415 | * | ||
416 | * The file system configurations are: | ||
417 | * (1) device (partition) with data and internal log | ||
418 | * (2) logical volume with data and log subvolumes. | ||
419 | * (3) logical volume with data, log, and realtime subvolumes. | ||
420 | * | ||
421 | * We only have to handle opening the log and realtime volumes here if | ||
422 | * they are present. The data subvolume has already been opened by | ||
423 | * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev. | ||
424 | */ | ||
425 | int | ||
426 | xfs_mount( | ||
427 | struct xfs_mount *mp, | ||
428 | struct xfs_mount_args *args, | ||
429 | cred_t *credp) | ||
430 | { | ||
431 | struct block_device *ddev, *logdev, *rtdev; | ||
432 | int flags = 0, error; | ||
433 | |||
434 | ddev = mp->m_super->s_bdev; | ||
435 | logdev = rtdev = NULL; | ||
436 | |||
437 | error = xfs_dmops_get(mp, args); | ||
438 | if (error) | ||
439 | return error; | ||
440 | error = xfs_qmops_get(mp, args); | ||
441 | if (error) | ||
442 | return error; | ||
443 | |||
444 | if (args->flags & XFSMNT_QUIET) | ||
445 | flags |= XFS_MFSI_QUIET; | ||
446 | |||
447 | /* | ||
448 | * Open real time and log devices - order is important. | ||
449 | */ | ||
450 | if (args->logname[0]) { | ||
451 | error = xfs_blkdev_get(mp, args->logname, &logdev); | ||
452 | if (error) | ||
453 | return error; | ||
454 | } | ||
455 | if (args->rtname[0]) { | ||
456 | error = xfs_blkdev_get(mp, args->rtname, &rtdev); | ||
457 | if (error) { | ||
458 | xfs_blkdev_put(logdev); | ||
459 | return error; | ||
460 | } | ||
461 | |||
462 | if (rtdev == ddev || rtdev == logdev) { | ||
463 | cmn_err(CE_WARN, | ||
464 | "XFS: Cannot mount filesystem with identical rtdev and ddev/logdev."); | ||
465 | xfs_blkdev_put(logdev); | ||
466 | xfs_blkdev_put(rtdev); | ||
467 | return EINVAL; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * Setup xfs_mount buffer target pointers | ||
473 | */ | ||
474 | error = ENOMEM; | ||
475 | mp->m_ddev_targp = xfs_alloc_buftarg(ddev, 0); | ||
476 | if (!mp->m_ddev_targp) { | ||
477 | xfs_blkdev_put(logdev); | ||
478 | xfs_blkdev_put(rtdev); | ||
479 | return error; | ||
480 | } | ||
481 | if (rtdev) { | ||
482 | mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1); | ||
483 | if (!mp->m_rtdev_targp) { | ||
484 | xfs_blkdev_put(logdev); | ||
485 | xfs_blkdev_put(rtdev); | ||
486 | goto error0; | ||
487 | } | ||
488 | } | ||
489 | mp->m_logdev_targp = (logdev && logdev != ddev) ? | ||
490 | xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp; | ||
491 | if (!mp->m_logdev_targp) { | ||
492 | xfs_blkdev_put(logdev); | ||
493 | xfs_blkdev_put(rtdev); | ||
494 | goto error0; | ||
495 | } | ||
496 | |||
497 | /* | ||
498 | * Setup flags based on mount(2) options and then the superblock | ||
499 | */ | ||
500 | error = xfs_start_flags(args, mp); | ||
501 | if (error) | ||
502 | goto error1; | ||
503 | error = xfs_readsb(mp, flags); | ||
504 | if (error) | ||
505 | goto error1; | ||
506 | error = xfs_finish_flags(args, mp); | ||
507 | if (error) | ||
508 | goto error2; | ||
509 | |||
510 | /* | ||
511 | * Setup xfs_mount buffer target pointers based on superblock | ||
512 | */ | ||
513 | error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, | ||
514 | mp->m_sb.sb_sectsize); | ||
515 | if (!error && logdev && logdev != ddev) { | ||
516 | unsigned int log_sector_size = BBSIZE; | ||
517 | |||
518 | if (xfs_sb_version_hassector(&mp->m_sb)) | ||
519 | log_sector_size = mp->m_sb.sb_logsectsize; | ||
520 | error = xfs_setsize_buftarg(mp->m_logdev_targp, | ||
521 | mp->m_sb.sb_blocksize, | ||
522 | log_sector_size); | ||
523 | } | ||
524 | if (!error && rtdev) | ||
525 | error = xfs_setsize_buftarg(mp->m_rtdev_targp, | ||
526 | mp->m_sb.sb_blocksize, | ||
527 | mp->m_sb.sb_sectsize); | ||
528 | if (error) | ||
529 | goto error2; | ||
530 | |||
531 | if (mp->m_flags & XFS_MOUNT_BARRIER) | ||
532 | xfs_mountfs_check_barriers(mp); | ||
533 | |||
534 | if ((error = xfs_filestream_mount(mp))) | ||
535 | goto error2; | ||
536 | |||
537 | error = xfs_mountfs(mp, flags); | ||
538 | if (error) | ||
539 | goto error2; | ||
540 | |||
541 | XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname); | ||
542 | |||
543 | return 0; | ||
544 | |||
545 | error2: | ||
546 | if (mp->m_sb_bp) | ||
547 | xfs_freesb(mp); | ||
548 | error1: | ||
549 | xfs_binval(mp->m_ddev_targp); | ||
550 | if (logdev && logdev != ddev) | ||
551 | xfs_binval(mp->m_logdev_targp); | ||
552 | if (rtdev) | ||
553 | xfs_binval(mp->m_rtdev_targp); | ||
554 | error0: | ||
555 | xfs_unmountfs_close(mp, credp); | ||
556 | xfs_qmops_put(mp); | ||
557 | xfs_dmops_put(mp); | ||
558 | return error; | ||
559 | } | ||
560 | |||
561 | STATIC void | 192 | STATIC void |
562 | xfs_quiesce_fs( | 193 | xfs_quiesce_fs( |
563 | xfs_mount_t *mp) | 194 | xfs_mount_t *mp) |