Commit 9589ef2a authored by Nathan Scott's avatar Nathan Scott

[XFS] Next step in bhv code cleanup - this is a start on moving quota and dmapi

into behavior layers, purging several points where these sit slap bang in
the middle of XFS code (esp. read_super).  Also removes numerous #ifdef's
and a bunch of unused #define's from all over the place.  More to come.

SGI Modid: 2.5.x-xfs:slinx:141499a
parent d189d057
# #
# Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. # Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -32,10 +32,6 @@ ...@@ -32,10 +32,6 @@
# Makefile for XFS on Linux. # Makefile for XFS on Linux.
# #
# This needs -I. because everything does #include <xfs.h> instead of "xfs.h".
# The code is wrong, local files should be included using "xfs.h", not <xfs.h>
# but I am not going to change every file at the moment.
EXTRA_CFLAGS += -Ifs/xfs -funsigned-char EXTRA_CFLAGS += -Ifs/xfs -funsigned-char
ifeq ($(CONFIG_XFS_DEBUG),y) ifeq ($(CONFIG_XFS_DEBUG),y)
...@@ -54,6 +50,7 @@ xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \ ...@@ -54,6 +50,7 @@ xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \
xfs_dquot_item.o \ xfs_dquot_item.o \
xfs_trans_dquot.o \ xfs_trans_dquot.o \
xfs_qm_syscalls.o \ xfs_qm_syscalls.o \
xfs_qmops.o \
xfs_qm.o xfs_qm.o
xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
...@@ -127,6 +124,7 @@ xfs-y += $(addprefix linux/, \ ...@@ -127,6 +124,7 @@ xfs-y += $(addprefix linux/, \
xfs_iops.o \ xfs_iops.o \
xfs_lrw.o \ xfs_lrw.o \
xfs_super.o \ xfs_super.o \
xfs_vfs.o \
xfs_vnode.o) xfs_vnode.o)
# Objects in support/ # Objects in support/
......
/* /*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -30,41 +30,77 @@ ...@@ -30,41 +30,77 @@
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
* *
*/ */
#include <xfs.h>
/* /*
* Source file used to associate/disassociate behaviors with virtualized * Source file used to associate/disassociate behaviors with virtualized
* objects. See behavior.h for more information about behaviors, etc. * objects. See xfs_behavior.h for more information about behaviors, etc.
* *
* The implementation is split between functions in this file and macros * The implementation is split between functions in this file and macros
* in behavior.h. * in xfs_behavior.h.
*/ */
#include <xfs.h>
kmem_zone_t *bhv_global_zone;
/* /*
* Global initialization function called out of main. * Insert a new behavior descriptor into a behavior chain.
*
* The behavior chain is ordered based on the 'position' number which
* lives in the first field of the ops vector (higher numbers first).
*
* Attemps to insert duplicate ops result in an EINVAL return code.
* Otherwise, return 0 to indicate success.
*/ */
void int
bhv_global_init(void) bhv_insert(bhv_head_t *bhp, bhv_desc_t *bdp)
{ {
bhv_desc_t *curdesc, *prev;
int position;
/*
* Validate the position value of the new behavior.
*/
position = BHV_POSITION(bdp);
ASSERT(position >= BHV_POSITION_BASE && position <= BHV_POSITION_TOP);
/* /*
* Initialize a behavior zone used by subsystems using behaviors * Find location to insert behavior. Check for duplicates.
* but without any private data. In the UNIKERNEL case, this zone
* is used only for behaviors that are not yet isolated to a single
* cell. The only such user is in pshm.c in which a dummy vnode is
* obtained in support of vce avoidance logic.
*/ */
bhv_global_zone = kmem_zone_init(sizeof(bhv_desc_t), "bhv_global_zone"); prev = NULL;
for (curdesc = bhp->bh_first;
curdesc != NULL;
curdesc = curdesc->bd_next) {
/* Check for duplication. */
if (curdesc->bd_ops == bdp->bd_ops) {
ASSERT(0);
return EINVAL;
}
/* Find correct position */
if (position >= BHV_POSITION(curdesc)) {
ASSERT(position != BHV_POSITION(curdesc));
break; /* found it */
}
prev = curdesc;
}
if (prev == NULL) {
/* insert at front of chain */
bdp->bd_next = bhp->bh_first;
bhp->bh_first = bdp;
} else {
/* insert after prev */
bdp->bd_next = prev->bd_next;
prev->bd_next = bdp;
}
return 0;
} }
/* /*
* Remove a behavior descriptor from a position in a behavior chain; * Remove a behavior descriptor from a position in a behavior chain;
* the postition is guaranteed not to be the first position. * the postition is guaranteed not to be the first position.
* Should only be called by the bhv_remove() macro. * Should only be called by the bhv_remove() macro.
*
* The act of modifying the chain is done atomically w.r.t. ops-in-progress
* (see comment at top of behavior.h for more info on synchronization).
*/ */
void void
bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp) bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
...@@ -86,7 +122,6 @@ bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp) ...@@ -86,7 +122,6 @@ bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
ASSERT(curdesc == bdp); ASSERT(curdesc == bdp);
prev->bd_next = bdp->bd_next; /* remove from after prev */ prev->bd_next = bdp->bd_next; /* remove from after prev */
/* atomic wrt oip's */
} }
/* /*
...@@ -110,20 +145,28 @@ bhv_lookup(bhv_head_t *bhp, void *ops) ...@@ -110,20 +145,28 @@ bhv_lookup(bhv_head_t *bhp, void *ops)
} }
/* /*
* Look for a specific ops vector on the specified behavior chain. * Looks for the first behavior within a specified range of positions.
* Return the associated behavior descriptor. Or NULL, if not found. * Return the associated behavior descriptor. Or NULL, if none found.
*
* The caller has not read locked the behavior chain, so acquire the
* lock before traversing the chain.
*/ */
bhv_desc_t * bhv_desc_t *
bhv_lookup_unlocked(bhv_head_t *bhp, void *ops) bhv_lookup_range(bhv_head_t *bhp, int low, int high)
{ {
bhv_desc_t *bdp; bhv_desc_t *curdesc;
for (curdesc = bhp->bh_first;
curdesc != NULL;
curdesc = curdesc->bd_next) {
bdp = bhv_lookup(bhp, ops); int position = BHV_POSITION(curdesc);
return bdp; if (position <= high) {
if (position >= low)
return curdesc;
return NULL;
}
}
return NULL;
} }
/* /*
...@@ -134,49 +177,36 @@ bhv_lookup_unlocked(bhv_head_t *bhp, void *ops) ...@@ -134,49 +177,36 @@ bhv_lookup_unlocked(bhv_head_t *bhp, void *ops)
* lock before traversing the chain. * lock before traversing the chain.
*/ */
bhv_desc_t * bhv_desc_t *
bhv_base_unlocked(bhv_head_t *bhp) bhv_base(bhv_head_t *bhp)
{ {
bhv_desc_t *curdesc; bhv_desc_t *curdesc;
for (curdesc = bhp->bh_first; for (curdesc = bhp->bh_first;
curdesc != NULL; curdesc != NULL;
curdesc = curdesc->bd_next) { curdesc = curdesc->bd_next) {
if (curdesc->bd_next == NULL)
if (curdesc->bd_next == NULL) {
return curdesc; return curdesc;
}
} }
return NULL; return NULL;
} }
#define BHVMAGIC (void *)0xf00d
/* ARGSUSED */
void void
bhv_head_init( bhv_head_init(
bhv_head_t *bhp, bhv_head_t *bhp,
char *name) char *name)
{ {
bhp->bh_first = NULL; bhp->bh_first = NULL;
bhp->bh_lockp = BHVMAGIC;
}
/* ARGSUSED */
void
bhv_head_reinit(
bhv_head_t *bhp)
{
ASSERT(bhp->bh_first == NULL);
ASSERT(bhp->bh_lockp == BHVMAGIC);
} }
void void
bhv_insert_initial( bhv_insert_initial(
bhv_head_t *bhp, bhv_head_t *bhp,
bhv_desc_t *bdp) bhv_desc_t *bdp)
{ {
ASSERT(bhp->bh_first == NULL); ASSERT(bhp->bh_first == NULL);
ASSERT(bhp->bh_lockp == BHVMAGIC);
(bhp)->bh_first = bdp; (bhp)->bh_first = bdp;
} }
...@@ -185,7 +215,4 @@ bhv_head_destroy( ...@@ -185,7 +215,4 @@ bhv_head_destroy(
bhv_head_t *bhp) bhv_head_t *bhp)
{ {
ASSERT(bhp->bh_first == NULL); ASSERT(bhp->bh_first == NULL);
ASSERT(bhp->bh_lockp == BHVMAGIC);
bhp->bh_lockp = NULL;
} }
/* /*
* Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -91,8 +91,8 @@ ...@@ -91,8 +91,8 @@
* active object * active object
* *
*/ */
typedef void bhv_head_lock_t; struct bhv_head_lock;
/* /*
* Behavior head. Head of the chain of behaviors. * Behavior head. Head of the chain of behaviors.
...@@ -100,7 +100,7 @@ typedef void bhv_head_lock_t; ...@@ -100,7 +100,7 @@ typedef void bhv_head_lock_t;
*/ */
typedef struct bhv_head { typedef struct bhv_head {
struct bhv_desc *bh_first; /* first behavior in chain */ struct bhv_desc *bh_first; /* first behavior in chain */
bhv_head_lock_t *bh_lockp; /* pointer to lock info struct */ struct bhv_head_lock *bh_lockp; /* pointer to lock info struct */
} bhv_head_t; } bhv_head_t;
/* /*
...@@ -128,10 +128,8 @@ typedef struct bhv_identity { ...@@ -128,10 +128,8 @@ typedef struct bhv_identity {
typedef bhv_identity_t bhv_position_t; typedef bhv_identity_t bhv_position_t;
#define BHV_IDENTITY_INIT(id,pos) {id, pos} #define BHV_IDENTITY_INIT(id,pos) {id, pos}
#define BHV_IDENTITY_INIT_POSITION(pos) BHV_IDENTITY_INIT(0, pos) #define BHV_IDENTITY_INIT_POSITION(pos) BHV_IDENTITY_INIT(0, pos)
/* /*
* Define boundaries of position values. * Define boundaries of position values.
*/ */
...@@ -154,7 +152,7 @@ typedef bhv_identity_t bhv_position_t; ...@@ -154,7 +152,7 @@ typedef bhv_identity_t bhv_position_t;
extern void bhv_head_init(bhv_head_t *, char *); extern void bhv_head_init(bhv_head_t *, char *);
extern void bhv_head_destroy(bhv_head_t *); extern void bhv_head_destroy(bhv_head_t *);
extern void bhv_head_reinit(bhv_head_t *); extern int bhv_insert(bhv_head_t *, bhv_desc_t *);
extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *); extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *);
/* /*
...@@ -196,7 +194,11 @@ extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *); ...@@ -196,7 +194,11 @@ extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *);
*/ */
extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp); extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp);
extern bhv_desc_t * bhv_lookup(bhv_head_t *bhp, void *ops); extern bhv_desc_t * bhv_lookup(bhv_head_t *bhp, void *ops);
extern bhv_desc_t * bhv_lookup_unlocked(bhv_head_t *bhp, void *ops); extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high);
extern bhv_desc_t * bhv_base_unlocked(bhv_head_t *bhp); extern bhv_desc_t * bhv_base(bhv_head_t *bhp);
/* No bhv locking on Linux */
#define bhv_lookup_unlocked bhv_lookup
#define bhv_base_unlocked bhv_base
#endif /* __XFS_BEHAVIOR_H__ */ #endif /* __XFS_BEHAVIOR_H__ */
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -130,7 +130,7 @@ xfs_find_handle( ...@@ -130,7 +130,7 @@ xfs_find_handle(
int lock_mode; int lock_mode;
/* need to get access to the xfs_inode to read the generation */ /* need to get access to the xfs_inode to read the generation */
bhv = VNODE_TO_FIRST_BHV(vp); bhv = vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops);
ASSERT(bhv); ASSERT(bhv);
ip = XFS_BHVTOI(bhv); ip = XFS_BHVTOI(bhv);
ASSERT(ip); ASSERT(ip);
......
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <linux/major.h> #include <linux/major.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/seq_file.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/div64.h> #include <asm/div64.h>
...@@ -160,6 +161,15 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh) ...@@ -160,6 +161,15 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
#define SYNCHRONIZE() barrier() #define SYNCHRONIZE() barrier()
#define __return_address __builtin_return_address(0) #define __return_address __builtin_return_address(0)
/*
* IRIX (BSD) quotactl makes use of separate commands for user/group,
* whereas on Linux the syscall encodes this information into the cmd
* field (see the QCMD macro in quota.h). These macros help keep the
* code portable - they are not visible from the syscall interface.
*/
#define Q_XSETGQLIM XQM_CMD(0x8) /* set groups disk limits */
#define Q_XGETGQUOTA XQM_CMD(0x9) /* get groups disk limits */
/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */ /* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
/* we may well need to fine-tune this if it ever becomes an issue. */ /* we may well need to fine-tune this if it ever becomes an issue. */
#define DQUOT_MAX_HEURISTIC 1024 /* NR_DQUOTS */ #define DQUOT_MAX_HEURISTIC 1024 /* NR_DQUOTS */
......
This diff is collapsed.
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -34,20 +34,34 @@ ...@@ -34,20 +34,34 @@
#ifdef CONFIG_XFS_POSIX_ACL #ifdef CONFIG_XFS_POSIX_ACL
# define XFS_ACL_STRING "ACLs, " # define XFS_ACL_STRING "ACLs, "
# define set_posix_acl_flag(sb) ((sb)->s_flags |= MS_POSIXACL)
#else #else
# define XFS_ACL_STRING # define XFS_ACL_STRING
# define set_posix_acl_flag(sb) do { } while (0)
#endif #endif
#ifdef CONFIG_XFS_DMAPI #ifdef CONFIG_XFS_DMAPI
# define XFS_DMAPI_STRING "DMAPI, " # define XFS_DMAPI_STRING "DMAPI, "
# define vfs_insertdmapi(vfs) vfs_insertops(vfsp, &xfs_dmops_xfs)
# define vfs_initdmapi() (0) /* temporarily */
# define vfs_exitdmapi() do { } while (0) /* temporarily */
#else #else
# define XFS_DMAPI_STRING # define XFS_DMAPI_STRING
# define vfs_insertdmapi(vfs) do { } while (0)
# define vfs_initdmapi() (0)
# define vfs_exitdmapi() do { } while (0)
#endif #endif
#ifdef CONFIG_XFS_QUOTA #ifdef CONFIG_XFS_QUOTA
# define XFS_QUOTA_STRING "quota, " # define XFS_QUOTA_STRING "quota, "
# define vfs_insertquota(vfs) vfs_insertops(vfsp, &xfs_qmops_xfs)
# define vfs_initquota() (0) /* temporarily */
# define vfs_exitquota() do { } while (0) /* temporarily */
#else #else
# define XFS_QUOTA_STRING # define XFS_QUOTA_STRING
# define vfs_insertquota(vfs) do { } while (0)
# define vfs_initquota() (0)
# define vfs_exitquota() do { } while (0)
#endif #endif
#ifdef CONFIG_XFS_RT #ifdef CONFIG_XFS_RT
...@@ -82,6 +96,8 @@ struct xfs_mount; ...@@ -82,6 +96,8 @@ struct xfs_mount;
struct pb_target; struct pb_target;
struct block_device; struct block_device;
extern int xfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
extern int xfs_showargs(bhv_desc_t *, struct seq_file *);
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(struct xfs_mount *, const char *, extern int xfs_blkdev_get(struct xfs_mount *, const char *,
...@@ -95,4 +111,8 @@ extern void xfs_free_buftarg(struct pb_target *); ...@@ -95,4 +111,8 @@ extern void xfs_free_buftarg(struct pb_target *);
extern void xfs_setsize_buftarg(struct pb_target *, unsigned int, unsigned int); extern void xfs_setsize_buftarg(struct pb_target *, unsigned int, unsigned int);
extern unsigned int xfs_getsize_buftarg(struct pb_target *); extern unsigned int xfs_getsize_buftarg(struct pb_target *);
extern void bhv_insert_all_vfsops(struct vfs *);
extern void bhv_remove_all_vfsops(struct vfs *, int);
extern void bhv_remove_vfsops(struct vfs *, int);
#endif /* __XFS_SUPER_H__ */ #endif /* __XFS_SUPER_H__ */
/*
* Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
*
* 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
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#include <xfs.h>
int
vfs_mount(bhv_desc_t *bdp, struct xfs_mount_args *args, struct cred *cr)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_mount)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_mount)(next, args, cr));
}
int
vfs_parseargs(bhv_desc_t *bdp, char *s, struct xfs_mount_args *args, int f)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_parseargs)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_parseargs)(next, s, args, f));
}
int
vfs_showargs(bhv_desc_t *bdp, struct seq_file *m)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_showargs)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_showargs)(next, m));
}
int
vfs_unmount(bhv_desc_t *bdp, int fl, struct cred *cr)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_unmount)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_unmount)(next, fl, cr));
}
int
vfs_root(bhv_desc_t *bdp, struct vnode **vpp)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_root)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_root)(next, vpp));
}
int
vfs_statvfs(bhv_desc_t *bdp, struct statfs *sp, struct vnode *vp)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_statvfs)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_statvfs)(next, sp, vp));
}
int
vfs_sync(bhv_desc_t *bdp, int fl, struct cred *cr)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_sync)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_sync)(next, fl, cr));
}
int
vfs_vget(bhv_desc_t *bdp, struct vnode **vpp, struct fid *fidp)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_vget)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_vget)(next, vpp, fidp));
}
int
vfs_dmapiops(bhv_desc_t *bdp, caddr_t addr)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_dmapiops)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_dmapiops)(next, addr));
}
int
vfs_quotactl(bhv_desc_t *bdp, int cmd, int id, caddr_t addr)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_quotactl)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_quotactl)(next, cmd, id, addr));
}
void
vfs_init_vnode(bhv_desc_t *bdp, struct vnode *vp, bhv_desc_t *bp, int unlock)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_init_vnode)
next = BHV_NEXT(next);
((*bhvtovfsops(next)->vfs_init_vnode)(next, vp, bp, unlock));
}
void
vfs_force_shutdown(bhv_desc_t *bdp, int fl, char *file, int line)
{
bhv_desc_t *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_force_shutdown)
next = BHV_NEXT(next);
((*bhvtovfsops(next)->vfs_force_shutdown)(next, fl, file, line));
}
vfs_t *
vfs_allocate(void)
{
vfs_t *vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP);
bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
return vfsp;
}
void
vfs_deallocate(vfs_t *vfsp)
{
bhv_head_destroy(VFS_BHVHEAD(vfsp));
kmem_free(vfsp, sizeof(vfs_t));
}
void
vfs_insertops(vfs_t *vfsp, vfsops_t *vfsops)
{
bhv_desc_t *bdp = kmem_alloc(sizeof(bhv_desc_t), KM_SLEEP);
bhv_desc_init(bdp, NULL, vfsp, vfsops);
bhv_insert(&vfsp->vfs_bh, bdp);
}
void
vfs_insertbhv(vfs_t *vfsp, bhv_desc_t *bdp, vfsops_t *vfsops, void *mount)
{
bhv_desc_init(bdp, mount, vfsp, vfsops);
bhv_insert_initial(&vfsp->vfs_bh, bdp);
}
This diff is collapsed.
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -85,10 +85,16 @@ typedef struct vnode { ...@@ -85,10 +85,16 @@ typedef struct vnode {
typedef enum { typedef enum {
VN_BHV_UNKNOWN, /* not specified */ VN_BHV_UNKNOWN, /* not specified */
VN_BHV_XFS, /* xfs */ VN_BHV_XFS, /* xfs */
VN_BHV_DM, /* data migration */
VN_BHV_QM, /* quota manager */
VN_BHV_IO, /* IO path */
VN_BHV_END /* housekeeping end-of-range */ VN_BHV_END /* housekeeping end-of-range */
} vn_bhv_t; } vn_bhv_t;
#define VNODE_POSITION_XFS (VNODE_POSITION_BASE) #define VNODE_POSITION_XFS (VNODE_POSITION_BASE)
#define VNODE_POSITION_DM (VNODE_POSITION_BASE+10)
#define VNODE_POSITION_QM (VNODE_POSITION_BASE+20)
#define VNODE_POSITION_IO (VNODE_POSITION_BASE+30)
/* /*
* Macros for dealing with the behavior descriptor inside of the vnode. * Macros for dealing with the behavior descriptor inside of the vnode.
...@@ -96,7 +102,6 @@ typedef enum { ...@@ -96,7 +102,6 @@ typedef enum {
#define BHV_TO_VNODE(bdp) ((vnode_t *)BHV_VOBJ(bdp)) #define BHV_TO_VNODE(bdp) ((vnode_t *)BHV_VOBJ(bdp))
#define BHV_TO_VNODE_NULL(bdp) ((vnode_t *)BHV_VOBJNULL(bdp)) #define BHV_TO_VNODE_NULL(bdp) ((vnode_t *)BHV_VOBJNULL(bdp))
#define VNODE_TO_FIRST_BHV(vp) (BHV_HEAD_FIRST(&(vp)->v_bh))
#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh))) #define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name) #define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
#define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp) #define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp)
...@@ -127,16 +132,6 @@ extern ushort vttoif_tab[]; ...@@ -127,16 +132,6 @@ extern ushort vttoif_tab[];
#define VWAIT 0x4 /* waiting for VINACT/VRECLM to end */ #define VWAIT 0x4 /* waiting for VINACT/VRECLM to end */
#define VMODIFIED 0x8 /* XFS inode state possibly differs */ #define VMODIFIED 0x8 /* XFS inode state possibly differs */
/* to the Linux inode state. */ /* to the Linux inode state. */
#define VROOT 0x100000 /* root of its file system */
#define VNOSWAP 0x200000 /* cannot be used as virt swap device */
#define VISSWAP 0x400000 /* vnode is part of virt swap device */
#define VREPLICABLE 0x800000 /* Vnode can have replicated pages */
#define VNONREPLICABLE 0x1000000 /* Vnode has writers. Don't replicate */
#define VDOCMP 0x2000000 /* Vnode has special VOP_CMP impl. */
#define VSHARE 0x4000000 /* vnode part of global cache */
#define VFRLOCKS 0x8000000 /* vnode has FR locks applied */
#define VENF_LOCKING 0x10000000 /* enf. mode FR locking in effect */
#define VOPLOCK 0x20000000 /* oplock set on the vnode */
typedef enum vrwlock { VRWLOCK_NONE, VRWLOCK_READ, typedef enum vrwlock { VRWLOCK_NONE, VRWLOCK_READ,
VRWLOCK_WRITE, VRWLOCK_WRITE_DIRECT, VRWLOCK_WRITE, VRWLOCK_WRITE_DIRECT,
...@@ -267,163 +262,92 @@ typedef struct vnodeops { ...@@ -267,163 +262,92 @@ typedef struct vnodeops {
*/ */
#define _VOP_(op, vp) (*((vnodeops_t *)(vp)->v_fops)->op) #define _VOP_(op, vp) (*((vnodeops_t *)(vp)->v_fops)->op)
#define VOP_READ(vp,file,iov,segs,offset,cr,rv) \ #define VOP_READ(vp,file,iov,segs,offset,cr,rv) \
{ \ rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,cr)
rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,cr); \ #define VOP_WRITE(vp,file,iov,segs,offset,cr,rv) \
} rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,cr)
#define VOP_WRITE(vp,file,iov,segs,offset,cr,rv) \ #define VOP_SENDFILE(vp,f,off,cnt,act,targ,cr,rv) \
{ \ rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,cnt,act,targ,cr)
rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,cr);\
}
#define VOP_SENDFILE(vp,f,of,cnt,act,targ,cr,rv) \
{ \
rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,of,cnt,act,targ,cr);\
}
#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \ #define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
{ \ rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n); \
}
#define VOP_OPEN(vp, cr, rv) \ #define VOP_OPEN(vp, cr, rv) \
{ \ rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr)
rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr); \
}
#define VOP_GETATTR(vp, vap, f, cr, rv) \ #define VOP_GETATTR(vp, vap, f, cr, rv) \
{ \ rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr)
rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr); \
}
#define VOP_SETATTR(vp, vap, f, cr, rv) \ #define VOP_SETATTR(vp, vap, f, cr, rv) \
{ \ rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr)
rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr); \
}
#define VOP_ACCESS(vp, mode, cr, rv) \ #define VOP_ACCESS(vp, mode, cr, rv) \
{ \ rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr)
rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr); \
}
#define VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv) \ #define VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv) \
{ \ rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr)
rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr); \
}
#define VOP_CREATE(dvp,d,vap,vpp,cr,rv) \ #define VOP_CREATE(dvp,d,vap,vpp,cr,rv) \
{ \ rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr)
rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr); \
}
#define VOP_REMOVE(dvp,d,cr,rv) \ #define VOP_REMOVE(dvp,d,cr,rv) \
{ \ rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr)
rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr); \
}
#define VOP_LINK(tdvp,fvp,d,cr,rv) \ #define VOP_LINK(tdvp,fvp,d,cr,rv) \
{ \ rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr)
rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr); \
}
#define VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv) \ #define VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv) \
{ \ rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr)
rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr); \
}
#define VOP_MKDIR(dp,d,vap,vpp,cr,rv) \ #define VOP_MKDIR(dp,d,vap,vpp,cr,rv) \
{ \ rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr)
rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr); \
}
#define VOP_RMDIR(dp,d,cr,rv) \ #define VOP_RMDIR(dp,d,cr,rv) \
{ \ rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr)
rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr); \
}
#define VOP_READDIR(vp,uiop,cr,eofp,rv) \ #define VOP_READDIR(vp,uiop,cr,eofp,rv) \
{ \ rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp)
rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp); \
}
#define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \ #define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \
{ \ rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr)
rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr); \
}
#define VOP_READLINK(vp,uiop,cr,rv) \ #define VOP_READLINK(vp,uiop,cr,rv) \
{ \ rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,cr)
rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,cr); \
}
#define VOP_FSYNC(vp,f,cr,b,e,rv) \ #define VOP_FSYNC(vp,f,cr,b,e,rv) \
{ \ rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e)
rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e); \
}
#define VOP_INACTIVE(vp, cr, rv) \ #define VOP_INACTIVE(vp, cr, rv) \
{ \ rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr)
rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr); \
}
#define VOP_RELEASE(vp, rv) \ #define VOP_RELEASE(vp, rv) \
{ \ rv = _VOP_(vop_release, vp)((vp)->v_fbhv)
rv = _VOP_(vop_release, vp)((vp)->v_fbhv); \
}
#define VOP_FID2(vp, fidp, rv) \ #define VOP_FID2(vp, fidp, rv) \
{ \ rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp)
rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp); \
}
#define VOP_RWLOCK(vp,i) \ #define VOP_RWLOCK(vp,i) \
{ \ (void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
(void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i); \
}
#define VOP_RWLOCK_TRY(vp,i) \ #define VOP_RWLOCK_TRY(vp,i) \
_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i) _VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
#define VOP_RWUNLOCK(vp,i) \ #define VOP_RWUNLOCK(vp,i) \
{ \ (void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i)
(void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i); \ #define VOP_FRLOCK(vp,c,fl,flags,offset,fr,rv) \
} rv = _VOP_(vop_frlock, vp)((vp)->v_fbhv,c,fl,flags,offset,fr)
#define VOP_RECLAIM(vp, rv) \ #define VOP_RECLAIM(vp, rv) \
{ \ rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv)
rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv); \
}
#define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv) \ #define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv) \
{ \ rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred)
rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred); \
}
#define VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv) \ #define VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv) \
{ \ rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred)
rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred); \
}
#define VOP_ATTR_REMOVE(vp, name, flags, cred, rv) \ #define VOP_ATTR_REMOVE(vp, name, flags, cred, rv) \
{ \ rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred)
rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred); \
}
#define VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv) \ #define VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv) \
{ \ rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred)
rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred);\
}
#define VOP_LINK_REMOVED(vp, dvp, linkzero) \ #define VOP_LINK_REMOVED(vp, dvp, linkzero) \
{ \ (void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero)
(void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero); \
}
#define VOP_VNODE_CHANGE(vp, cmd, val) \ #define VOP_VNODE_CHANGE(vp, cmd, val) \
{ \ (void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val)
(void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val); \
}
/* /*
* These are page cache functions that now go thru VOPs. * These are page cache functions that now go thru VOPs.
* 'last' parameter is unused and left in for IRIX compatibility * 'last' parameter is unused and left in for IRIX compatibility
*/ */
#define VOP_TOSS_PAGES(vp, first, last, fiopt) \ #define VOP_TOSS_PAGES(vp, first, last, fiopt) \
{ \ _VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt)
_VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt); \
}
/* /*
* 'last' parameter is unused and left in for IRIX compatibility * 'last' parameter is unused and left in for IRIX compatibility
*/ */
#define VOP_FLUSHINVAL_PAGES(vp, first, last, fiopt) \ #define VOP_FLUSHINVAL_PAGES(vp, first, last, fiopt) \
{ \ _VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt)
_VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt); \
}
/* /*
* 'last' parameter is unused and left in for IRIX compatibility * 'last' parameter is unused and left in for IRIX compatibility
*/ */
#define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv) \ #define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv) \
{ \ rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt)
rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt);\
}
#define VOP_IOCTL(vp, inode, filp, cmd, arg, rv) \ #define VOP_IOCTL(vp, inode, filp, cmd, arg, rv) \
{ \ rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,cmd,arg)
rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,cmd,arg); \
}
#define VOP_IFLUSH(vp, flags, rv) \ #define VOP_IFLUSH(vp, flags, rv) \
{ \ rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags)
rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags); \
}
/* /*
* Flags for VOP_IFLUSH call * Flags for VOP_IFLUSH call
......
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -144,16 +144,10 @@ ...@@ -144,16 +144,10 @@
(1 << DM_EVENT_DESTROY) ) (1 << DM_EVENT_DESTROY) )
extern int
xfs_dm_mount(
vfs_t *vfsp,
char *dir_name,
char *fsname);
extern int extern int
xfs_dm_get_fsys_vector( xfs_dm_get_fsys_vector(
bhv_desc_t *bdp, bhv_desc_t *bdp,
dm_fcntl_vector_t *vecrq); caddr_t vecrq);
extern int extern int
xfs_dm_send_data_event( xfs_dm_send_data_event(
......
/*
* Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
*
* 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
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#include <xfs.h>
#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
STATIC int
xfs_dm_parseargs(
struct bhv_desc *bhv,
char *options,
struct xfs_mount_args *args,
int update)
{
size_t length;
char *local_options = options;
char *this_char;
int error;
while ((this_char = strsep(&local_options, ",")) != NULL) {
length = strlen(this_char);
if (local_options)
length++;
if (!strcmp(this_char, MNTOPT_DMAPI)) {
args->flags |= XFSMNT_DMAPI;
} else if (!strcmp(this_char, MNTOPT_XDSM)) {
args->flags |= XFSMNT_DMAPI;
} else {
if (local_options)
*(local_options-1) = ',';
continue;
}
while (length--)
*this_char++ = ',';
}
PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
if (!error && (args->flags & XFSMNT_DMAPI) && (*args->mtpt == '\0'))
error = EINVAL;
if (!error && !update && !(args->flags & XFSMNT_DMAPI))
bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_DM);
return error;
}
STATIC int
xfs_dm_showargs(
struct bhv_desc *bhv,
struct seq_file *m)
{
struct vfs *vfsp = bhvtovfs(bhv);
int error;
if (vfsp->vfs_flag & VFS_DMI)
seq_puts(m, "," MNTOPT_DMAPI);
PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
return error;
}
STATIC int
xfs_dm_mount(
struct bhv_desc *bhv,
struct xfs_mount_args *args,
struct cred *cr)
{
struct bhv_desc *rootbdp;
struct vnode *rootvp;
struct vfs *vfsp;
int error = 0;
PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
if (error)
return error;
if (args->flags & XFSMNT_DMAPI) {
vfsp = bhvtovfs(bhv);
VFS_ROOT(vfsp, &rootvp, error);
if (!error) {
vfsp->vfs_flag |= VFS_DMI;
rootbdp = vn_bhv_lookup_unlocked(
VN_BHV_HEAD(rootvp), &xfs_vnodeops);
VN_RELE(rootvp);
error = dm_send_mount_event(vfsp, DM_RIGHT_NULL, NULL,
DM_RIGHT_NULL, rootbdp, DM_RIGHT_NULL,
args->mtpt, args->fsname);
}
}
return error;
}
vfsops_t xfs_dmops_xfs = {
BHV_IDENTITY_INIT(VFS_BHV_DM, VFS_POSITION_DM),
.vfs_mount = xfs_dm_mount,
.vfs_parseargs = xfs_dm_parseargs,
.vfs_showargs = xfs_dm_showargs,
.vfs_dmapiops = xfs_dm_get_fsys_vector,
};
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -1190,25 +1190,6 @@ xfs_ialloc( ...@@ -1190,25 +1190,6 @@ xfs_ialloc(
ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
ip->i_d.di_anextents = 0; ip->i_d.di_anextents = 0;
#if DEBUG
{
uint badflags = VNOSWAP |
VISSWAP |
VREPLICABLE |
/* VNONREPLICABLE | XXX uncomment this */
VDOCMP |
VFRLOCKS;
/*
* For shared mounts, VNOSWAP is set in xfs_iget
*/
if (tp->t_mountp->m_cxfstype != XFS_CXFS_NOT)
badflags &= ~VNOSWAP;
ASSERT(!(vp->v_flag & badflags));
}
#endif /* DEBUG */
/* /*
* Log the new values stuffed into the inode. * Log the new values stuffed into the inode.
*/ */
......
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -33,15 +33,25 @@ ...@@ -33,15 +33,25 @@
#include <xfs.h> #include <xfs.h>
static xfs_fsize_t STATIC xfs_fsize_t
xfs_size_fn( xfs_size_fn(
xfs_inode_t *ip) xfs_inode_t *ip)
{ {
return (ip->i_d.di_size); return (ip->i_d.di_size);
} }
STATIC int
xfs_ioinit(
struct vfs *vfsp,
struct xfs_mount_args *mntargs,
int flags)
{
return xfs_mountfs(vfsp, XFS_VFSTOM(vfsp),
vfsp->vfs_super->s_bdev->bd_dev, flags);
}
xfs_ioops_t xfs_iocore_xfs = { xfs_ioops_t xfs_iocore_xfs = {
.xfs_ioinit = (xfs_ioinit_t) fs_noerr, .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit,
.xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi, .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi,
.xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof, .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof,
.xfs_iomap_write_direct = .xfs_iomap_write_direct =
......
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -358,6 +358,14 @@ xfs_bhvtom(bhv_desc_t *bdp) ...@@ -358,6 +358,14 @@ xfs_bhvtom(bhv_desc_t *bdp)
} }
#endif #endif
#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_VFSTOM)
xfs_mount_t *
xfs_vfstom(vfs_t *vfs)
{
return XFS_VFSTOM(vfs);
}
#endif
#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BM_MAXLEVELS) #if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_BM_MAXLEVELS)
int int
xfs_bm_maxlevels(xfs_mount_t *mp, int w) xfs_bm_maxlevels(xfs_mount_t *mp, int w)
......
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -40,8 +40,6 @@ mutex_t xfs_uuidtabmon; /* monitor for uuidtab */ ...@@ -40,8 +40,6 @@ mutex_t xfs_uuidtabmon; /* monitor for uuidtab */
STATIC int xfs_uuidtab_size; STATIC int xfs_uuidtab_size;
STATIC uuid_t *xfs_uuidtab; STATIC uuid_t *xfs_uuidtab;
STATIC void xfs_uuid_unmount(xfs_mount_t *);
void xfs_xlatesb(void *, xfs_sb_t *, int, xfs_arch_t, __int64_t); void xfs_xlatesb(void *, xfs_sb_t *, int, xfs_arch_t, __int64_t);
static struct { static struct {
...@@ -120,10 +118,9 @@ xfs_mount_init(void) ...@@ -120,10 +118,9 @@ xfs_mount_init(void)
spinlock_init(&mp->m_freeze_lock, "xfs_freeze"); spinlock_init(&mp->m_freeze_lock, "xfs_freeze");
init_sv(&mp->m_wait_unfreeze, SV_DEFAULT, "xfs_freeze", 0); init_sv(&mp->m_wait_unfreeze, SV_DEFAULT, "xfs_freeze", 0);
atomic_set(&mp->m_active_trans, 0); atomic_set(&mp->m_active_trans, 0);
mp->m_cxfstype = XFS_CXFS_NOT;
return mp; return mp;
} /* xfs_mount_init */ }
/* /*
* Free up the resources associated with a mount structure. Assume that * Free up the resources associated with a mount structure. Assume that
...@@ -146,19 +143,12 @@ xfs_mount_free( ...@@ -146,19 +143,12 @@ xfs_mount_free(
for (agno = 0; agno < mp->m_maxagi; agno++) for (agno = 0; agno < mp->m_maxagi; agno++)
if (mp->m_perag[agno].pagb_list) if (mp->m_perag[agno].pagb_list)
kmem_free(mp->m_perag[agno].pagb_list, kmem_free(mp->m_perag[agno].pagb_list,
sizeof(xfs_perag_busy_t) * XFS_PAGB_NUM_SLOTS); sizeof(xfs_perag_busy_t) *
XFS_PAGB_NUM_SLOTS);
kmem_free(mp->m_perag, kmem_free(mp->m_perag,
sizeof(xfs_perag_t) * mp->m_sb.sb_agcount); sizeof(xfs_perag_t) * mp->m_sb.sb_agcount);
} }
#if 0
/*
* XXXdpd - Doesn't work now for shutdown case.
* Should at least free the memory.
*/
ASSERT(mp->m_ail.ail_back == (xfs_log_item_t*)&(mp->m_ail));
ASSERT(mp->m_ail.ail_forw == (xfs_log_item_t*)&(mp->m_ail));
#endif
AIL_LOCK_DESTROY(&mp->m_ail_lock); AIL_LOCK_DESTROY(&mp->m_ail_lock);
spinlock_destroy(&mp->m_sb_lock); spinlock_destroy(&mp->m_sb_lock);
mutex_destroy(&mp->m_ilock); mutex_destroy(&mp->m_ilock);
...@@ -172,8 +162,12 @@ xfs_mount_free( ...@@ -172,8 +162,12 @@ xfs_mount_free(
} }
if (remove_bhv) { if (remove_bhv) {
VFS_REMOVEBHV(XFS_MTOVFS(mp), &mp->m_bhv); struct vfs *vfsp = XFS_MTOVFS(mp);
bhv_remove_all_vfsops(vfsp, 0);
VFS_REMOVEBHV(vfsp, &mp->m_bhv);
} }
spinlock_destroy(&mp->m_freeze_lock); spinlock_destroy(&mp->m_freeze_lock);
sv_destroy(&mp->m_wait_unfreeze); sv_destroy(&mp->m_wait_unfreeze);
kmem_free(mp, sizeof(xfs_mount_t)); kmem_free(mp, sizeof(xfs_mount_t));
...@@ -605,14 +599,11 @@ xfs_mountfs( ...@@ -605,14 +599,11 @@ xfs_mountfs(
{ {
xfs_buf_t *bp; xfs_buf_t *bp;
xfs_sb_t *sbp = &(mp->m_sb); xfs_sb_t *sbp = &(mp->m_sb);
int error = 0;
xfs_inode_t *rip; xfs_inode_t *rip;
vnode_t *rvp = 0; vnode_t *rvp = 0;
int readio_log; int readio_log, writeio_log;
int writeio_log;
vmap_t vmap; vmap_t vmap;
xfs_daddr_t d; xfs_daddr_t d;
extern xfs_ioops_t xfs_iocore_xfs; /* from xfs_iocore.c */
__uint64_t ret64; __uint64_t ret64;
uint quotaflags, quotaondisk; uint quotaflags, quotaondisk;
uint uquotaondisk = 0, gquotaondisk = 0; uint uquotaondisk = 0, gquotaondisk = 0;
...@@ -620,6 +611,7 @@ xfs_mountfs( ...@@ -620,6 +611,7 @@ xfs_mountfs(
__int64_t update_flags; __int64_t update_flags;
int agno, noio; int agno, noio;
int uuid_mounted = 0; int uuid_mounted = 0;
int error = 0;
noio = dev == 0 && mp->m_sb_bp != NULL; noio = dev == 0 && mp->m_sb_bp != NULL;
if (mp->m_sb_bp == NULL) { if (mp->m_sb_bp == NULL) {
...@@ -644,7 +636,8 @@ xfs_mountfs( ...@@ -644,7 +636,8 @@ xfs_mountfs(
if ((BBTOB(mp->m_dalign) & mp->m_blockmask) || if ((BBTOB(mp->m_dalign) & mp->m_blockmask) ||
(BBTOB(mp->m_swidth) & mp->m_blockmask)) { (BBTOB(mp->m_swidth) & mp->m_blockmask)) {
if (mp->m_flags & XFS_MOUNT_RETERR) { if (mp->m_flags & XFS_MOUNT_RETERR) {
cmn_err(CE_WARN, "XFS: alignment check 1 failed"); cmn_err(CE_WARN,
"XFS: alignment check 1 failed");
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error1; goto error1;
} }
...@@ -664,7 +657,8 @@ xfs_mountfs( ...@@ -664,7 +657,8 @@ xfs_mountfs(
mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth); mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth);
} else { } else {
if (mp->m_flags & XFS_MOUNT_RETERR) { if (mp->m_flags & XFS_MOUNT_RETERR) {
cmn_err(CE_WARN, "XFS: alignment check 3 failed"); cmn_err(CE_WARN,
"XFS: alignment check 3 failed");
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error1; goto error1;
} }
...@@ -718,7 +712,8 @@ xfs_mountfs( ...@@ -718,7 +712,8 @@ xfs_mountfs(
* since a single partition filesystem is identical to a single * since a single partition filesystem is identical to a single
* partition volume/filesystem. * partition volume/filesystem.
*/ */
if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { if ((mfsi_flags & XFS_MFSI_SECOND) == 0 &&
(mp->m_flags & XFS_MOUNT_NOUUID) == 0) {
if (xfs_uuid_mount(mp)) { if (xfs_uuid_mount(mp)) {
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error1; goto error1;
...@@ -859,9 +854,6 @@ xfs_mountfs( ...@@ -859,9 +854,6 @@ xfs_mountfs(
return(0); return(0);
} }
/* Initialize the I/O function vector with XFS functions */
mp->m_io_ops = xfs_iocore_xfs;
/* /*
* Copies the low order bits of the timestamp and the randomly * Copies the low order bits of the timestamp and the randomly
* set "sequence" number out of a UUID. * set "sequence" number out of a UUID.
...@@ -1118,6 +1110,7 @@ xfs_mountfs( ...@@ -1118,6 +1110,7 @@ xfs_mountfs(
int int
xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
{ {
struct vfs *vfsp = XFS_MTOVFS(mp);
int ndquots; int ndquots;
#if defined(DEBUG) || defined(INDUCE_IO_ERROR) #if defined(DEBUG) || defined(INDUCE_IO_ERROR)
int64_t fsid; int64_t fsid;
...@@ -1178,14 +1171,14 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) ...@@ -1178,14 +1171,14 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
/* /*
* clear all error tags on this filesystem * clear all error tags on this filesystem
*/ */
memcpy(&fsid, &(XFS_MTOVFS(mp)->vfs_fsid), sizeof(int64_t)); memcpy(&fsid, &vfsp->vfs_fsid, sizeof(int64_t));
(void) xfs_errortag_clearall_umount(fsid, mp->m_fsname, 0); xfs_errortag_clearall_umount(fsid, mp->m_fsname, 0);
#endif #endif
XFS_IODONE(vfsp);
xfs_mount_free(mp, 1); xfs_mount_free(mp, 1);
return 0; return 0;
} }
void void
xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr) xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr)
{ {
......
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -95,7 +95,7 @@ struct flid; ...@@ -95,7 +95,7 @@ struct flid;
struct buf; struct buf;
typedef int (*xfs_ioinit_t)(struct vfs *, typedef int (*xfs_ioinit_t)(struct vfs *,
struct xfs_mount_args *, int *); struct xfs_mount_args *, int);
typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
xfs_fileoff_t, xfs_filblks_t, int, xfs_fileoff_t, xfs_filblks_t, int,
xfs_fsblock_t *, xfs_extlen_t, xfs_fsblock_t *, xfs_extlen_t,
...@@ -187,11 +187,6 @@ typedef struct xfs_ioops { ...@@ -187,11 +187,6 @@ typedef struct xfs_ioops {
(*(mp)->m_io_ops.xfs_iodone)(vfsp) (*(mp)->m_io_ops.xfs_iodone)(vfsp)
/*
* Prototypes and functions for the XFS realtime subsystem.
*/
typedef struct xfs_mount { typedef struct xfs_mount {
bhv_desc_t m_bhv; /* vfs xfs behavior */ bhv_desc_t m_bhv; /* vfs xfs behavior */
xfs_tid_t m_tid; /* next unused tid for fs */ xfs_tid_t m_tid; /* next unused tid for fs */
...@@ -324,8 +319,7 @@ typedef struct xfs_mount { ...@@ -324,8 +319,7 @@ typedef struct xfs_mount {
#define XFS_MOUNT_NOALIGN 0x00000080 /* turn off stripe alignment #define XFS_MOUNT_NOALIGN 0x00000080 /* turn off stripe alignment
allocations */ allocations */
/* 0x00000100 -- currently unused */ /* 0x00000100 -- currently unused */
#define XFS_MOUNT_REGISTERED 0x00000200 /* registered with cxfs master /* 0x00000200 -- currently unused */
cell logic */
#define XFS_MOUNT_NORECOVERY 0x00000400 /* no recovery - dirty fs */ #define XFS_MOUNT_NORECOVERY 0x00000400 /* no recovery - dirty fs */
#define XFS_MOUNT_SHARED 0x00000800 /* shared mount */ #define XFS_MOUNT_SHARED 0x00000800 /* shared mount */
#define XFS_MOUNT_DFLT_IOSIZE 0x00001000 /* set default i/o size */ #define XFS_MOUNT_DFLT_IOSIZE 0x00001000 /* set default i/o size */
...@@ -336,14 +330,6 @@ typedef struct xfs_mount { ...@@ -336,14 +330,6 @@ typedef struct xfs_mount {
* 32 bits in size */ * 32 bits in size */
#define XFS_MOUNT_NOLOGFLUSH 0x00010000 #define XFS_MOUNT_NOLOGFLUSH 0x00010000
/*
* Flags for m_cxfstype
*/
#define XFS_CXFS_NOT 0x00000001 /* local mount */
#define XFS_CXFS_SERVER 0x00000002 /* we're the CXFS server */
#define XFS_CXFS_CLIENT 0x00000004 /* We're a CXFS client */
#define XFS_CXFS_REC_ENABLED 0x00000008 /* recovery is enabled */
#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
/* /*
...@@ -370,15 +356,17 @@ typedef struct xfs_mount { ...@@ -370,15 +356,17 @@ typedef struct xfs_mount {
#define XFS_WSYNC_READIO_LOG 15 /* 32K */ #define XFS_WSYNC_READIO_LOG 15 /* 32K */
#define XFS_WSYNC_WRITEIO_LOG 14 /* 16K */ #define XFS_WSYNC_WRITEIO_LOG 14 /* 16K */
#define xfs_force_shutdown(m,f) VFS_FORCE_SHUTDOWN(XFS_MTOVFS(m),f) #define xfs_force_shutdown(m,f) \
VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
/* /*
* Flags sent to xfs_force_shutdown. * Flags sent to xfs_force_shutdown.
*/ */
#define XFS_METADATA_IO_ERROR 0x1 #define XFS_METADATA_IO_ERROR 0x1
#define XFS_LOG_IO_ERROR 0x2 #define XFS_LOG_IO_ERROR 0x2
#define XFS_FORCE_UMOUNT 0x4 #define XFS_FORCE_UMOUNT 0x4
#define XFS_CORRUPT_INCORE 0x8 /* corrupt in-memory data structures */ #define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */
#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* shutdown came from remote cell */ #define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */
/* /*
* xflags for xfs_syncsub * xflags for xfs_syncsub
...@@ -388,9 +376,7 @@ typedef struct xfs_mount { ...@@ -388,9 +376,7 @@ typedef struct xfs_mount {
/* /*
* Flags for xfs_mountfs * Flags for xfs_mountfs
*/ */
#define XFS_MFSI_SECOND 0x01 /* Is a cxfs secondary mount -- skip */ #define XFS_MFSI_SECOND 0x01 /* Secondary mount -- skip stuff */
/* stuff which should only be done */
/* once. */
#define XFS_MFSI_CLIENT 0x02 /* Is a client -- skip lots of stuff */ #define XFS_MFSI_CLIENT 0x02 /* Is a client -- skip lots of stuff */
#define XFS_MFSI_NOUNLINK 0x08 /* Skip unlinked inode processing in */ #define XFS_MFSI_NOUNLINK 0x08 /* Skip unlinked inode processing in */
/* log recovery */ /* log recovery */
...@@ -410,6 +396,13 @@ xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp); ...@@ -410,6 +396,13 @@ xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp);
#else #else
#define XFS_BHVTOM(bdp) ((xfs_mount_t *)BHV_PDATA(bdp)) #define XFS_BHVTOM(bdp) ((xfs_mount_t *)BHV_PDATA(bdp))
#endif #endif
#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_VFSTOM)
xfs_mount_t *xfs_vfstom(vfs_t *vfs);
#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
#else
#define XFS_VFSTOM(vfs) \
(XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops)))
#endif
/* /*
...@@ -447,7 +440,7 @@ static inline xfs_agblock_t XFS_DADDR_TO_AGBNO(xfs_mount_t *mp, xfs_daddr_t d) ...@@ -447,7 +440,7 @@ static inline xfs_agblock_t XFS_DADDR_TO_AGBNO(xfs_mount_t *mp, xfs_daddr_t d)
*/ */
typedef struct xfs_mod_sb { typedef struct xfs_mod_sb {
xfs_sb_field_t msb_field; /* Field to modify, see below */ xfs_sb_field_t msb_field; /* Field to modify, see below */
int msb_delta; /* change to make to the specified field */ int msb_delta; /* Change to make to specified field */
} xfs_mod_sb_t; } xfs_mod_sb_t;
#define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock), PINOD) #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock), PINOD)
...@@ -455,24 +448,26 @@ typedef struct xfs_mod_sb { ...@@ -455,24 +448,26 @@ typedef struct xfs_mod_sb {
#define XFS_SB_LOCK(mp) mutex_spinlock(&(mp)->m_sb_lock) #define XFS_SB_LOCK(mp) mutex_spinlock(&(mp)->m_sb_lock)
#define XFS_SB_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_sb_lock,(s)) #define XFS_SB_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_sb_lock,(s))
void xfs_mod_sb(xfs_trans_t *, __int64_t); extern xfs_mount_t *xfs_mount_init(void);
xfs_mount_t *xfs_mount_init(void); extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
int xfs_mountfs(struct vfs *, xfs_mount_t *mp, dev_t, int); extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, dev_t, int);
int xfs_unmountfs(xfs_mount_t *, struct cred *); extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
void xfs_unmountfs_close(xfs_mount_t *, struct cred *); extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *);
int xfs_unmountfs_writesb(xfs_mount_t *); extern int xfs_unmountfs_writesb(xfs_mount_t *);
int xfs_unmount_flush(xfs_mount_t *, int); extern int xfs_unmount_flush(xfs_mount_t *, int);
int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int, int); extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int, int);
int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, uint, int); extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
int xfs_readsb(xfs_mount_t *mp); uint, int);
struct xfs_buf *xfs_getsb(xfs_mount_t *, int); extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
void xfs_freesb(xfs_mount_t *); extern int xfs_readsb(xfs_mount_t *mp);
void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); extern void xfs_freesb(xfs_mount_t *);
int xfs_syncsub(xfs_mount_t *, int, int, int *); extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
void xfs_initialize_perag(xfs_mount_t *, int); extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
void xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t, __int64_t); extern void xfs_initialize_perag(xfs_mount_t *, int);
extern void xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t,
__int64_t);
/* /*
* Flags for freeze operations. * Flags for freeze operations.
...@@ -480,11 +475,20 @@ void xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t, __int64_t); ...@@ -480,11 +475,20 @@ void xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t, __int64_t);
#define XFS_FREEZE_WRITE 1 #define XFS_FREEZE_WRITE 1
#define XFS_FREEZE_TRANS 2 #define XFS_FREEZE_TRANS 2
void xfs_start_freeze(xfs_mount_t *, int); extern void xfs_start_freeze(xfs_mount_t *, int);
void xfs_finish_freeze(xfs_mount_t *); extern void xfs_finish_freeze(xfs_mount_t *);
void xfs_check_frozen(xfs_mount_t *, bhv_desc_t *, int); extern void xfs_check_frozen(xfs_mount_t *, bhv_desc_t *, int);
extern struct vfsops xfs_vfsops;
extern struct vnodeops xfs_vnodeops;
extern struct xfs_ioops xfs_iocore_xfs;
extern struct vfsops xfs_qmops_xfs;
extern struct vfsops xfs_dmops_xfs;
extern struct vfsops xfs_vfsops; extern int xfs_init(void);
extern void xfs_cleanup(void);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
/* /*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -199,10 +199,7 @@ extern int xfs_qm_mplist_nowait(xfs_mount_t *); ...@@ -199,10 +199,7 @@ extern int xfs_qm_mplist_nowait(xfs_mount_t *);
extern int xfs_qm_dqhashlock_nowait(xfs_dquot_t *); extern int xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
/* system call interface */ /* system call interface */
extern int linvfs_getxstate(struct super_block *, struct fs_quota_stat *); extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t);
extern int linvfs_setxstate(struct super_block *, unsigned int, int);
extern int linvfs_getxquota(struct super_block *, int, qid_t, struct fs_disk_quota *);
extern int linvfs_setxquota(struct super_block *, int, qid_t, struct fs_disk_quota *);
#ifdef DEBUG #ifdef DEBUG
extern int xfs_qm_internalqcheck(xfs_mount_t *); extern int xfs_qm_internalqcheck(xfs_mount_t *);
......
This diff is collapsed.
/*
* Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
*
* 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
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#include <xfs.h>
#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
#define MNTOPT_NOQUOTA "noquota" /* no quotas */
#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
STATIC int
xfs_qm_parseargs(
struct bhv_desc *bhv,
char *options,
struct xfs_mount_args *args,
int update)
{
size_t length;
char *local_options = options;
char *this_char;
int error;
int referenced = update;
while ((this_char = strsep(&local_options, ",")) != NULL) {
length = strlen(this_char);
if (local_options)
length++;
if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
referenced = update;
} else if (!strcmp(this_char, MNTOPT_QUOTA) ||
!strcmp(this_char, MNTOPT_UQUOTA) ||
!strcmp(this_char, MNTOPT_USRQUOTA)) {
args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
referenced = 1;
} else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
!strcmp(this_char, MNTOPT_UQUOTANOENF)) {
args->flags |= XFSMNT_UQUOTA;
args->flags &= ~XFSMNT_UQUOTAENF;
referenced = 1;
} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
!strcmp(this_char, MNTOPT_GRPQUOTA)) {
args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
referenced = 1;
} else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
args->flags |= XFSMNT_GQUOTA;
args->flags &= ~XFSMNT_GQUOTAENF;
referenced = 1;
} else {
if (local_options)
*(local_options-1) = ',';
continue;
}
while (length--)
*this_char++ = ',';
}
PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
if (!error && !referenced)
bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
return error;
}
STATIC int
xfs_qm_showargs(
struct bhv_desc *bhv,
struct seq_file *m)
{
struct vfs *vfsp = bhvtovfs(bhv);
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
int error;
if (mp->m_qflags & XFS_UQUOTA_ACCT) {
(mp->m_qflags & XFS_UQUOTA_ENFD) ?
seq_puts(m, "," MNTOPT_UQUOTA) :
seq_puts(m, "," MNTOPT_UQUOTANOENF);
}
if (mp->m_qflags & XFS_GQUOTA_ACCT) {
(mp->m_qflags & XFS_GQUOTA_ENFD) ?
seq_puts(m, "," MNTOPT_GQUOTA) :
seq_puts(m, "," MNTOPT_GQUOTANOENF);
}
if (!(mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT)))
seq_puts(m, "," MNTOPT_NOQUOTA);
PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
return error;
}
STATIC int
xfs_qm_mount(
struct bhv_desc *bhv,
struct xfs_mount_args *args,
struct cred *cr)
{
struct vfs *vfsp = bhvtovfs(bhv);
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
int error;
if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA))
xfs_qm_mount_quotainit(mp, args->flags);
PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
return error;
}
STATIC int
xfs_qm_syncall(
struct bhv_desc *bhv,
int flags,
cred_t *credp)
{
struct vfs *vfsp = bhvtovfs(bhv);
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
int error;
/*
* Get the Quota Manager to flush the dquots.
*/
if (XFS_IS_QUOTA_ON(mp)) {
if ((error = xfs_qm_sync(mp, flags))) {
/*
* If we got an IO error, we will be shutting down.
* So, there's nothing more for us to do here.
*/
ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp));
if (XFS_FORCED_SHUTDOWN(mp)) {
return XFS_ERROR(error);
}
}
}
PVFS_SYNC(BHV_NEXT(bhv), flags, credp, error);
return error;
}
vfsops_t xfs_qmops_xfs = {
BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
.vfs_parseargs = xfs_qm_parseargs,
.vfs_showargs = xfs_qm_showargs,
.vfs_mount = xfs_qm_mount,
.vfs_sync = xfs_qm_syncall,
.vfs_quotactl = xfs_qm_quotactl,
};
/* /*
* XFS filesystem operations. * XFS filesystem operations.
* *
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2003 Silicon Graphics, Inc. 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
...@@ -248,9 +248,6 @@ xfs_start_flags( ...@@ -248,9 +248,6 @@ xfs_start_flags(
if (ap->flags & XFSMNT_NOATIME) if (ap->flags & XFSMNT_NOATIME)
mp->m_flags |= XFS_MOUNT_NOATIME; mp->m_flags |= XFS_MOUNT_NOATIME;
if (ap->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA))
xfs_qm_mount_quotainit(mp, ap->flags);
if (ap->flags & XFSMNT_RETERR) if (ap->flags & XFSMNT_RETERR)
mp->m_flags |= XFS_MOUNT_RETERR; mp->m_flags |= XFS_MOUNT_RETERR;
...@@ -387,11 +384,12 @@ xfs_finish_flags( ...@@ -387,11 +384,12 @@ xfs_finish_flags(
*/ */
STATIC int STATIC int
xfs_mount( xfs_mount(
vfs_t *vfsp, struct bhv_desc *bhvp,
struct xfs_mount_args *args, struct xfs_mount_args *args,
cred_t *credp) cred_t *credp)
{ {
xfs_mount_t *mp; struct vfs *vfsp = bhvtovfs(bhvp);
struct xfs_mount *mp = XFS_BHVTOM(bhvp);
struct block_device *ddev, *logdev, *rtdev; struct block_device *ddev, *logdev, *rtdev;
int ronly = (vfsp->vfs_flag & VFS_RDONLY); int ronly = (vfsp->vfs_flag & VFS_RDONLY);
int flags = 0, error; int flags = 0, error;
...@@ -399,24 +397,19 @@ xfs_mount( ...@@ -399,24 +397,19 @@ 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(mp, args->logname, &logdev); error = xfs_blkdev_get(mp, args->logname, &logdev);
if (error) if (error)
goto free_mp; return error;
} }
if (args->rtname[0]) { if (args->rtname[0]) {
error = xfs_blkdev_get(mp, args->rtname, &rtdev); error = xfs_blkdev_get(mp, args->rtname, &rtdev);
if (error) { if (error) {
xfs_blkdev_put(logdev); xfs_blkdev_put(logdev);
goto free_mp; return error;
} }
if (rtdev == ddev || rtdev == logdev) { if (rtdev == ddev || rtdev == logdev) {
...@@ -424,12 +417,11 @@ xfs_mount( ...@@ -424,12 +417,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);
error = EINVAL; return EINVAL;
goto free_mp;
} }
} }
vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp); mp->m_io_ops = xfs_iocore_xfs;
mp->m_ddev_targp = xfs_alloc_buftarg(ddev); mp->m_ddev_targp = xfs_alloc_buftarg(ddev);
if (rtdev) if (rtdev)
...@@ -465,10 +457,8 @@ xfs_mount( ...@@ -465,10 +457,8 @@ xfs_mount(
xfs_setsize_buftarg(mp->m_rtdev_targp, mp->m_sb.sb_blocksize, xfs_setsize_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); if (!(error = XFS_IOINIT(vfsp, args, flags)))
if (error) return 0;
goto error;
return 0;
error: error:
xfs_binval(mp->m_ddev_targp); xfs_binval(mp->m_ddev_targp);
...@@ -479,9 +469,6 @@ xfs_mount( ...@@ -479,9 +469,6 @@ 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);
return error; return error;
} }
...@@ -523,8 +510,9 @@ xfs_ibusy( ...@@ -523,8 +510,9 @@ xfs_ibusy(
continue; continue;
} }
#ifdef DEBUG #ifdef DEBUG
printk("busy vp=0x%p ip=0x%p inum %Ld count=%d\n", cmn_err(CE_WARN, "%s: busy vp=0x%p ip=0x%p "
vp, ip, ip->i_ino, vn_count(vp)); "inum %Ld count=%d",
__FUNCTION__, vp, ip, ip->i_ino, vn_count(vp));
#endif #endif
busy++; busy++;
} }
...@@ -577,7 +565,8 @@ xfs_unmount( ...@@ -577,7 +565,8 @@ xfs_unmount(
*/ */
if (xfs_ibusy(mp)) { if (xfs_ibusy(mp)) {
error = XFS_ERROR(EBUSY); error = XFS_ERROR(EBUSY);
printk("xfs_unmount: xfs_ibusy says error/%d\n", error); cmn_err(CE_ALERT, "%s: xfs_ibusy failed -- error code %d",
__FUNCTION__, error);
goto out; goto out;
} }
...@@ -598,7 +587,7 @@ xfs_unmount( ...@@ -598,7 +587,7 @@ xfs_unmount(
* we want to make sure we invalidate dirty pages that belong to * we want to make sure we invalidate dirty pages that belong to
* referenced vnodes as well. * referenced vnodes as well.
*/ */
if (XFS_FORCED_SHUTDOWN(mp)) { if (XFS_FORCED_SHUTDOWN(mp)) {
error = xfs_sync(&mp->m_bhv, error = xfs_sync(&mp->m_bhv,
(SYNC_WAIT | SYNC_CLOSE), credp); (SYNC_WAIT | SYNC_CLOSE), credp);
ASSERT(error != EFSCORRUPTED); ASSERT(error != EFSCORRUPTED);
...@@ -641,7 +630,7 @@ xfs_unmount_flush( ...@@ -641,7 +630,7 @@ xfs_unmount_flush(
{ {
xfs_inode_t *rip = mp->m_rootip; xfs_inode_t *rip = mp->m_rootip;
xfs_inode_t *rbmip; xfs_inode_t *rbmip;
xfs_inode_t *rsumip=NULL; xfs_inode_t *rsumip = NULL;
vnode_t *rvp = XFS_ITOV(rip); vnode_t *rvp = XFS_ITOV(rip);
int error; int error;
...@@ -675,18 +664,17 @@ xfs_unmount_flush( ...@@ -675,18 +664,17 @@ xfs_unmount_flush(
} }
/* /*
* synchronously flush root inode to disk * Synchronously flush root inode to disk
*/ */
error = xfs_iflush(rip, XFS_IFLUSH_SYNC); error = xfs_iflush(rip, XFS_IFLUSH_SYNC);
if (error == EFSCORRUPTED) if (error == EFSCORRUPTED)
goto fscorrupt_out2; goto fscorrupt_out2;
if (vn_count(rvp) != 1 && !relocation) { if (vn_count(rvp) != 1 && !relocation) {
xfs_iunlock(rip, XFS_ILOCK_EXCL); xfs_iunlock(rip, XFS_ILOCK_EXCL);
error = XFS_ERROR(EBUSY); return XFS_ERROR(EBUSY);
return (error);
} }
/* /*
* Release dquot that rootinode, rbmino and rsumino might be holding, * Release dquot that rootinode, rbmino and rsumino might be holding,
* flush and purge the quota inodes. * flush and purge the quota inodes.
...@@ -701,7 +689,7 @@ xfs_unmount_flush( ...@@ -701,7 +689,7 @@ xfs_unmount_flush(
} }
xfs_iunlock(rip, XFS_ILOCK_EXCL); xfs_iunlock(rip, XFS_ILOCK_EXCL);
return (0); return 0;
fscorrupt_out: fscorrupt_out:
xfs_ifunlock(rip); xfs_ifunlock(rip);
...@@ -709,8 +697,7 @@ xfs_unmount_flush( ...@@ -709,8 +697,7 @@ xfs_unmount_flush(
fscorrupt_out2: fscorrupt_out2:
xfs_iunlock(rip, XFS_ILOCK_EXCL); xfs_iunlock(rip, XFS_ILOCK_EXCL);
error = XFS_ERROR(EFSCORRUPTED); return XFS_ERROR(EFSCORRUPTED);
return (error);
} }
/* /*
...@@ -725,12 +712,11 @@ xfs_root( ...@@ -725,12 +712,11 @@ xfs_root(
bhv_desc_t *bdp, bhv_desc_t *bdp,
vnode_t **vpp) vnode_t **vpp)
{ {
vnode_t *vp; vnode_t *vp;
vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip); vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip);
VN_HOLD(vp); VN_HOLD(vp);
*vpp = vp; *vpp = vp;
return 0; return 0;
} }
...@@ -1410,23 +1396,6 @@ xfs_syncsub( ...@@ -1410,23 +1396,6 @@ xfs_syncsub(
ASSERT(ipointer_in == B_FALSE); ASSERT(ipointer_in == B_FALSE);
/*
* Get the Quota Manager to flush the dquots in a similar manner.
*/
if (XFS_IS_QUOTA_ON(mp)) {
if ((error = xfs_qm_sync(mp, flags))) {
/*
* If we got an IO error, we will be shutting down.
* So, there's nothing more for us to do here.
*/
ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp));
if (XFS_FORCED_SHUTDOWN(mp)) {
kmem_free(ipointer, sizeof(xfs_iptr_t));
return XFS_ERROR(error);
}
}
}
/* /*
* Flushing out dirty data above probably generated more * Flushing out dirty data above probably generated more
* log activity, so if this isn't vfs_sync() then flush * log activity, so if this isn't vfs_sync() then flush
...@@ -1581,16 +1550,17 @@ xfs_vget( ...@@ -1581,16 +1550,17 @@ xfs_vget(
vfsops_t xfs_vfsops = { vfsops_t xfs_vfsops = {
BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
.vfs_parseargs = xfs_parseargs,
.vfs_showargs = xfs_showargs,
.vfs_mount = xfs_mount, .vfs_mount = xfs_mount,
.vfs_unmount = xfs_unmount, .vfs_unmount = xfs_unmount,
.vfs_root = xfs_root, .vfs_root = xfs_root,
.vfs_statvfs = xfs_statvfs, .vfs_statvfs = xfs_statvfs,
.vfs_sync = xfs_sync, .vfs_sync = xfs_sync,
.vfs_vget = xfs_vget, .vfs_vget = xfs_vget,
.vfs_dmapiops = (vfs_dmapiops_t)fs_nosys,
.vfs_quotactl = (vfs_quotactl_t)fs_nosys,
.vfs_init_vnode = xfs_initialize_vnode, .vfs_init_vnode = xfs_initialize_vnode,
.vfs_force_shutdown = xfs_do_force_shutdown, .vfs_force_shutdown = xfs_do_force_shutdown,
#ifdef CONFIG_XFS_DMAPI
.vfs_dmapi_mount = xfs_dm_mount,
.vfs_dmapi_fsys_vector = xfs_dm_get_fsys_vector,
#endif
}; };
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