Commit 2c4d3eb6 authored by Christoph Hellwig's avatar Christoph Hellwig

Merge hera.kernel.org:/home/torvalds/BK/linux-2.5

into hera.kernel.org:/home/hch/BK/xfs/linux-2.5
parents bda0e956 8c88cd21
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/mpage.h> #include <linux/mpage.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/uio.h> #include <linux/uio.h>
#include <linux/namei.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -796,3 +797,82 @@ const char *__bdevname(dev_t dev) ...@@ -796,3 +797,82 @@ const char *__bdevname(dev_t dev)
sprintf(buffer, "%s(%d,%d)", name, MAJOR(dev), MINOR(dev)); sprintf(buffer, "%s(%d,%d)", name, MAJOR(dev), MINOR(dev));
return buffer; return buffer;
} }
/**
* open_bdev_excl - open a block device by name and set it up for use
*
* @path: special file representing the block device
* @flags: %MS_RDONLY for opening read-only
* @kind: usage (same as the 4th paramter to blkdev_get)
* @holder: owner for exclusion
*
* Open the blockdevice described by the special file at @path, claim it
* for the @holder and properly set it up for @kind usage.
*/
struct block_device *open_bdev_excl(const char *path, int flags,
int kind, void *holder)
{
struct inode *inode;
struct block_device *bdev;
struct nameidata nd;
mode_t mode = FMODE_READ;
int error = 0;
if (!path || !*path)
return ERR_PTR(-EINVAL);
error = path_lookup(path, LOOKUP_FOLLOW, &nd);
if (error)
return ERR_PTR(error);
inode = nd.dentry->d_inode;
error = -ENOTBLK;
if (!S_ISBLK(inode->i_mode))
goto path_release;
error = -EACCES;
if (nd.mnt->mnt_flags & MNT_NODEV)
goto path_release;
error = bd_acquire(inode);
if (error)
goto path_release;
bdev = inode->i_bdev;
/* Done with lookups */
path_release(&nd);
if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE;
error = blkdev_get(bdev, mode, 0, kind);
if (error)
return ERR_PTR(error);
error = -EACCES;
if (!(flags & MS_RDONLY) && bdev_read_only(bdev))
goto blkdev_put;
error = bd_claim(bdev, holder);
if (error)
goto blkdev_put;
return bdev;
blkdev_put:
blkdev_put(bdev, BDEV_FS);
return ERR_PTR(error);
path_release:
path_release(&nd);
return ERR_PTR(error);
}
/**
* close_bdev_excl - release a blockdevice openen by open_bdev_excl()
*
* @bdev: blockdevice to close
* @kind: usage (same as the 4th paramter to blkdev_get)
*
* This is the counterpart to open_bdev_excl().
*/
void close_bdev_excl(struct block_device *bdev, int kind)
{
bd_release(bdev);
blkdev_put(bdev, kind);
}
...@@ -505,55 +505,25 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type, ...@@ -505,55 +505,25 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
int flags, char *dev_name, void * data, int flags, char *dev_name, void * data,
int (*fill_super)(struct super_block *, void *, int)) int (*fill_super)(struct super_block *, void *, int))
{ {
struct inode *inode;
struct block_device *bdev; struct block_device *bdev;
struct super_block * s; struct super_block *s;
struct nameidata nd;
int error = 0; int error = 0;
mode_t mode = FMODE_READ; /* we always need it ;-) */
/* What device it is? */ bdev = open_bdev_excl(dev_name, flags, BDEV_FS, fs_type);
if (!dev_name || !*dev_name) if (IS_ERR(bdev))
return ERR_PTR(-EINVAL); return (struct super_block *)bdev;
error = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
if (error)
return ERR_PTR(error);
inode = nd.dentry->d_inode;
error = -ENOTBLK;
if (!S_ISBLK(inode->i_mode))
goto out;
error = -EACCES;
if (nd.mnt->mnt_flags & MNT_NODEV)
goto out;
error = bd_acquire(inode);
if (error)
goto out;
bdev = inode->i_bdev;
/* Done with lookups, semaphore down */
if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE;
error = blkdev_get(bdev, mode, 0, BDEV_FS);
if (error)
goto out;
error = -EACCES;
if (!(flags & MS_RDONLY) && bdev_read_only(bdev))
goto out1;
error = bd_claim(bdev, fs_type);
if (error)
goto out1;
s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
if (IS_ERR(s)) { if (IS_ERR(s))
bd_release(bdev); goto out;
blkdev_put(bdev, BDEV_FS);
} else if (s->s_root) { if (s->s_root) {
if ((flags ^ s->s_flags) & MS_RDONLY) { if ((flags ^ s->s_flags) & MS_RDONLY) {
up_write(&s->s_umount); up_write(&s->s_umount);
deactivate_super(s); deactivate_super(s);
s = ERR_PTR(-EBUSY); s = ERR_PTR(-EBUSY);
} }
bd_release(bdev); goto out;
blkdev_put(bdev, BDEV_FS);
} else { } else {
s->s_flags = flags; s->s_flags = flags;
strncpy(s->s_id, bdevname(bdev), sizeof(s->s_id)); strncpy(s->s_id, bdevname(bdev), sizeof(s->s_id));
...@@ -567,14 +537,12 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type, ...@@ -567,14 +537,12 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
} else } else
s->s_flags |= MS_ACTIVE; s->s_flags |= MS_ACTIVE;
} }
path_release(&nd);
return s; return s;
out1:
blkdev_put(bdev, BDEV_FS);
out: out:
path_release(&nd); close_bdev_excl(bdev, BDEV_FS);
return ERR_PTR(error); return s;
} }
void kill_block_super(struct super_block *sb) void kill_block_super(struct super_block *sb)
...@@ -582,8 +550,7 @@ void kill_block_super(struct super_block *sb) ...@@ -582,8 +550,7 @@ void kill_block_super(struct super_block *sb)
struct block_device *bdev = sb->s_bdev; struct block_device *bdev = sb->s_bdev;
generic_shutdown_super(sb); generic_shutdown_super(sb);
set_blocksize(bdev, sb->s_old_blocksize); set_blocksize(bdev, sb->s_old_blocksize);
bd_release(bdev); close_bdev_excl(bdev, BDEV_FS);
blkdev_put(bdev, BDEV_FS);
} }
struct super_block *get_sb_nodev(struct file_system_type *fs_type, struct super_block *get_sb_nodev(struct file_system_type *fs_type,
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/root_dev.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/div64.h> #include <asm/div64.h>
......
...@@ -215,54 +215,46 @@ xfs_sendfile( ...@@ -215,54 +215,46 @@ xfs_sendfile(
void *target, void *target,
cred_t *credp) cred_t *credp)
{ {
size_t size = 0;
ssize_t ret; ssize_t ret;
xfs_fsize_t n; xfs_fsize_t n;
xfs_inode_t *ip; xfs_inode_t *ip;
xfs_mount_t *mp;
vnode_t *vp; vnode_t *vp;
int invisible = (filp->f_mode & FINVIS);
ip = XFS_BHVTOI(bdp); ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp); vp = BHV_TO_VNODE(bdp);
mp = ip->i_mount;
vn_trace_entry(vp, "xfs_sendfile", (inst_t *)__return_address); vn_trace_entry(vp, "xfs_sendfile", (inst_t *)__return_address);
XFS_STATS_INC(xfsstats.xs_read_calls); XFS_STATS_INC(xfsstats.xs_read_calls);
n = XFS_MAX_FILE_OFFSET - *offp; n = XFS_MAX_FILE_OFFSET - *offp;
if ((n <= 0) || (size == 0)) if ((n <= 0) || (count == 0))
return 0; return 0;
if (n < size) if (n < count)
size = n; count = n;
if (XFS_FORCED_SHUTDOWN(mp)) { if (XFS_FORCED_SHUTDOWN(ip->i_mount))
return -EIO; return -EIO;
}
xfs_ilock(ip, XFS_IOLOCK_SHARED); xfs_ilock(ip, XFS_IOLOCK_SHARED);
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && !invisible) {
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
!(filp->f_mode & FINVIS)) {
int error;
vrwlock_t locktype = VRWLOCK_READ; vrwlock_t locktype = VRWLOCK_READ;
int error;
error = xfs_dm_send_data_event(DM_EVENT_READ, bdp, *offp, error = xfs_dm_send_data_event(DM_EVENT_READ, bdp, *offp,
size, FILP_DELAY_FLAG(filp), &locktype); count, FILP_DELAY_FLAG(filp), &locktype);
if (error) { if (error) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED); xfs_iunlock(ip, XFS_IOLOCK_SHARED);
return -error; return -error;
} }
} }
ret = generic_file_sendfile(filp, offp, count, actor, target); ret = generic_file_sendfile(filp, offp, count, actor, target);
xfs_iunlock(ip, XFS_IOLOCK_SHARED); xfs_iunlock(ip, XFS_IOLOCK_SHARED);
XFS_STATS_ADD(xfsstats.xs_read_bytes, ret); XFS_STATS_ADD(xfsstats.xs_read_bytes, ret);
if (!invisible)
if (!(filp->f_mode & FINVIS))
xfs_ichgtime(ip, XFS_ICHGTIME_ACC); xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
return ret; return ret;
} }
......
...@@ -58,6 +58,9 @@ extern ssize_t xfs_read (struct bhv_desc *, struct file *, ...@@ -58,6 +58,9 @@ extern ssize_t xfs_read (struct bhv_desc *, struct file *,
extern ssize_t xfs_write (struct bhv_desc *, struct file *, extern ssize_t xfs_write (struct bhv_desc *, struct file *,
const struct iovec *, unsigned long, const struct iovec *, unsigned long,
loff_t *, struct cred *); loff_t *, struct cred *);
extern ssize_t xfs_sendfile (struct bhv_desc *, struct file *,
loff_t *, size_t, read_actor_t,
void *, struct cred *);
extern int xfs_dev_is_read_only (struct xfs_mount *, char *); extern int xfs_dev_is_read_only (struct xfs_mount *, char *);
......
...@@ -468,27 +468,18 @@ xfs_initialize_vnode( ...@@ -468,27 +468,18 @@ xfs_initialize_vnode(
int int
xfs_blkdev_get( xfs_blkdev_get(
xfs_mount_t *mp,
const char *name, const char *name,
struct block_device **bdevp) struct block_device **bdevp)
{ {
struct nameidata nd; int error = 0;
int error;
error = path_lookup(name, LOOKUP_FOLLOW, &nd); *bdevp = open_bdev_excl(name, 0, BDEV_FS, mp);
if (error) { if (IS_ERR(*bdevp)) {
error = PTR_ERR(*bdevp);
printk("XFS: Invalid device [%s], error=%d\n", name, 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; return -error;
} }
...@@ -497,7 +488,7 @@ xfs_blkdev_put( ...@@ -497,7 +488,7 @@ xfs_blkdev_put(
struct block_device *bdev) struct block_device *bdev)
{ {
if (bdev) if (bdev)
blkdev_put(bdev, BDEV_FS); close_bdev_excl(bdev, BDEV_FS);
} }
void void
...@@ -761,17 +752,6 @@ linvfs_clear_inode( ...@@ -761,17 +752,6 @@ linvfs_clear_inode(
} }
} }
STATIC void
linvfs_put_inode(
struct inode *ip)
{
vnode_t *vp = LINVFS_GET_VP(ip);
int error;
if (vp && vp->v_fbhv && (atomic_read(&ip->i_count) == 1))
VOP_RELEASE(vp, error);
}
STATIC void STATIC void
linvfs_put_super( linvfs_put_super(
struct super_block *sb) struct super_block *sb)
...@@ -989,7 +969,6 @@ STATIC struct super_operations linvfs_sops = { ...@@ -989,7 +969,6 @@ STATIC struct super_operations linvfs_sops = {
.alloc_inode = linvfs_alloc_inode, .alloc_inode = linvfs_alloc_inode,
.destroy_inode = linvfs_destroy_inode, .destroy_inode = linvfs_destroy_inode,
.write_inode = linvfs_write_inode, .write_inode = linvfs_write_inode,
.put_inode = linvfs_put_inode,
.clear_inode = linvfs_clear_inode, .clear_inode = linvfs_clear_inode,
.put_super = linvfs_put_super, .put_super = linvfs_put_super,
.write_super = linvfs_write_super, .write_super = linvfs_write_super,
......
...@@ -78,12 +78,14 @@ ...@@ -78,12 +78,14 @@
#define LINVFS_SET_VFS(s, vfsp) \ #define LINVFS_SET_VFS(s, vfsp) \
((s)->s_fs_info = vfsp) ((s)->s_fs_info = vfsp)
struct xfs_mount;
struct pb_target; struct pb_target;
struct block_device; struct block_device;
extern void xfs_initialize_vnode (bhv_desc_t *, vnode_t *, bhv_desc_t *, int); extern void xfs_initialize_vnode (bhv_desc_t *, vnode_t *, bhv_desc_t *, int);
extern int xfs_blkdev_get (const char *, struct block_device **); extern int xfs_blkdev_get (struct xfs_mount *, const char *,
struct block_device **);
extern void xfs_blkdev_put (struct block_device *); extern void xfs_blkdev_put (struct block_device *);
extern struct pb_target *xfs_alloc_buftarg (struct block_device *); extern struct pb_target *xfs_alloc_buftarg (struct block_device *);
......
This diff is collapsed.
...@@ -109,7 +109,6 @@ typedef enum page_buf_flags_e { /* pb_flags values */ ...@@ -109,7 +109,6 @@ typedef enum page_buf_flags_e { /* pb_flags values */
/* flags used only internally */ /* flags used only internally */
_PBF_LOCKABLE = (1 << 19), /* page_buf_t may be locked */ _PBF_LOCKABLE = (1 << 19), /* page_buf_t may be locked */
_PBF_PRIVATE_BH = (1 << 20), /* do not use public buffer heads */
_PBF_ALL_PAGES_MAPPED = (1 << 21), _PBF_ALL_PAGES_MAPPED = (1 << 21),
/* all pages in rage are mapped */ /* all pages in rage are mapped */
_PBF_ADDR_ALLOCATED = (1 << 22), _PBF_ADDR_ALLOCATED = (1 << 22),
...@@ -195,6 +194,10 @@ typedef int (*page_buf_bdstrat_t)(struct page_buf_s *); ...@@ -195,6 +194,10 @@ typedef int (*page_buf_bdstrat_t)(struct page_buf_s *);
#define PB_PAGES 4 #define PB_PAGES 4
typedef struct page_buf_s { typedef struct page_buf_s {
struct semaphore pb_sema; /* semaphore for lockables */
unsigned long pb_flushtime; /* time to flush pagebuf */
atomic_t pb_pin_count; /* pin count */
wait_queue_head_t pb_waiters; /* unpin waiters */
struct list_head pb_list; struct list_head pb_list;
page_buf_flags_t pb_flags; /* status flags */ page_buf_flags_t pb_flags; /* status flags */
struct list_head pb_hash_list; struct list_head pb_hash_list;
...@@ -221,6 +224,9 @@ typedef struct page_buf_s { ...@@ -221,6 +224,9 @@ typedef struct page_buf_s {
unsigned char pb_hash_index; /* hash table index */ unsigned char pb_hash_index; /* hash table index */
struct page **pb_pages; /* array of page pointers */ struct page **pb_pages; /* array of page pointers */
struct page *pb_page_array[PB_PAGES]; /* inline pages */ struct page *pb_page_array[PB_PAGES]; /* inline pages */
#ifdef PAGEBUF_LOCK_TRACKING
int pb_last_holder;
#endif
} page_buf_t; } page_buf_t;
...@@ -244,14 +250,6 @@ extern page_buf_t *pagebuf_get( /* allocate a buffer */ ...@@ -244,14 +250,6 @@ extern page_buf_t *pagebuf_get( /* allocate a buffer */
page_buf_flags_t); /* PBF_LOCK, PBF_READ, */ page_buf_flags_t); /* PBF_LOCK, PBF_READ, */
/* PBF_ASYNC */ /* PBF_ASYNC */
extern page_buf_t *pagebuf_lookup(
struct pb_target *,
struct inode *,
loff_t, /* starting offset of range */
size_t, /* length of range */
page_buf_flags_t); /* PBF_READ, PBF_WRITE, */
/* PBF_FORCEIO, _PBF_LOCKABLE */
extern page_buf_t *pagebuf_get_empty( /* allocate pagebuf struct with */ extern page_buf_t *pagebuf_get_empty( /* allocate pagebuf struct with */
/* no memory or disk address */ /* no memory or disk address */
struct pb_target *); /* mount point "fake" inode */ struct pb_target *); /* mount point "fake" inode */
...@@ -340,7 +338,7 @@ extern caddr_t pagebuf_offset(page_buf_t *, off_t); ...@@ -340,7 +338,7 @@ extern caddr_t pagebuf_offset(page_buf_t *, off_t);
extern void pagebuf_iomove( /* move data in/out of pagebuf */ extern void pagebuf_iomove( /* move data in/out of pagebuf */
page_buf_t *, /* buffer to manipulate */ page_buf_t *, /* buffer to manipulate */
off_t, /* starting buffer offset */ size_t, /* starting buffer offset */
size_t, /* length in buffer */ size_t, /* length in buffer */
caddr_t, /* data pointer */ caddr_t, /* data pointer */
page_buf_rw_t); /* direction */ page_buf_rw_t); /* direction */
......
...@@ -48,24 +48,10 @@ ...@@ -48,24 +48,10 @@
#define page_has_buffers(page) ((page)->buffers) #define page_has_buffers(page) ((page)->buffers)
#endif #endif
typedef struct page_buf_private_s {
page_buf_t pb_common; /* public part of structure */
struct semaphore pb_sema; /* semaphore for lockables */
unsigned long pb_flushtime; /* time to flush pagebuf */
atomic_t pb_pin_count; /* pin count */
wait_queue_head_t pb_waiters; /* unpin waiters */
#ifdef PAGEBUF_LOCK_TRACKING #ifdef PAGEBUF_LOCK_TRACKING
int pb_last_holder; #define PB_SET_OWNER(pb) (pb->pb_last_holder = current->pid)
#endif #define PB_CLEAR_OWNER(pb) (pb->pb_last_holder = -1)
} page_buf_private_t; #define PB_GET_OWNER(pb) (pb->pb_last_holder)
#define PBC(pb) (&((pb)->pb_common))
#define PBP(pb) ((page_buf_private_t *) (pb))
#ifdef PAGEBUF_LOCK_TRACKING
#define PB_SET_OWNER(pb) (PBP(pb)->pb_last_holder = current->pid)
#define PB_CLEAR_OWNER(pb) (PBP(pb)->pb_last_holder = -1)
#define PB_GET_OWNER(pb) (PBP(pb)->pb_last_holder)
#else #else
#define PB_SET_OWNER(pb) #define PB_SET_OWNER(pb)
#define PB_CLEAR_OWNER(pb) #define PB_CLEAR_OWNER(pb)
...@@ -95,12 +81,6 @@ struct pagebuf_trace_buf { ...@@ -95,12 +81,6 @@ struct pagebuf_trace_buf {
#define PB_TRACE_BUFSIZE 1024 #define PB_TRACE_BUFSIZE 1024
#define CIRC_INC(i) (((i) + 1) & (PB_TRACE_BUFSIZE - 1)) #define CIRC_INC(i) (((i) + 1) & (PB_TRACE_BUFSIZE - 1))
typedef struct pagebuf_daemon {
int active;
spinlock_t pb_delwrite_lock;
struct list_head pb_delwrite_l;
} pagebuf_daemon_t;
/* /*
* Tunable pagebuf parameters * Tunable pagebuf parameters
*/ */
......
...@@ -75,7 +75,7 @@ pagebuf_cond_lock( /* lock buffer, if not locked */ ...@@ -75,7 +75,7 @@ pagebuf_cond_lock( /* lock buffer, if not locked */
ASSERT(pb->pb_flags & _PBF_LOCKABLE); ASSERT(pb->pb_flags & _PBF_LOCKABLE);
locked = down_trylock(&PBP(pb)->pb_sema) == 0; locked = down_trylock(&pb->pb_sema) == 0;
if (locked) { if (locked) {
PB_SET_OWNER(pb); PB_SET_OWNER(pb);
} }
...@@ -95,7 +95,7 @@ pagebuf_lock_value( ...@@ -95,7 +95,7 @@ pagebuf_lock_value(
page_buf_t *pb) page_buf_t *pb)
{ {
ASSERT(pb->pb_flags & _PBF_LOCKABLE); ASSERT(pb->pb_flags & _PBF_LOCKABLE);
return(atomic_read(&PBP(pb)->pb_sema.count)); return(atomic_read(&pb->pb_sema.count));
} }
/* /*
...@@ -114,7 +114,7 @@ pagebuf_lock( ...@@ -114,7 +114,7 @@ pagebuf_lock(
PB_TRACE(pb, PB_TRACE_REC(lock), 0); PB_TRACE(pb, PB_TRACE_REC(lock), 0);
pagebuf_run_queues(pb); pagebuf_run_queues(pb);
down(&PBP(pb)->pb_sema); down(&pb->pb_sema);
PB_SET_OWNER(pb); PB_SET_OWNER(pb);
PB_TRACE(pb, PB_TRACE_REC(locked), 0); PB_TRACE(pb, PB_TRACE_REC(locked), 0);
return 0; return 0;
...@@ -133,6 +133,6 @@ pagebuf_unlock( /* unlock buffer */ ...@@ -133,6 +133,6 @@ pagebuf_unlock( /* unlock buffer */
{ {
ASSERT(pb->pb_flags & _PBF_LOCKABLE); ASSERT(pb->pb_flags & _PBF_LOCKABLE);
PB_CLEAR_OWNER(pb); PB_CLEAR_OWNER(pb);
up(&PBP(pb)->pb_sema); up(&pb->pb_sema);
PB_TRACE(pb, PB_TRACE_REC(unlock), 0); PB_TRACE(pb, PB_TRACE_REC(unlock), 0);
} }
...@@ -428,11 +428,6 @@ int xfs_syncsub(xfs_mount_t *, int, int, int *); ...@@ -428,11 +428,6 @@ 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.
*/ */
......
...@@ -381,8 +381,9 @@ xfs_finish_flags( ...@@ -381,8 +381,9 @@ xfs_finish_flags(
* (2) logical volume with data and log subvolumes. * (2) logical volume with data and log subvolumes.
* (3) logical volume with data, log, and realtime subvolumes. * (3) logical volume with data, log, and realtime subvolumes.
* *
* The Linux VFS took care of finding and opening the data volume for * We only have to handle opening the log and realtime volumes here if
* us. We have to handle the other two (if present) here. * they are present. The data subvolume has already been opened by
* get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev.
*/ */
STATIC int STATIC int
xfs_mount( xfs_mount(
...@@ -398,19 +399,24 @@ xfs_mount( ...@@ -398,19 +399,24 @@ xfs_mount(
ddev = vfsp->vfs_super->s_bdev; ddev = vfsp->vfs_super->s_bdev;
logdev = rtdev = NULL; logdev = rtdev = NULL;
/*
* Allocate VFS private data (xfs mount structure).
*/
mp = xfs_mount_init();
/* /*
* Open real time and log devices - order is important. * Open real time and log devices - order is important.
*/ */
if (args->logname[0]) { if (args->logname[0]) {
error = xfs_blkdev_get(args->logname, &logdev); error = xfs_blkdev_get(mp, args->logname, &logdev);
if (error) if (error)
return error; goto free_mp;
} }
if (args->rtname[0]) { if (args->rtname[0]) {
error = xfs_blkdev_get(args->rtname, &rtdev); error = xfs_blkdev_get(mp, args->rtname, &rtdev);
if (error) { if (error) {
xfs_blkdev_put(logdev); xfs_blkdev_put(logdev);
return error; goto free_mp;
} }
if (rtdev == ddev || rtdev == logdev) { if (rtdev == ddev || rtdev == logdev) {
...@@ -418,15 +424,11 @@ xfs_mount( ...@@ -418,15 +424,11 @@ xfs_mount(
"XFS: Cannot mount filesystem with identical rtdev and ddev/logdev."); "XFS: Cannot mount filesystem with identical rtdev and ddev/logdev.");
xfs_blkdev_put(logdev); xfs_blkdev_put(logdev);
xfs_blkdev_put(rtdev); xfs_blkdev_put(rtdev);
return EINVAL; error = EINVAL;
goto free_mp;
} }
} }
/*
* Allocate VFS private data (xfs mount structure).
*/
mp = xfs_mount_init();
vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp); vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
mp->m_ddev_targp = xfs_alloc_buftarg(ddev); mp->m_ddev_targp = xfs_alloc_buftarg(ddev);
...@@ -459,7 +461,7 @@ xfs_mount( ...@@ -459,7 +461,7 @@ xfs_mount(
xfs_size_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize, ss); xfs_size_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize, ss);
} }
if (rtdev) if (rtdev)
xfs_size_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize, xfs_size_buftarg(mp->m_rtdev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_blocksize); mp->m_sb.sb_blocksize);
error = xfs_mountfs(vfsp, mp, ddev->bd_dev, flags); error = xfs_mountfs(vfsp, mp, ddev->bd_dev, flags);
...@@ -476,6 +478,8 @@ xfs_mount( ...@@ -476,6 +478,8 @@ xfs_mount(
xfs_binval(mp->m_rtdev_targp); xfs_binval(mp->m_rtdev_targp);
} }
xfs_unmountfs_close(mp, NULL); xfs_unmountfs_close(mp, NULL);
free_mp:
xfs_mount_free(mp, 1); xfs_mount_free(mp, 1);
return error; return error;
} }
......
...@@ -4870,6 +4870,7 @@ vnodeops_t xfs_vnodeops = { ...@@ -4870,6 +4870,7 @@ vnodeops_t xfs_vnodeops = {
BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS),
.vop_open = xfs_open, .vop_open = xfs_open,
.vop_read = xfs_read, .vop_read = xfs_read,
.vop_sendfile = xfs_sendfile,
.vop_write = xfs_write, .vop_write = xfs_write,
.vop_ioctl = xfs_ioctl, .vop_ioctl = xfs_ioctl,
.vop_getattr = xfs_getattr, .vop_getattr = xfs_getattr,
......
...@@ -1793,7 +1793,7 @@ kdbm_pb_flags(int argc, const char **argv, const char **envp, struct pt_regs *re ...@@ -1793,7 +1793,7 @@ kdbm_pb_flags(int argc, const char **argv, const char **envp, struct pt_regs *re
static int static int
kdbm_pb(int argc, const char **argv, const char **envp, struct pt_regs *regs) kdbm_pb(int argc, const char **argv, const char **envp, struct pt_regs *regs)
{ {
page_buf_private_t bp; page_buf_t bp;
unsigned long addr; unsigned long addr;
long offset=0; long offset=0;
int nextarg; int nextarg;
...@@ -1808,43 +1808,43 @@ kdbm_pb(int argc, const char **argv, const char **envp, struct pt_regs *regs) ...@@ -1808,43 +1808,43 @@ kdbm_pb(int argc, const char **argv, const char **envp, struct pt_regs *regs)
return diag; return diag;
kdb_printf("page_buf_t at 0x%lx\n", addr); kdb_printf("page_buf_t at 0x%lx\n", addr);
kdb_printf(" pb_flags %s\n", pb_flags(bp.pb_common.pb_flags)); kdb_printf(" pb_flags %s\n", pb_flags(bp.pb_flags));
kdb_printf(" pb_target 0x%p pb_hold %d pb_next 0x%p pb_prev 0x%p\n", kdb_printf(" pb_target 0x%p pb_hold %d pb_next 0x%p pb_prev 0x%p\n",
bp.pb_common.pb_target, bp.pb_common.pb_hold.counter, bp.pb_target, bp.pb_hold.counter,
bp.pb_common.pb_list.next, bp.pb_common.pb_list.prev); bp.pb_list.next, bp.pb_list.prev);
kdb_printf(" pb_hash_index %d pb_hash_next 0x%p pb_hash_prev 0x%p\n", kdb_printf(" pb_hash_index %d pb_hash_next 0x%p pb_hash_prev 0x%p\n",
bp.pb_common.pb_hash_index, bp.pb_hash_index,
bp.pb_common.pb_hash_list.next, bp.pb_hash_list.next,
bp.pb_common.pb_hash_list.prev); bp.pb_hash_list.prev);
kdb_printf(" pb_file_offset 0x%llx pb_buffer_length 0x%llx pb_addr 0x%p\n", kdb_printf(" pb_file_offset 0x%llx pb_buffer_length 0x%llx pb_addr 0x%p\n",
(unsigned long long) bp.pb_common.pb_file_offset, (unsigned long long) bp.pb_file_offset,
(unsigned long long) bp.pb_common.pb_buffer_length, (unsigned long long) bp.pb_buffer_length,
bp.pb_common.pb_addr); bp.pb_addr);
kdb_printf(" pb_bn 0x%Lx pb_count_desired 0x%lx\n", kdb_printf(" pb_bn 0x%Lx pb_count_desired 0x%lx\n",
bp.pb_common.pb_bn, bp.pb_bn,
(unsigned long) bp.pb_common.pb_count_desired); (unsigned long) bp.pb_count_desired);
kdb_printf(" pb_io_remaining %d pb_error %u\n", kdb_printf(" pb_io_remaining %d pb_error %u\n",
bp.pb_common.pb_io_remaining.counter, bp.pb_io_remaining.counter,
bp.pb_common.pb_error); bp.pb_error);
kdb_printf(" pb_page_count %u pb_offset 0x%x pb_pages 0x%p\n", kdb_printf(" pb_page_count %u pb_offset 0x%x pb_pages 0x%p\n",
bp.pb_common.pb_page_count, bp.pb_common.pb_offset, bp.pb_page_count, bp.pb_offset,
bp.pb_common.pb_pages); bp.pb_pages);
#ifdef PAGEBUF_LOCK_TRACKING #ifdef PAGEBUF_LOCK_TRACKING
kdb_printf(" pb_iodonesema (%d,%d) pb_sema (%d,%d) pincount (%d) last holder %d\n", kdb_printf(" pb_iodonesema (%d,%d) pb_sema (%d,%d) pincount (%d) last holder %d\n",
bp.pb_common.pb_iodonesema.count.counter, bp.pb_iodonesema.count.counter,
bp.pb_common.pb_iodonesema.sleepers, bp.pb_iodonesema.sleepers,
bp.pb_sema.count.counter, bp.pb_sema.sleepers, bp.pb_sema.count.counter, bp.pb_sema.sleepers,
bp.pb_pin_count.counter, bp.pb_last_holder); bp.pb_pin_count.counter, bp.pb_last_holder);
#else #else
kdb_printf(" pb_iodonesema (%d,%d) pb_sema (%d,%d) pincount (%d)\n", kdb_printf(" pb_iodonesema (%d,%d) pb_sema (%d,%d) pincount (%d)\n",
bp.pb_common.pb_iodonesema.count.counter, bp.pb_iodonesema.count.counter,
bp.pb_common.pb_iodonesema.sleepers, bp.pb_iodonesema.sleepers,
bp.pb_sema.count.counter, bp.pb_sema.sleepers, bp.pb_sema.count.counter, bp.pb_sema.sleepers,
bp.pb_pin_count.counter); bp.pb_pin_count.counter);
#endif #endif
if (bp.pb_common.pb_fspriv || bp.pb_common.pb_fspriv2) { if (bp.pb_fspriv || bp.pb_fspriv2) {
kdb_printf( "pb_fspriv 0x%p pb_fspriv2 0x%p\n", kdb_printf( "pb_fspriv 0x%p pb_fspriv2 0x%p\n",
bp.pb_common.pb_fspriv, bp.pb_common.pb_fspriv2); bp.pb_fspriv, bp.pb_fspriv2);
} }
return 0; return 0;
......
...@@ -1098,15 +1098,20 @@ extern int bd_claim(struct block_device *, void *); ...@@ -1098,15 +1098,20 @@ extern int bd_claim(struct block_device *, void *);
extern void bd_release(struct block_device *); extern void bd_release(struct block_device *);
extern void blk_run_queues(void); extern void blk_run_queues(void);
/* fs/devices.c */ /* fs/char_dev.c */
extern int register_chrdev(unsigned int, const char *, struct file_operations *); extern int register_chrdev(unsigned int, const char *, struct file_operations *);
extern int unregister_chrdev(unsigned int, const char *); extern int unregister_chrdev(unsigned int, const char *);
extern int chrdev_open(struct inode *, struct file *); extern int chrdev_open(struct inode *, struct file *);
/* fs/block_dev.c */
extern const char *__bdevname(dev_t); extern const char *__bdevname(dev_t);
extern inline const char *bdevname(struct block_device *bdev) extern inline const char *bdevname(struct block_device *bdev)
{ {
return __bdevname(bdev->bd_dev); return __bdevname(bdev->bd_dev);
} }
extern struct block_device *open_bdev_excl(const char *, int, int, void *);
extern void close_bdev_excl(struct block_device *, int);
extern const char * cdevname(kdev_t); extern const char * cdevname(kdev_t);
extern const char * kdevname(kdev_t); extern const char * kdevname(kdev_t);
extern void init_special_inode(struct inode *, umode_t, dev_t); extern void init_special_inode(struct inode *, umode_t, dev_t);
......
...@@ -203,6 +203,8 @@ EXPORT_SYMBOL(bdget); ...@@ -203,6 +203,8 @@ EXPORT_SYMBOL(bdget);
EXPORT_SYMBOL(bdput); EXPORT_SYMBOL(bdput);
EXPORT_SYMBOL(bd_claim); EXPORT_SYMBOL(bd_claim);
EXPORT_SYMBOL(bd_release); EXPORT_SYMBOL(bd_release);
EXPORT_SYMBOL(open_bdev_excl);
EXPORT_SYMBOL(close_bdev_excl);
EXPORT_SYMBOL(__brelse); EXPORT_SYMBOL(__brelse);
EXPORT_SYMBOL(__bforget); EXPORT_SYMBOL(__bforget);
EXPORT_SYMBOL(ll_rw_block); EXPORT_SYMBOL(ll_rw_block);
......
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