Commit 1c3d71d9 authored by Christoph Hellwig's avatar Christoph Hellwig

XFS: More mount cleanups

Modid: 2.5.x-xfs:slinx:128571a
parent 71660e15
...@@ -264,55 +264,6 @@ printk("XFS: osyncisdsync is now the default, and will soon be deprecated.\n"); ...@@ -264,55 +264,6 @@ printk("XFS: osyncisdsync is now the default, and will soon be deprecated.\n");
return 0; return 0;
} }
/*
* Convert one device special file to a dev_t.
* Helper routine, used only by spectodevs below.
*/
STATIC int
spectodev(
const char *name,
const char *id,
dev_t *dev)
{
struct nameidata nd;
int error;
error = path_lookup(name, LOOKUP_FOLLOW, &nd);
if (error)
return error;
*dev = kdev_t_to_nr(nd.dentry->d_inode->i_rdev);
path_release(&nd);
return 0;
}
/*
* Convert device special files to dev_t for data, log, realtime.
*/
int
spectodevs(
struct super_block *sb,
struct xfs_mount_args *args,
dev_t *ddevp,
dev_t *logdevp,
dev_t *rtdevp)
{
int rval = 0;
*ddevp = sb->s_dev;
if (args->logname[0])
rval = spectodev(args->logname, "log", logdevp);
else
*logdevp = sb->s_dev;
if (args->rtname[0] && !rval)
rval = spectodev(args->rtname, "realtime", rtdevp);
else
*rtdevp = 0;
return rval;
}
STATIC kmem_cache_t * linvfs_inode_cachep; STATIC kmem_cache_t * linvfs_inode_cachep;
......
...@@ -80,18 +80,8 @@ ...@@ -80,18 +80,8 @@
((s)->s_fs_info = vfsp) ((s)->s_fs_info = vfsp)
struct xfs_mount_args;
extern void extern void
linvfs_set_inode_ops( linvfs_set_inode_ops(
struct inode *inode); struct inode *inode);
extern int
spectodevs(
struct super_block *sb,
struct xfs_mount_args *args,
dev_t *ddevp,
dev_t *logdevp,
dev_t *rtdevp);
#endif /* __XFS_SUPER_H__ */ #endif /* __XFS_SUPER_H__ */
...@@ -145,7 +145,6 @@ typedef struct pb_target { ...@@ -145,7 +145,6 @@ typedef struct pb_target {
struct block_device *pbr_bdev; struct block_device *pbr_bdev;
struct address_space *pbr_mapping; struct address_space *pbr_mapping;
unsigned int pbr_blocksize; unsigned int pbr_blocksize;
unsigned int pbr_blocksize_bits;
} pb_target_t; } pb_target_t;
/* /*
...@@ -303,18 +302,6 @@ extern int pagebuf_lock_value( /* return count on lock */ ...@@ -303,18 +302,6 @@ extern int pagebuf_lock_value( /* return count on lock */
extern int pagebuf_lock( /* lock buffer */ extern int pagebuf_lock( /* lock buffer */
page_buf_t *); /* buffer to lock */ page_buf_t *); /* buffer to lock */
extern void pagebuf_lock_disable( /* disable buffer locking */
struct pb_target *, /* inode for buffers */
int); /* do blkdev_put? */
extern struct pb_target *pagebuf_lock_enable(
dev_t,
int); /* do blkdev_get? */
extern void pagebuf_target_blocksize(
pb_target_t *,
unsigned int); /* block size */
extern void pagebuf_target_clear(struct pb_target *); extern void pagebuf_target_clear(struct pb_target *);
extern void pagebuf_unlock( /* unlock buffer */ extern void pagebuf_unlock( /* unlock buffer */
......
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
* Portions Copyright (c) 2002 Christoph Hellwig. All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as * under the terms of version 2 of the GNU General Public License as
...@@ -58,10 +57,6 @@ ...@@ -58,10 +57,6 @@
#include "page_buf_internal.h" #include "page_buf_internal.h"
#ifndef EVMS_MAJOR
#define EVMS_MAJOR 117
#endif
/* /*
* pagebuf_cond_lock * pagebuf_cond_lock
* *
...@@ -126,82 +121,6 @@ pagebuf_lock( ...@@ -126,82 +121,6 @@ pagebuf_lock(
return 0; return 0;
} }
/*
* pagebuf_lock_disable
*
* pagebuf_lock_disable disables buffer object locking for an inode.
* remove_super() does a blkdev_put for us on the data device, hence
* the do_blkdev_put argument.
*/
void
pagebuf_lock_disable(
pb_target_t *target,
int do_blkdev_put)
{
pagebuf_delwri_flush(target, PBDF_WAIT, NULL);
if (do_blkdev_put)
blkdev_put(target->pbr_bdev, BDEV_FS);
kfree(target);
}
/*
* pagebuf_lock_enable
*
* get_sb_bdev() does a blkdev_get for us on the data device, hence
* the do_blkdev_get argument.
*/
pb_target_t *
pagebuf_lock_enable(
dev_t dev,
int do_blkdev_get)
{
struct block_device *bdev;
pb_target_t *target;
int error = -ENOMEM;
target = kmalloc(sizeof(pb_target_t), GFP_KERNEL);
if (unlikely(!target))
return ERR_PTR(error);
bdev = bdget(dev);
if (unlikely(!bdev))
goto fail;
if (do_blkdev_get) {
error = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_FS);
if (unlikely(error))
goto fail;
}
target->pbr_dev = dev;
target->pbr_bdev = bdev;
target->pbr_mapping = bdev->bd_inode->i_mapping;
pagebuf_target_blocksize(target, PAGE_CACHE_SIZE);
if ((MAJOR(dev) == MD_MAJOR) || (MAJOR(dev) == EVMS_MAJOR))
target->pbr_flags = PBR_ALIGNED_ONLY;
else if (MAJOR(dev) == LVM_BLK_MAJOR)
target->pbr_flags = PBR_SECTOR_ONLY;
else
target->pbr_flags = 0;
return target;
fail:
kfree(target);
return ERR_PTR(error);
}
void
pagebuf_target_blocksize(
pb_target_t *target,
unsigned int blocksize)
{
target->pbr_blocksize = blocksize;
target->pbr_blocksize_bits = ffs(blocksize) - 1;
}
void void
pagebuf_target_clear( pagebuf_target_clear(
pb_target_t *target) pb_target_t *target)
......
...@@ -31,6 +31,13 @@ ...@@ -31,6 +31,13 @@
*/ */
#include <xfs.h> #include <xfs.h>
#include <linux/major.h>
#include <linux/namei.h>
#include <linux/pagemap.h>
#ifndef EVMS_MAJOR
#define EVMS_MAJOR 117
#endif
STATIC void xfs_mount_reset_sbqflags(xfs_mount_t *); STATIC void xfs_mount_reset_sbqflags(xfs_mount_t *);
STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t); STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t);
...@@ -1149,15 +1156,17 @@ xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr) ...@@ -1149,15 +1156,17 @@ xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr)
int have_logdev = (mp->m_logdev_targp != mp->m_ddev_targp); int have_logdev = (mp->m_logdev_targp != mp->m_ddev_targp);
if (mp->m_ddev_targp) { if (mp->m_ddev_targp) {
pagebuf_lock_disable(mp->m_ddev_targp, 0); xfs_free_buftarg(mp->m_ddev_targp);
mp->m_ddev_targp = NULL; mp->m_ddev_targp = NULL;
} }
if (mp->m_rtdev_targp) { if (mp->m_rtdev_targp) {
pagebuf_lock_disable(mp->m_rtdev_targp, 1); xfs_blkdev_put(mp->m_rtdev_targp->pbr_bdev);
xfs_free_buftarg(mp->m_rtdev_targp);
mp->m_rtdev_targp = NULL; mp->m_rtdev_targp = NULL;
} }
if (mp->m_logdev_targp && have_logdev) { if (mp->m_logdev_targp && have_logdev) {
pagebuf_lock_disable(mp->m_logdev_targp, 1); xfs_blkdev_put(mp->m_logdev_targp->pbr_bdev);
xfs_free_buftarg(mp->m_logdev_targp);
mp->m_logdev_targp = NULL; mp->m_logdev_targp = NULL;
} }
} }
...@@ -1725,3 +1734,71 @@ xfs_check_frozen( ...@@ -1725,3 +1734,71 @@ xfs_check_frozen(
if (level == XFS_FREEZE_TRANS) if (level == XFS_FREEZE_TRANS)
atomic_inc(&mp->m_active_trans); atomic_inc(&mp->m_active_trans);
} }
int
xfs_blkdev_get(
const char *name,
struct block_device **bdevp)
{
struct nameidata nd;
int error = 0;
error = path_lookup(name, LOOKUP_FOLLOW, &nd);
if (error) {
printk("XFS: Invalid device [%s], error=%d\n",
name, error);
return error;
}
/* I think we actually want bd_acquire here.. --hch */
*bdevp = bdget(kdev_t_to_nr(nd.dentry->d_inode->i_rdev));
if (*bdevp) {
error = blkdev_get(*bdevp, FMODE_READ|FMODE_WRITE, 0, BDEV_FS);
} else {
error = -ENOMEM;
}
path_release(&nd);
return -error;
}
void
xfs_blkdev_put(
struct block_device *bdev)
{
blkdev_put(bdev, BDEV_FS);
}
void
xfs_free_buftarg(
xfs_buftarg_t *btp)
{
pagebuf_delwri_flush(btp, PBDF_WAIT, NULL);
kfree(btp);
}
xfs_buftarg_t *
xfs_alloc_buftarg(
struct block_device *bdev)
{
xfs_buftarg_t *btp;
btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
btp->pbr_dev = bdev->bd_dev;
btp->pbr_bdev = bdev;
btp->pbr_mapping = bdev->bd_inode->i_mapping;
btp->pbr_blocksize = PAGE_CACHE_SIZE;
switch (MAJOR(btp->pbr_dev)) {
case MD_MAJOR:
case EVMS_MAJOR:
btp->pbr_flags = PBR_ALIGNED_ONLY;
break;
case LVM_BLK_MAJOR:
btp->pbr_flags = PBR_SECTOR_ONLY;
break;
}
return btp;
}
...@@ -436,6 +436,11 @@ int xfs_syncsub(xfs_mount_t *, int, int, int *); ...@@ -436,6 +436,11 @@ int xfs_syncsub(xfs_mount_t *, int, int, int *);
void xfs_initialize_perag(xfs_mount_t *, int); void xfs_initialize_perag(xfs_mount_t *, int);
void xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t, __int64_t); void xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t, __int64_t);
int xfs_blkdev_get(const char *, struct block_device **);
void xfs_blkdev_put(struct block_device *);
struct xfs_buftarg *xfs_alloc_buftarg(struct block_device *);
void xfs_free_buftarg(struct xfs_buftarg *);
/* /*
* Flags for freeze operations. * Flags for freeze operations.
*/ */
......
...@@ -392,144 +392,114 @@ xfs_finish_flags( ...@@ -392,144 +392,114 @@ xfs_finish_flags(
} }
/* /*
* xfs_cmountfs * xfs_mount
*
* The file system configurations are:
* (1) device (partition) with data and internal log
* (2) logical volume with data and log subvolumes.
* (3) logical volume with data, log, and realtime subvolumes.
* *
* This function is the common mount file system function for XFS. * The Linux VFS took care of finding and opening the data volume for
* us. We have to handle the other two (if present) here.
*/ */
STATIC int STATIC int
xfs_cmountfs( xfs_mount(
vfs_t *vfsp, vfs_t *vfsp,
dev_t ddev, struct xfs_mount_args *args,
dev_t logdev, cred_t *credp)
dev_t rtdev,
struct xfs_mount_args *ap,
struct cred *cr)
{ {
xfs_mount_t *mp; xfs_mount_t *mp;
struct block_device *ddev, *logdev, *rtdev;
int ronly = (vfsp->vfs_flag & VFS_RDONLY); int ronly = (vfsp->vfs_flag & VFS_RDONLY);
int error = 0; int error = 0;
/* ddev = vfsp->vfs_super->s_bdev;
* Allocate VFS private data (xfs mount structure). logdev = rtdev = NULL;
*/
mp = xfs_mount_init();
vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
/* /*
* Open data, real time, and log devices now - order is important. * Open real time and log devices - order is important.
*/ */
mp->m_ddev_targp = pagebuf_lock_enable(ddev, 0); if (args->logname[0]) {
if (IS_ERR(mp->m_ddev_targp)) { error = xfs_blkdev_get(args->logname, &logdev);
error = PTR_ERR(mp->m_ddev_targp); if (error)
goto error2; return error;
} }
if (args->rtname[0]) {
if (rtdev != 0) { error = xfs_blkdev_get(args->rtname, &rtdev);
mp->m_rtdev_targp = pagebuf_lock_enable(rtdev, 1); if (error) {
if (IS_ERR(mp->m_rtdev_targp)) { xfs_blkdev_put(logdev);
error = PTR_ERR(mp->m_rtdev_targp); return error;
pagebuf_lock_disable(mp->m_ddev_targp, 0);
goto error2;
} }
if (rtdev == ddev || rtdev == logdev) { if (rtdev == ddev || rtdev == logdev) {
cmn_err(CE_WARN, cmn_err(CE_WARN,
"XFS: Cannot mount filesystem with identical rtdev and ddev/logdev."); "XFS: Cannot mount filesystem with identical rtdev and ddev/logdev.");
error = EINVAL; xfs_blkdev_put(logdev);
pagebuf_lock_disable(mp->m_ddev_targp, 0); xfs_blkdev_put(rtdev);
goto error2; return EINVAL;
} }
/* Set the realtime device's block size */
set_blocksize(mp->m_rtdev_targp->pbr_bdev, 512);
} }
if (logdev != ddev) { /*
mp->m_logdev_targp = pagebuf_lock_enable(logdev, 1); * Allocate VFS private data (xfs mount structure).
if (IS_ERR(mp->m_logdev_targp)) { */
error = PTR_ERR(mp->m_logdev_targp); mp = xfs_mount_init();
pagebuf_lock_disable(mp->m_ddev_targp, 1);
if (mp->m_rtdev_targp)
pagebuf_lock_disable(mp->m_rtdev_targp, 1);
goto error2;
}
/* Set the log device's block size */ vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
set_blocksize(mp->m_logdev_targp->pbr_bdev, 512);
mp->m_ddev_targp = xfs_alloc_buftarg(ddev);
if (rtdev != NULL) {
mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev);
set_blocksize(rtdev, 512);
}
if (logdev != NULL && logdev != ddev) {
mp->m_logdev_targp = xfs_alloc_buftarg(logdev);
set_blocksize(logdev, 512);
} else { } else {
mp->m_logdev_targp = mp->m_ddev_targp; mp->m_logdev_targp = mp->m_ddev_targp;
} }
if ((error = xfs_start_flags(ap, mp, ronly))) error = xfs_start_flags(args, mp, ronly);
goto error3; if (error)
goto error;
if ((error = xfs_readsb(mp))) error = xfs_readsb(mp);
goto error3; if (error)
goto error;
if ((error = xfs_finish_flags(ap, mp, ronly))) { error = xfs_finish_flags(args, mp, ronly);
if (error) {
xfs_freesb(mp); xfs_freesb(mp);
goto error3; goto error;
} }
pagebuf_target_blocksize(mp->m_ddev_targp, mp->m_sb.sb_blocksize); mp->m_ddev_targp->pbr_blocksize = mp->m_sb.sb_blocksize;
if (logdev != 0 && logdev != ddev) if (logdev != 0 && logdev != ddev) {
pagebuf_target_blocksize(mp->m_logdev_targp, mp->m_logdev_targp->pbr_blocksize = mp->m_sb.sb_blocksize;
mp->m_sb.sb_blocksize); }
if (rtdev != 0) if (rtdev != 0) {
pagebuf_target_blocksize(mp->m_rtdev_targp, mp->m_rtdev_targp->pbr_blocksize = mp->m_sb.sb_blocksize;
mp->m_sb.sb_blocksize); }
mp->m_cxfstype = XFS_CXFS_NOT; mp->m_cxfstype = XFS_CXFS_NOT;
error = xfs_mountfs(vfsp, mp, ddev, 0); error = xfs_mountfs(vfsp, mp, ddev->bd_dev, 0);
if (error) if (error)
goto error3; goto error;
return 0; return 0;
error3: error:
/* It's impossible to get here before buftargs are filled */
xfs_binval(mp->m_ddev_targp); xfs_binval(mp->m_ddev_targp);
pagebuf_lock_disable(mp->m_ddev_targp, 0); if (logdev != NULL && logdev != ddev) {
if (logdev && logdev != ddev) {
xfs_binval(mp->m_logdev_targp); xfs_binval(mp->m_logdev_targp);
pagebuf_lock_disable(mp->m_logdev_targp, 1);
} }
if (rtdev != 0) { if (rtdev != NULL) {
xfs_binval(mp->m_rtdev_targp); xfs_binval(mp->m_rtdev_targp);
pagebuf_lock_disable(mp->m_rtdev_targp, 1);
}
error2:
if (error) {
xfs_mount_free(mp, 1);
} }
xfs_unmountfs_close(mp, NULL);
xfs_mount_free(mp, 1);
return error; return error;
} }
/*
* xfs_mount
*
* The file system configurations are:
* (1) device (partition) with data and internal log
* (2) logical volume with data and log subvolumes.
* (3) logical volume with data, log, and realtime subvolumes.
*/
STATIC int
xfs_mount(
vfs_t *vfsp,
struct xfs_mount_args *args,
cred_t *credp)
{
dev_t ddev;
dev_t logdev;
dev_t rtdev;
int error;
error = spectodevs(vfsp->vfs_super, args, &ddev, &logdev, &rtdev);
if (!error)
error = xfs_cmountfs(vfsp, ddev, logdev, rtdev, args, credp);
return (error);
}
/* /*
* xfs_ibusy searches for a busy inode in the mounted file system. * xfs_ibusy searches for a busy inode in the mounted file system.
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment