summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@hera.kernel.org>2003-03-25 19:36:46 -0800
committerChristoph Hellwig <hch@hera.kernel.org>2003-03-25 19:36:46 -0800
commit04792016b3cd1b65b5015cc8df824191b3f41afe (patch)
treeb3bcb92ae8ad7119112e2dd6ac16775c8b102ab4
parent5ec5104a85efc102b0e6e0f3f07772bcbb2b1e96 (diff)
parentfec5b07586911d63f8cc2ae1741ab985fc7e9f5d (diff)
Merge
-rw-r--r--fs/xfs/Makefile30
-rw-r--r--fs/xfs/linux/xfs_aops.c2
-rw-r--r--fs/xfs/linux/xfs_behavior.c125
-rw-r--r--fs/xfs/linux/xfs_behavior.h20
-rw-r--r--fs/xfs/linux/xfs_file.c10
-rw-r--r--fs/xfs/linux/xfs_globals.c16
-rw-r--r--fs/xfs/linux/xfs_globals.h9
-rw-r--r--fs/xfs/linux/xfs_ioctl.c4
-rw-r--r--fs/xfs/linux/xfs_iomap.c34
-rw-r--r--fs/xfs/linux/xfs_linux.h12
-rw-r--r--fs/xfs/linux/xfs_lrw.c51
-rw-r--r--fs/xfs/linux/xfs_stats.c36
-rw-r--r--fs/xfs/linux/xfs_stats.h11
-rw-r--r--fs/xfs/linux/xfs_super.c555
-rw-r--r--fs/xfs/linux/xfs_super.h42
-rw-r--r--fs/xfs/linux/xfs_vfs.c285
-rw-r--r--fs/xfs/linux/xfs_vfs.h280
-rw-r--r--fs/xfs/linux/xfs_vnode.c81
-rw-r--r--fs/xfs/linux/xfs_vnode.h172
-rw-r--r--fs/xfs/pagebuf/page_buf.c12
-rw-r--r--fs/xfs/pagebuf/page_buf.h1
-rw-r--r--fs/xfs/quota/xfs_dquot.c (renamed from fs/xfs/xfs_dquot.c)214
-rw-r--r--fs/xfs/quota/xfs_dquot.h (renamed from fs/xfs/xfs_dquot.h)12
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c (renamed from fs/xfs/xfs_dquot_item.c)4
-rw-r--r--fs/xfs/quota/xfs_dquot_item.h (renamed from fs/xfs/xfs_dquot_item.h)52
-rw-r--r--fs/xfs/quota/xfs_qm.c (renamed from fs/xfs/xfs_qm.c)248
-rw-r--r--fs/xfs/quota/xfs_qm.h (renamed from fs/xfs/xfs_qm.h)76
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c379
-rw-r--r--fs/xfs/quota/xfs_qm_stats.c117
-rw-r--r--fs/xfs/quota/xfs_qm_stats.h68
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c (renamed from fs/xfs/xfs_qm_syscalls.c)262
-rw-r--r--fs/xfs/quota/xfs_quota_priv.h (renamed from fs/xfs/xfs_quota_priv.h)6
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c (renamed from fs/xfs/xfs_trans_dquot.c)84
-rw-r--r--fs/xfs/support/atomic.h10
-rw-r--r--fs/xfs/support/debug.c6
-rw-r--r--fs/xfs/support/mrlock.c14
-rw-r--r--fs/xfs/support/mrlock.h8
-rw-r--r--fs/xfs/support/mutex.h3
-rw-r--r--fs/xfs/support/time.h6
-rw-r--r--fs/xfs/xfs.h12
-rw-r--r--fs/xfs/xfs_attr.c35
-rw-r--r--fs/xfs/xfs_bmap.c149
-rw-r--r--fs/xfs/xfs_bmap.h6
-rw-r--r--fs/xfs/xfs_bmap_btree.c30
-rw-r--r--fs/xfs/xfs_buf.h5
-rw-r--r--fs/xfs/xfs_clnt.h29
-rw-r--r--fs/xfs/xfs_dmapi.h215
-rw-r--r--fs/xfs/xfs_dmops.c42
-rw-r--r--fs/xfs/xfs_dqblk.h99
-rw-r--r--fs/xfs/xfs_iget.c11
-rw-r--r--fs/xfs/xfs_inode.c36
-rw-r--r--fs/xfs/xfs_inode.h8
-rw-r--r--fs/xfs/xfs_iocore.c24
-rw-r--r--fs/xfs/xfs_log_recover.c137
-rw-r--r--fs/xfs/xfs_macros.c10
-rw-r--r--fs/xfs/xfs_mount.c233
-rw-r--r--fs/xfs/xfs_mount.h229
-rw-r--r--fs/xfs/xfs_qmops.c60
-rw-r--r--fs/xfs/xfs_quota.h364
-rw-r--r--fs/xfs/xfs_rename.c16
-rw-r--r--fs/xfs/xfs_rtalloc.h4
-rw-r--r--fs/xfs/xfs_trans.c25
-rw-r--r--fs/xfs/xfs_trans.h4
-rw-r--r--fs/xfs/xfs_utils.c4
-rw-r--r--fs/xfs/xfs_vfsops.c124
-rw-r--r--fs/xfs/xfs_vnodeops.c449
-rw-r--r--fs/xfs/xfsidbg.c31
67 files changed, 3038 insertions, 2710 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 93afc0a65581..738ebec594dc 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -1,5 +1,5 @@
#
-# 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
# under the terms of version 2 of the GNU General Public License as
@@ -29,13 +29,7 @@
#
# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
#
-# 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
ifeq ($(CONFIG_XFS_DEBUG),y)
@@ -48,17 +42,22 @@ endif
obj-$(CONFIG_XFS_FS) += xfs.o
-xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
-
-xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \
+xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \
+ xfs_dquot.o \
xfs_dquot_item.o \
xfs_trans_dquot.o \
xfs_qm_syscalls.o \
- xfs_qm.o
+ xfs_qm_bhv.o \
+ xfs_qm.o)
+ifeq ($(CONFIG_XFS_QUOTA),y)
+xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o
+endif
+
+xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
-xfs-$(CONFIG_FS_POSIX_CAP) += xfs_cap.o
-xfs-$(CONFIG_FS_POSIX_MAC) += xfs_mac.o
+xfs-$(CONFIG_XFS_POSIX_CAP) += xfs_cap.o
+xfs-$(CONFIG_XFS_POSIX_MAC) += xfs_mac.o
xfs-$(CONFIG_PROC_FS) += linux/xfs_stats.o
xfs-$(CONFIG_SYSCTL) += linux/xfs_sysctl.o
@@ -127,6 +126,7 @@ xfs-y += $(addprefix linux/, \
xfs_iops.o \
xfs_lrw.o \
xfs_super.o \
+ xfs_vfs.o \
xfs_vnode.o)
# Objects in support/
@@ -139,6 +139,10 @@ xfs-y += $(addprefix support/, \
qsort.o \
uuid.o)
+# Quota and DMAPI stubs
+xfs-y += xfs_dmops.o \
+ xfs_qmops.o
+
# If both xfs and kdb modules are built in then xfsidbg is built in. If xfs is
# a module and kdb modules are being compiled then xfsidbg must be a module, to
# follow xfs. If xfs is built in then xfsidbg tracks the kdb module state.
diff --git a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c
index 75a9e1aa1e8e..3c33d98a7bbd 100644
--- a/fs/xfs/linux/xfs_aops.c
+++ b/fs/xfs/linux/xfs_aops.c
@@ -78,6 +78,7 @@ xfs_unwritten_conv(
XFS_BUF_OFFSET(bp), XFS_BUF_SIZE(bp));
XFS_BUF_SET_FSPRIVATE(bp, NULL);
XFS_BUF_CLR_IODONE_FUNC(bp);
+ XFS_BUF_UNDATAIO(bp);
xfs_biodone(bp);
}
@@ -431,6 +432,7 @@ map_unwritten(
size = nblocks; /* NB: using 64bit number here */
size <<= block_bits; /* convert fsb's to byte range */
+ XFS_BUF_DATAIO(pb);
XFS_BUF_SET_SIZE(pb, size);
XFS_BUF_SET_OFFSET(pb, offset);
XFS_BUF_SET_FSPRIVATE(pb, LINVFS_GET_VP(inode)->v_fbhv);
diff --git a/fs/xfs/linux/xfs_behavior.c b/fs/xfs/linux/xfs_behavior.c
index 9147a57c5ffa..b69fb1d94c28 100644
--- a/fs/xfs/linux/xfs_behavior.c
+++ b/fs/xfs/linux/xfs_behavior.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -30,41 +30,77 @@
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*
*/
+#include <xfs.h>
/*
* 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
- * 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
-bhv_global_init(void)
+int
+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
- * 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.
+ * Find location to insert behavior. Check for duplicates.
*/
- 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;
* the postition is guaranteed not to be the first position.
* 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
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);
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)
}
/*
- * Look for a specific ops vector on the specified behavior chain.
- * Return the associated behavior descriptor. Or NULL, if not found.
- *
- * The caller has not read locked the behavior chain, so acquire the
- * lock before traversing the chain.
+ * Looks for the first behavior within a specified range of positions.
+ * Return the associated behavior descriptor. Or NULL, if none found.
*/
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)
* lock before traversing the chain.
*/
bhv_desc_t *
-bhv_base_unlocked(bhv_head_t *bhp)
+bhv_base(bhv_head_t *bhp)
{
bhv_desc_t *curdesc;
for (curdesc = bhp->bh_first;
curdesc != NULL;
curdesc = curdesc->bd_next) {
- if (curdesc->bd_next == NULL)
+
+ if (curdesc->bd_next == NULL) {
return curdesc;
+ }
}
+
return NULL;
}
-#define BHVMAGIC (void *)0xf00d
-
-/* ARGSUSED */
void
bhv_head_init(
bhv_head_t *bhp,
char *name)
{
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
bhv_insert_initial(
bhv_head_t *bhp,
bhv_desc_t *bdp)
{
ASSERT(bhp->bh_first == NULL);
- ASSERT(bhp->bh_lockp == BHVMAGIC);
(bhp)->bh_first = bdp;
}
@@ -185,7 +215,4 @@ bhv_head_destroy(
bhv_head_t *bhp)
{
ASSERT(bhp->bh_first == NULL);
- ASSERT(bhp->bh_lockp == BHVMAGIC);
- bhp->bh_lockp = NULL;
}
-
diff --git a/fs/xfs/linux/xfs_behavior.h b/fs/xfs/linux/xfs_behavior.h
index fd165e527c8f..bae4c9359810 100644
--- a/fs/xfs/linux/xfs_behavior.h
+++ b/fs/xfs/linux/xfs_behavior.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -91,8 +91,8 @@
* active object
*
*/
-
-typedef void bhv_head_lock_t;
+
+struct bhv_head_lock;
/*
* Behavior head. Head of the chain of behaviors.
@@ -100,7 +100,7 @@ typedef void bhv_head_lock_t;
*/
typedef struct bhv_head {
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;
/*
@@ -128,10 +128,8 @@ typedef struct bhv_identity {
typedef bhv_identity_t bhv_position_t;
#define BHV_IDENTITY_INIT(id,pos) {id, pos}
-
#define BHV_IDENTITY_INIT_POSITION(pos) BHV_IDENTITY_INIT(0, pos)
-
/*
* Define boundaries of position values.
*/
@@ -154,7 +152,7 @@ typedef bhv_identity_t bhv_position_t;
extern void bhv_head_init(bhv_head_t *, char *);
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 *);
/*
@@ -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 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_base_unlocked(bhv_head_t *bhp);
+extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high);
+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__ */
diff --git a/fs/xfs/linux/xfs_file.c b/fs/xfs/linux/xfs_file.c
index 25d6df57e0ab..0331e582c830 100644
--- a/fs/xfs/linux/xfs_file.c
+++ b/fs/xfs/linux/xfs_file.c
@@ -299,7 +299,9 @@ linvfs_file_mmap(
int error;
if ((vp->v_type == VREG) && (vp->v_vfsp->vfs_flag & VFS_DMI)) {
- error = -xfs_dm_send_mmap_event(vma, 0);
+ xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
+
+ error = -XFS_SEND_MMAP(mp, vma, 0);
if (error)
return error;
}
@@ -345,8 +347,10 @@ linvfs_mprotect(
if ((vp->v_type == VREG) && (vp->v_vfsp->vfs_flag & VFS_DMI)) {
if ((vma->vm_flags & VM_MAYSHARE) &&
- (newflags & PROT_WRITE) && !(vma->vm_flags & PROT_WRITE)){
- error = xfs_dm_send_mmap_event(vma, VM_WRITE);
+ (newflags & PROT_WRITE) && !(vma->vm_flags & PROT_WRITE)) {
+ xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
+
+ error = XFS_SEND_MMAP(mp, vma, VM_WRITE);
}
}
return error;
diff --git a/fs/xfs/linux/xfs_globals.c b/fs/xfs/linux/xfs_globals.c
index 40fd5618f100..21ac11aecd99 100644
--- a/fs/xfs/linux/xfs_globals.c
+++ b/fs/xfs/linux/xfs_globals.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -40,7 +40,7 @@
/*
* System memory size - used to scale certain data structures in XFS.
*/
-unsigned long xfs_physmem;
+unsigned long xfs_physmem;
/*
* Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n,
@@ -51,24 +51,14 @@ xfs_param_t xfs_params = { 0, 1, 0, 0, 0, 3 };
/*
* Used to serialize atomicIncWithWrap.
*/
-spinlock_t Atomic_spin = SPIN_LOCK_UNLOCKED;
+spinlock_t xfs_atomic_spin = SPIN_LOCK_UNLOCKED;
/*
* Global system credential structure.
*/
cred_t sys_cred_val, *sys_cred = &sys_cred_val;
-/*
- * The global quota manager. There is only one of these for the entire
- * system, _not_ one per file system. XQM keeps track of the overall
- * quota functionality, including maintaining the freelist and hash
- * tables of dquots.
- */
-struct xfs_qm *xfs_Gqm;
-mutex_t xfs_Gqm_lock;
-
/* Export XFS symbols used by xfsidbg */
-EXPORT_SYMBOL(xfs_Gqm);
EXPORT_SYMBOL(xfs_next_bit);
EXPORT_SYMBOL(xfs_contig_bits);
EXPORT_SYMBOL(xfs_bmbt_get_all);
diff --git a/fs/xfs/linux/xfs_globals.h b/fs/xfs/linux/xfs_globals.h
index 07c9856b1353..190e0717617c 100644
--- a/fs/xfs/linux/xfs_globals.h
+++ b/fs/xfs/linux/xfs_globals.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -39,11 +39,10 @@
extern uint64_t xfs_panic_mask; /* set to cause more panics */
-extern unsigned long xfs_physmem;
+extern unsigned long xfs_physmem;
-extern struct cred *sys_cred;
+extern spinlock_t xfs_atomic_spin;
-extern struct xfs_qm *xfs_Gqm;
-extern mutex_t xfs_Gqm_lock;
+extern struct cred *sys_cred;
#endif /* __XFS_GLOBALS_H__ */
diff --git a/fs/xfs/linux/xfs_ioctl.c b/fs/xfs/linux/xfs_ioctl.c
index f411729ca11e..b0dd066307dc 100644
--- a/fs/xfs/linux/xfs_ioctl.c
+++ b/fs/xfs/linux/xfs_ioctl.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -130,7 +130,7 @@ xfs_find_handle(
int lock_mode;
/* 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);
ip = XFS_BHVTOI(bhv);
ASSERT(ip);
diff --git a/fs/xfs/linux/xfs_iomap.c b/fs/xfs/linux/xfs_iomap.c
index cc1ab771ede0..a96e2141e141 100644
--- a/fs/xfs/linux/xfs_iomap.c
+++ b/fs/xfs/linux/xfs_iomap.c
@@ -258,11 +258,10 @@ xfs_iomap_write_direct(
* the ilock across a disk read.
*/
- if (XFS_IS_QUOTA_ON(mp) && XFS_NOT_DQATTACHED(mp, ip)) {
- if ((error = xfs_qm_dqattach(ip, XFS_QMOPT_ILOCKED))) {
- return XFS_ERROR(error);
- }
- }
+ error = XFS_QM_DQATTACH(ip->i_mount, ip, XFS_QMOPT_ILOCKED);
+ if (error)
+ return XFS_ERROR(error);
+
maps = min(XFS_WRITE_IMAPS, *nmaps);
nimaps = maps;
@@ -291,7 +290,7 @@ xfs_iomap_write_direct(
* determine if reserving space on
* the data or realtime partition.
*/
- if ((rt = ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
+ if ((rt = XFS_IS_REALTIME_INODE(ip))) {
int sbrtextsize, iprtextsize;
sbrtextsize = mp->m_sb.sb_rextsize;
@@ -333,11 +332,9 @@ xfs_iomap_write_direct(
goto error_out; /* Don't return in above if .. trans ..,
need lock to return */
- if (XFS_IS_QUOTA_ON(mp)) {
- if (xfs_trans_reserve_blkquota(tp, ip, resblks)) {
- error = (EDQUOT);
- goto error1;
- }
+ if (XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, resblks)) {
+ error = (EDQUOT);
+ goto error1;
}
nimaps = 1;
@@ -422,11 +419,9 @@ xfs_iomap_write_delay(
* the ilock across a disk read.
*/
- if (XFS_IS_QUOTA_ON(mp) && XFS_NOT_DQATTACHED(mp, ip)) {
- if ((error = xfs_qm_dqattach(ip, XFS_QMOPT_ILOCKED))) {
- return XFS_ERROR(error);
- }
- }
+ error = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED);
+ if (error)
+ return XFS_ERROR(error);
retry:
isize = ip->i_d.di_size;
@@ -538,11 +533,8 @@ xfs_iomap_write_allocate(
* Make sure that the dquots are there.
*/
- if (XFS_IS_QUOTA_ON(mp) && XFS_NOT_DQATTACHED(mp, ip)) {
- if ((error = xfs_qm_dqattach(ip, 0))) {
- return XFS_ERROR(error);
- }
- }
+ if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
+ return XFS_ERROR(error);
offset_fsb = map->br_startoff;
count_fsb = map->br_blockcount;
diff --git a/fs/xfs/linux/xfs_linux.h b/fs/xfs/linux/xfs_linux.h
index bd6434eb8c7a..aba0b1fdf2dc 100644
--- a/fs/xfs/linux/xfs_linux.h
+++ b/fs/xfs/linux/xfs_linux.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -44,6 +44,7 @@
#include <linux/major.h>
#include <linux/pagemap.h>
#include <linux/vfs.h>
+#include <linux/seq_file.h>
#include <asm/page.h>
#include <asm/div64.h>
@@ -160,6 +161,15 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
#define SYNCHRONIZE() barrier()
#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) */
/* we may well need to fine-tune this if it ever becomes an issue. */
#define DQUOT_MAX_HEURISTIC 1024 /* NR_DQUOTS */
diff --git a/fs/xfs/linux/xfs_lrw.c b/fs/xfs/linux/xfs_lrw.c
index 214ac45c2485..2ee9f08d8721 100644
--- a/fs/xfs/linux/xfs_lrw.c
+++ b/fs/xfs/linux/xfs_lrw.c
@@ -121,7 +121,8 @@ xfs_read(
xfs_mount_t *mp;
vnode_t *vp;
unsigned long seg;
- int direct = filp->f_flags & O_DIRECT;
+ int direct = (filp->f_flags & O_DIRECT);
+ int invisible = (filp->f_mode & FINVIS);
ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp);
@@ -180,13 +181,12 @@ xfs_read(
xfs_ilock(ip, XFS_IOLOCK_SHARED);
- if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
- !(filp->f_mode & FINVIS)) {
+ if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && !invisible) {
int error;
vrwlock_t locktype = VRWLOCK_READ;
- error = xfs_dm_send_data_event(DM_EVENT_READ, bdp, *offp,
- size, FILP_DELAY_FLAG(filp), &locktype);
+ error = XFS_SEND_DATA(mp, DM_EVENT_READ, bdp, *offp, size,
+ FILP_DELAY_FLAG(filp), &locktype);
if (error) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
return -error;
@@ -198,7 +198,7 @@ xfs_read(
XFS_STATS_ADD(xfsstats.xs_read_bytes, ret);
- if (!(filp->f_mode & FINVIS))
+ if (!invisible)
xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
return ret;
@@ -217,11 +217,13 @@ xfs_sendfile(
ssize_t ret;
xfs_fsize_t n;
xfs_inode_t *ip;
+ xfs_mount_t *mp;
vnode_t *vp;
int invisible = (filp->f_mode & FINVIS);
ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp);
+ mp = ip->i_mount;
vn_trace_entry(vp, "xfs_sendfile", (inst_t *)__return_address);
XFS_STATS_INC(xfsstats.xs_read_calls);
@@ -241,8 +243,8 @@ xfs_sendfile(
vrwlock_t locktype = VRWLOCK_READ;
int error;
- error = xfs_dm_send_data_event(DM_EVENT_READ, bdp, *offp,
- count, FILP_DELAY_FLAG(filp), &locktype);
+ error = XFS_SEND_DATA(mp, DM_EVENT_READ, bdp, *offp, count,
+ FILP_DELAY_FLAG(filp), &locktype);
if (error) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
return -error;
@@ -493,7 +495,8 @@ xfs_write(
vnode_t *vp;
unsigned long seg;
int iolock;
- int direct = file->f_flags & O_DIRECT;
+ int direct = (file->f_flags & O_DIRECT);
+ int invisible = (file->f_mode & FINVIS);
int eventsent = 0;
vrwlock_t locktype;
@@ -573,13 +576,13 @@ start:
}
if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
- !(file->f_mode & FINVIS) && !eventsent)) {
+ !invisible && !eventsent)) {
loff_t savedsize = *offset;
xfs_iunlock(xip, XFS_ILOCK_EXCL);
- error = xfs_dm_send_data_event(DM_EVENT_WRITE, bdp,
- *offset, size,
- FILP_DELAY_FLAG(file), &locktype);
+ error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, bdp,
+ *offset, size,
+ FILP_DELAY_FLAG(file), &locktype);
if (error) {
xfs_iunlock(xip, iolock);
return -error;
@@ -588,12 +591,11 @@ start:
eventsent = 1;
/*
- * The iolock was dropped and reaquired in
- * xfs_dm_send_data_event so we have to recheck the size
- * when appending. We will only "goto start;" once,
- * since having sent the event prevents another call
- * to xfs_dm_send_data_event, which is what
- * allows the size to change in the first place.
+ * The iolock was dropped and reaquired in XFS_SEND_DATA
+ * so we have to recheck the size when appending.
+ * We will only "goto start;" once, since having sent the
+ * event prevents another call to XFS_SEND_DATA, which is
+ * what allows the size to change in the first place.
*/
if ((file->f_flags & O_APPEND) &&
savedsize != xip->i_d.di_size) {
@@ -608,10 +610,8 @@ start:
*
* We must update xfs' times since revalidate will overcopy xfs.
*/
- if (size) {
- if (!(file->f_mode & FINVIS))
- xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- }
+ if (size && !invisible)
+ xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
/*
* If the offset is beyond the size of the file, we have a couple
@@ -658,11 +658,10 @@ retry:
ret = generic_file_write_nolock(file, iovp, segs, offset);
if ((ret == -ENOSPC) &&
- DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) &&
- !(file->f_mode & FINVIS)) {
+ DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) && !invisible) {
xfs_rwunlock(bdp, locktype);
- error = dm_send_namesp_event(DM_EVENT_NOSPACE, bdp,
+ error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, bdp,
DM_RIGHT_NULL, bdp, DM_RIGHT_NULL, NULL, NULL,
0, 0, 0); /* Delay flag intentionally unused */
if (error)
diff --git a/fs/xfs/linux/xfs_stats.c b/fs/xfs/linux/xfs_stats.c
index 578d5bb0b4cf..5face9af532b 100644
--- a/fs/xfs/linux/xfs_stats.c
+++ b/fs/xfs/linux/xfs_stats.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2001 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
* under the terms of version 2 of the GNU General Public License as
@@ -61,7 +61,6 @@ xfs_read_xfsstats(
{ "xstrat", XFSSTAT_END_WRITE_CONVERT },
{ "rw", XFSSTAT_END_READ_WRITE_OPS },
{ "attr", XFSSTAT_END_ATTRIBUTE_OPS },
- { "qm", XFSSTAT_END_QUOTA_OPS },
{ "icluster", XFSSTAT_END_INODE_CLUSTER },
{ "vnodes", XFSSTAT_END_VNODE_OPS },
};
@@ -95,50 +94,17 @@ xfs_read_xfsstats(
return len;
}
-STATIC int
-xfs_read_xfsquota(
- char *buffer,
- char **start,
- off_t offset,
- int count,
- int *eof,
- void *data)
-{
- int len;
-
- /* maximum; incore; ratio free to inuse; freelist */
- len = sprintf(buffer, "%d\t%d\t%d\t%u\n",
- ndquot,
- xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0,
- xfs_Gqm? xfs_Gqm->qm_dqfree_ratio : 0,
- xfs_Gqm? xfs_Gqm->qm_dqfreelist.qh_nelems : 0);
-
- if (offset >= len) {
- *start = buffer;
- *eof = 1;
- return 0;
- }
- *start = buffer + offset;
- if ((len -= offset) > count)
- return count;
- *eof = 1;
-
- return len;
-}
-
void
xfs_init_procfs(void)
{
if (!proc_mkdir("fs/xfs", 0))
return;
create_proc_read_entry("fs/xfs/stat", 0, 0, xfs_read_xfsstats, NULL);
- create_proc_read_entry("fs/xfs/xqm", 0, 0, xfs_read_xfsquota, NULL);
}
void
xfs_cleanup_procfs(void)
{
remove_proc_entry("fs/xfs/stat", NULL);
- remove_proc_entry("fs/xfs/xqm", NULL);
remove_proc_entry("fs/xfs", NULL);
}
diff --git a/fs/xfs/linux/xfs_stats.h b/fs/xfs/linux/xfs_stats.h
index c4192e35482b..c5eb3b848c5a 100644
--- a/fs/xfs/linux/xfs_stats.h
+++ b/fs/xfs/linux/xfs_stats.h
@@ -107,16 +107,7 @@ struct xfsstats {
__uint32_t xs_attr_set;
__uint32_t xs_attr_remove;
__uint32_t xs_attr_list;
-# define XFSSTAT_END_QUOTA_OPS (XFSSTAT_END_ATTRIBUTE_OPS+8)
- __uint32_t xs_qm_dqreclaims;
- __uint32_t xs_qm_dqreclaim_misses;
- __uint32_t xs_qm_dquot_dups;
- __uint32_t xs_qm_dqcachemisses;
- __uint32_t xs_qm_dqcachehits;
- __uint32_t xs_qm_dqwants;
- __uint32_t xs_qm_dqshake_reclaims;
- __uint32_t xs_qm_dqinact_reclaims;
-# define XFSSTAT_END_INODE_CLUSTER (XFSSTAT_END_QUOTA_OPS+3)
+# define XFSSTAT_END_INODE_CLUSTER (XFSSTAT_END_ATTRIBUTE_OPS+3)
__uint32_t xs_iflush_count;
__uint32_t xs_icluster_flushcnt;
__uint32_t xs_icluster_flushinode;
diff --git a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c
index 58d5aea9bd2a..161c8f64b4c2 100644
--- a/fs/xfs/linux/xfs_super.c
+++ b/fs/xfs/linux/xfs_super.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -31,107 +31,68 @@
*/
#include <xfs.h>
-#include <linux/bitops.h>
#include <linux/blkdev.h>
#include <linux/namei.h>
-#include <linux/pagemap.h>
-#include <linux/major.h>
#include <linux/init.h>
-#include <linux/ctype.h>
-#include <linux/seq_file.h>
#include <linux/mount.h>
#include "xfs_version.h"
-/* xfs_vfs[ops].c */
-extern int xfs_init(void);
-extern void xfs_cleanup(void);
-
-/* For kernels which have the s_maxbytes field - set it */
-#ifdef MAX_NON_LFS
-# define set_max_bytes(sb) ((sb)->s_maxbytes = XFS_MAX_FILE_OFFSET)
-#else
-# define set_max_bytes(sb) do { } while (0)
-#endif
-
-#ifdef CONFIG_XFS_POSIX_ACL
-# define set_posix_acl(sb) ((sb)->s_flags |= MS_POSIXACL)
-#else
-# define set_posix_acl(sb) do { } while (0)
-#endif
-
-#ifdef CONFIG_XFS_QUOTA
-STATIC struct quotactl_ops linvfs_qops = {
- .get_xstate = linvfs_getxstate,
- .set_xstate = linvfs_setxstate,
- .get_xquota = linvfs_getxquota,
- .set_xquota = linvfs_setxquota,
-};
-# define set_quota_ops(sb) ((sb)->s_qcop = &linvfs_qops)
-#else
-# define set_quota_ops(sb) do { } while (0)
-#endif
-
-#ifdef CONFIG_XFS_DMAPI
-int dmapi_init(void);
-void dmapi_uninit(void);
-#else
-#define dmapi_init()
-#define dmapi_uninit()
-#endif
-
+STATIC struct quotactl_ops linvfs_qops;
STATIC struct super_operations linvfs_sops;
STATIC struct export_operations linvfs_export_ops;
+STATIC kmem_cache_t * linvfs_inode_cachep;
#define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */
-#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */
+#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */
#define MNTOPT_LOGDEV "logdev" /* log device */
#define MNTOPT_RTDEV "rtdev" /* realtime I/O device */
-#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
-#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
#define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */
#define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */
#define MNTOPT_INO64 "ino64" /* force inodes into 64-bit range */
#define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */
#define MNTOPT_SUNIT "sunit" /* data volume stripe unit */
#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
-#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
-#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
-#define MNTOPT_QUOTA "quota" /* disk quotas */
-#define MNTOPT_NOQUOTA "noquota" /* no quotas */
-#define MNTOPT_UQUOTA "usrquota" /* user quota enabled */
-#define MNTOPT_GQUOTA "grpquota" /* group quota enabled */
-#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
-#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
-#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
-#define MNTOPT_NOUUID "nouuid" /* Ignore FS uuid */
-#define MNTOPT_NOLOGFLUSH "nologflush" /* Don't use hard flushes in
- log writing */
+#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
+#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
+#define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */
+#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
-STATIC int
+STATIC struct xfs_mount_args *
+args_allocate(
+ struct super_block *sb)
+{
+ struct xfs_mount_args *args;
+
+ args = kmem_zalloc(sizeof(struct xfs_mount_args), KM_SLEEP);
+ args->logbufs = args->logbufsize = -1;
+ strncpy(args->fsname, sb->s_id, MAXNAMELEN);
+
+ /* Copy the already-parsed mount(2) flags we're interested in */
+ if (sb->s_flags & MS_NOATIME)
+ args->flags |= XFSMNT_NOATIME;
+
+ /* Default to 32 bit inodes on Linux all the time */
+ args->flags |= XFSMNT_32BITINODES;
+
+ return args;
+}
+
+int
xfs_parseargs(
+ struct bhv_desc *bhv,
char *options,
- int flags,
- struct xfs_mount_args *args)
+ struct xfs_mount_args *args,
+ int update)
{
+ struct vfs *vfsp = bhvtovfs(bhv);
char *this_char, *value, *eov;
int dsunit, dswidth, vol_dsunit, vol_dswidth;
- int logbufs, logbufsize;
int iosize;
- /* Default to 32 bit inodes on linux all the time */
- args->flags |= XFSMNT_32BITINODES;
-
- /* Copy the already-parsed mount(2) flags we're interested in */
- if (flags & MS_NOATIME)
- args->flags |= XFSMNT_NOATIME;
-
- if (!options) {
- args->logbufs = args->logbufsize = -1;
+ if (!options)
return 0;
- }
- logbufs = logbufsize = -1;
iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;
while ((this_char = strsep(&options, ",")) != NULL) {
@@ -146,22 +107,23 @@ xfs_parseargs(
MNTOPT_LOGBUFS);
return -EINVAL;
}
- logbufs = simple_strtoul(value, &eov, 10);
+ args->logbufs = simple_strtoul(value, &eov, 10);
} else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
- int in_kilobytes = 0;
+ int last, in_kilobytes = 0;
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
MNTOPT_LOGBSIZE);
return -EINVAL;
}
- if (toupper(value[strlen(value)-1]) == 'K') {
+ last = strlen(value) - 1;
+ if (value[last] == 'K' || value[last] == 'k') {
in_kilobytes = 1;
- value[strlen(value)-1] = '\0';
+ value[last] = '\0';
}
- logbufsize = simple_strtoul(value, &eov, 10);
+ args->logbufsize = simple_strtoul(value, &eov, 10);
if (in_kilobytes)
- logbufsize = logbufsize * 1024;
+ args->logbufsize <<= 10;
} else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
@@ -176,17 +138,6 @@ xfs_parseargs(
return -EINVAL;
}
strncpy(args->mtpt, value, MAXNAMELEN);
-#if CONFIG_XFS_DMAPI
- } else if (!strcmp(this_char, MNTOPT_DMAPI)) {
- args->flags |= XFSMNT_DMAPI;
- } else if (!strcmp(this_char, MNTOPT_XDSM)) {
- args->flags |= XFSMNT_DMAPI;
-#else
- } else if (!strcmp(this_char, MNTOPT_DMAPI) ||
- !strcmp(this_char, MNTOPT_XDSM)) {
- printk("XFS: this kernel does not support dmapi/xdsm.\n");
- return -EINVAL;
-#endif
} else if (!strcmp(this_char, MNTOPT_RTDEV)) {
if (!value || !*value) {
printk("XFS: %s option requires an argument\n",
@@ -210,28 +161,12 @@ xfs_parseargs(
} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
args->flags |= XFSMNT_NORECOVERY;
} else if (!strcmp(this_char, MNTOPT_INO64)) {
-#ifdef XFS_BIG_FILESYSTEMS
args->flags |= XFSMNT_INO64;
-#else
+#ifndef XFS_BIG_FILESYSTEMS
printk("XFS: %s option not allowed on this system\n",
MNTOPT_INO64);
return -EINVAL;
#endif
- } else if (!strcmp(this_char, MNTOPT_UQUOTA)) {
- args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
- } else if (!strcmp(this_char, MNTOPT_QUOTA)) {
- args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
- } else if (!strcmp(this_char, MNTOPT_UQUOTANOENF)) {
- args->flags |= XFSMNT_UQUOTA;
- args->flags &= ~XFSMNT_UQUOTAENF;
- } else if (!strcmp(this_char, MNTOPT_QUOTANOENF)) {
- args->flags |= XFSMNT_UQUOTA;
- args->flags &= ~XFSMNT_UQUOTAENF;
- } else if (!strcmp(this_char, MNTOPT_GQUOTA)) {
- args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
- } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
- args->flags |= XFSMNT_GQUOTA;
- args->flags &= ~XFSMNT_GQUOTAENF;
} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
args->flags |= XFSMNT_NOALIGN;
} else if (!strcmp(this_char, MNTOPT_SUNIT)) {
@@ -264,7 +199,7 @@ printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n");
}
if (args->flags & XFSMNT_NORECOVERY) {
- if ((flags & MS_RDONLY) == 0) {
+ if ((vfsp->vfs_flag & VFS_RDONLY) == 0) {
printk("XFS: no-recovery mounts must be read-only.\n");
return -EINVAL;
}
@@ -292,22 +227,21 @@ printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n");
if (dsunit) {
args->sunit = dsunit;
args->flags |= XFSMNT_RETERR;
- } else
+ } else {
args->sunit = vol_dsunit;
+ }
dswidth ? (args->swidth = dswidth) :
(args->swidth = vol_dswidth);
- } else
+ } else {
args->sunit = args->swidth = 0;
-
- args->logbufs = logbufs;
- args->logbufsize = logbufsize;
+ }
return 0;
}
-STATIC int
+int
xfs_showargs(
- struct vfs *vfsp,
+ struct bhv_desc *bhv,
struct seq_file *m)
{
static struct proc_xfs_info {
@@ -322,7 +256,7 @@ xfs_showargs(
{ 0, NULL }
};
struct proc_xfs_info *xfs_infop;
- struct xfs_mount *mp = XFS_BHVTOM(vfsp->vfs_fbhv);
+ struct xfs_mount *mp = XFS_BHVTOM(bhv);
char b[BDEVNAME_SIZE];
for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
@@ -330,18 +264,6 @@ xfs_showargs(
seq_puts(m, xfs_infop->str);
}
- 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_flags & XFS_MOUNT_DFLT_IOSIZE)
seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log);
@@ -368,9 +290,6 @@ xfs_showargs(
seq_printf(m, "," MNTOPT_SWIDTH "=%d",
(int)XFS_FSB_TO_BB(mp, mp->m_swidth));
- if (vfsp->vfs_flag & VFS_DMI)
- seq_puts(m, "," MNTOPT_DMAPI);
-
return 0;
}
@@ -402,21 +321,21 @@ xfs_set_inodeops(
STATIC __inline__ void
xfs_revalidate_inode(
- xfs_mount_t *mp,
- vnode_t *vp,
- xfs_inode_t *ip)
+ xfs_mount_t *mp,
+ vnode_t *vp,
+ xfs_inode_t *ip)
{
- struct inode *inode = LINVFS_GET_IP(vp);
+ struct inode *inode = LINVFS_GET_IP(vp);
inode->i_mode = (ip->i_d.di_mode & MODEMASK) | VTTOIF(vp->v_type);
inode->i_nlink = ip->i_d.di_nlink;
inode->i_uid = ip->i_d.di_uid;
inode->i_gid = ip->i_d.di_gid;
if (((1 << vp->v_type) & ((1<<VBLK) | (1<<VCHR))) == 0) {
- inode->i_rdev = NODEV;
+ inode->i_rdev = NODEV;
} else {
xfs_dev_t dev = ip->i_df.if_u2.if_rdev;
- inode->i_rdev = XFS_DEV_TO_KDEVT(dev);
+ inode->i_rdev = XFS_DEV_TO_KDEVT(dev);
}
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_generation = ip->i_d.di_gen;
@@ -435,23 +354,24 @@ xfs_revalidate_inode(
void
xfs_initialize_vnode(
- bhv_desc_t *bdp,
- vnode_t *vp,
- bhv_desc_t *inode_bhv,
- int unlock)
+ bhv_desc_t *bdp,
+ vnode_t *vp,
+ bhv_desc_t *inode_bhv,
+ int unlock)
{
- xfs_inode_t *ip = XFS_BHVTOI(inode_bhv);
- struct inode *inode = LINVFS_GET_IP(vp);
+ xfs_inode_t *ip = XFS_BHVTOI(inode_bhv);
+ struct inode *inode = LINVFS_GET_IP(vp);
- if (vp->v_fbhv == NULL) {
+ if (!inode_bhv->bd_vobj) {
vp->v_vfsp = bhvtovfs(bdp);
- bhv_desc_init(&(ip->i_bhv_desc), ip, vp, &xfs_vnodeops);
- bhv_insert_initial(VN_BHV_HEAD(vp), &(ip->i_bhv_desc));
+ bhv_desc_init(inode_bhv, ip, vp, &xfs_vnodeops);
+ bhv_insert(VN_BHV_HEAD(vp), inode_bhv);
}
vp->v_type = IFTOVT(ip->i_d.di_mode);
+
/* Have we been called during the new inode create process,
- * in which case we are too early to fill in the linux inode.
+ * in which case we are too early to fill in the Linux inode.
*/
if (vp->v_type == VNON)
return;
@@ -497,7 +417,7 @@ xfs_free_buftarg(
xfs_buftarg_t *btp)
{
pagebuf_delwri_flush(btp, PBDF_WAIT, NULL);
- kfree(btp);
+ kmem_free(btp, sizeof(*btp));
}
void
@@ -548,8 +468,6 @@ xfs_alloc_buftarg(
return btp;
}
-STATIC kmem_cache_t * linvfs_inode_cachep;
-
STATIC __inline__ unsigned int gfp_mask(void)
{
/* If we're not in a transaction, FS activity is ok */
@@ -557,7 +475,6 @@ STATIC __inline__ unsigned int gfp_mask(void)
return GFP_KERNEL;
}
-
STATIC struct inode *
linvfs_alloc_inode(
struct super_block *sb)
@@ -606,119 +523,7 @@ STATIC void
destroy_inodecache( void )
{
if (kmem_cache_destroy(linvfs_inode_cachep))
- printk(KERN_INFO
- "linvfs_inode_cache: not all structures were freed\n");
-}
-
-static int
-linvfs_fill_super(
- struct super_block *sb,
- void *data,
- int silent)
-{
- vfs_t *vfsp;
- vfsops_t *vfsops;
- vnode_t *rootvp;
- struct inode *ip;
- struct xfs_mount_args *args;
- struct statfs statvfs;
- int error = EINVAL;
-
- args = kmalloc(sizeof(struct xfs_mount_args), GFP_KERNEL);
- if (!args)
- return -EINVAL;
- memset(args, 0, sizeof(struct xfs_mount_args));
- args->slcount = args->stimeout = args->ctimeout = -1;
- strncpy(args->fsname, sb->s_id, MAXNAMELEN);
- if (xfs_parseargs((char *)data, sb->s_flags, args))
- goto out_null;
-
- /* Kludge in XFS until we have other VFS/VNODE FSs */
- vfsops = &xfs_vfsops;
-
- /* Set up the vfs_t structure */
- vfsp = vfs_allocate();
- if (!vfsp) {
- error = ENOMEM;
- goto out_null;
- }
-
- if (sb->s_flags & MS_RDONLY)
- vfsp->vfs_flag |= VFS_RDONLY;
-
- vfsp->vfs_super = sb;
- set_max_bytes(sb);
- set_quota_ops(sb);
- sb->s_op = &linvfs_sops;
- sb->s_export_op = &linvfs_export_ops;
-
- sb_min_blocksize(sb, BBSIZE);
-
- LINVFS_SET_VFS(sb, vfsp);
-
- VFSOPS_MOUNT(vfsops, vfsp, args, NULL, error);
- if (error)
- goto fail_vfsop;
-
- VFS_STATVFS(vfsp, &statvfs, NULL, error);
- if (error)
- goto fail_unmount;
-
- sb->s_magic = XFS_SB_MAGIC;
- sb->s_dirt = 1;
- sb->s_blocksize = statvfs.f_bsize;
- sb->s_blocksize_bits = ffs(statvfs.f_bsize) - 1;
- set_posix_acl(sb);
-
- VFS_ROOT(vfsp, &rootvp, error);
- if (error)
- goto fail_unmount;
-
- ip = LINVFS_GET_IP(rootvp);
-
- sb->s_root = d_alloc_root(ip);
- if (!sb->s_root)
- goto fail_vnrele;
- if (is_bad_inode(sb->s_root->d_inode))
- goto fail_vnrele;
-
- /* Don't set the VFS_DMI flag until here because we don't want
- * to send events while replaying the log.
- */
- if (args->flags & XFSMNT_DMAPI) {
- vfsp->vfs_flag |= VFS_DMI;
- VFSOPS_DMAPI_MOUNT(vfsops, vfsp, args->mtpt, args->fsname,
- error);
-
- if (error) {
- if (atomic_read(&sb->s_active) == 1)
- vfsp->vfs_flag &= ~VFS_DMI;
- goto fail_vnrele;
- }
- }
-
- vn_trace_exit(rootvp, __FUNCTION__, (inst_t *)__return_address);
-
- kfree(args);
- return 0;
-
-fail_vnrele:
- if (sb->s_root) {
- dput(sb->s_root);
- sb->s_root = NULL;
- } else {
- VN_RELE(rootvp);
- }
-
-fail_unmount:
- VFS_UNMOUNT(vfsp, 0, NULL, error);
-
-fail_vfsop:
- vfs_deallocate(vfsp);
-
-out_null:
- kfree(args);
- return -error;
+ printk(KERN_WARNING "%s: cache still in use!\n", __FUNCTION__);
}
/*
@@ -789,8 +594,7 @@ linvfs_write_super(
sb->s_dirt = 0;
if (sb->s_flags & MS_RDONLY)
return;
- VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR,
- NULL, error);
+ VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error);
}
STATIC int
@@ -811,30 +615,21 @@ linvfs_remount(
int *flags,
char *options)
{
- struct xfs_mount_args *args;
- vfs_t *vfsp;
- xfs_mount_t *mp;
- int error = 0;
-
- vfsp = LINVFS_GET_VFS(sb);
- mp = XFS_BHVTOM(vfsp->vfs_fbhv);
+ vfs_t *vfsp = LINVFS_GET_VFS(sb);
+ xfs_mount_t *mp = XFS_VFSTOM(vfsp);
+ struct xfs_mount_args *args = args_allocate(sb);
+ int error;
- args = kmalloc(sizeof(struct xfs_mount_args), GFP_KERNEL);
- if (!args)
- return -ENOMEM;
- memset(args, 0, sizeof(struct xfs_mount_args));
- args->slcount = args->stimeout = args->ctimeout = -1;
- if (xfs_parseargs(options, *flags, args)) {
- error = -EINVAL;
+ VFS_PARSEARGS(vfsp, options, args, 1, error);
+ if (error)
goto out;
- }
if (args->flags & XFSMNT_NOATIME)
mp->m_flags |= XFS_MOUNT_NOATIME;
else
mp->m_flags &= ~XFS_MOUNT_NOATIME;
- set_posix_acl(sb);
+ set_posix_acl_flag(sb);
linvfs_write_super(sb);
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
@@ -842,14 +637,14 @@ linvfs_remount(
if (*flags & MS_RDONLY) {
sb->s_flags |= MS_RDONLY;
- XFS_log_write_unmount_ro(vfsp->vfs_fbhv);
+ XFS_log_write_unmount_ro(&mp->m_bhv);
vfsp->vfs_flag |= VFS_RDONLY;
} else {
vfsp->vfs_flag &= ~VFS_RDONLY;
}
out:
- kfree(args);
+ kmem_free(args, sizeof(*args));
return error;
}
@@ -950,6 +745,151 @@ linvfs_get_dentry(
return result;
}
+STATIC int
+linvfs_show_options(
+ struct seq_file *m,
+ struct vfsmount *mnt)
+{
+ struct vfs *vfsp = LINVFS_GET_VFS(mnt->mnt_sb);
+ int error;
+
+ VFS_SHOWARGS(vfsp, m, error);
+ return error;
+}
+
+STATIC int
+linvfs_getxstate(
+ struct super_block *sb,
+ struct fs_quota_stat *fqs)
+{
+ struct vfs *vfsp = LINVFS_GET_VFS(sb);
+ int error;
+
+ VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
+ return -error;
+}
+
+STATIC int
+linvfs_setxstate(
+ struct super_block *sb,
+ unsigned int flags,
+ int op)
+{
+ struct vfs *vfsp = LINVFS_GET_VFS(sb);
+ int error;
+
+ VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
+ return -error;
+}
+
+STATIC int
+linvfs_getxquota(
+ struct super_block *sb,
+ int type,
+ qid_t id,
+ struct fs_disk_quota *fdq)
+{
+ struct vfs *vfsp = LINVFS_GET_VFS(sb);
+ int error, getmode;
+
+ getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA;
+ VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
+ return -error;
+}
+
+STATIC int
+linvfs_setxquota(
+ struct super_block *sb,
+ int type,
+ qid_t id,
+ struct fs_disk_quota *fdq)
+{
+ struct vfs *vfsp = LINVFS_GET_VFS(sb);
+ int error, setmode;
+
+ setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM;
+ VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
+ return -error;
+}
+
+STATIC int
+linvfs_fill_super(
+ struct super_block *sb,
+ void *data,
+ int silent)
+{
+ vnode_t *rootvp;
+ struct vfs *vfsp = vfs_allocate();
+ struct xfs_mount_args *args = args_allocate(sb);
+ struct statfs statvfs;
+ int error;
+
+ vfsp->vfs_super = sb;
+ LINVFS_SET_VFS(sb, vfsp);
+ if (sb->s_flags & MS_RDONLY)
+ vfsp->vfs_flag |= VFS_RDONLY;
+ bhv_insert_all_vfsops(vfsp);
+
+ VFS_PARSEARGS(vfsp, (char *)data, args, 0, error);
+ if (error) {
+ bhv_remove_all_vfsops(vfsp, 1);
+ goto fail_vfsop;
+ }
+
+ sb_min_blocksize(sb, BBSIZE);
+ sb->s_maxbytes = XFS_MAX_FILE_OFFSET;
+ sb->s_export_op = &linvfs_export_ops;
+ sb->s_qcop = &linvfs_qops;
+ sb->s_op = &linvfs_sops;
+
+ VFS_MOUNT(vfsp, args, NULL, error);
+ if (error) {
+ bhv_remove_all_vfsops(vfsp, 1);
+ goto fail_vfsop;
+ }
+
+ VFS_STATVFS(vfsp, &statvfs, NULL, error);
+ if (error)
+ goto fail_unmount;
+
+ sb->s_dirt = 1;
+ sb->s_magic = XFS_SB_MAGIC;
+ sb->s_blocksize = statvfs.f_bsize;
+ sb->s_blocksize_bits = ffs(statvfs.f_bsize) - 1;
+ set_posix_acl_flag(sb);
+
+ VFS_ROOT(vfsp, &rootvp, error);
+ if (error)
+ goto fail_unmount;
+
+ sb->s_root = d_alloc_root(LINVFS_GET_IP(rootvp));
+ if (!sb->s_root)
+ goto fail_vnrele;
+ if (is_bad_inode(sb->s_root->d_inode))
+ goto fail_vnrele;
+
+ vn_trace_exit(rootvp, __FUNCTION__, (inst_t *)__return_address);
+
+ kmem_free(args, sizeof(*args));
+ return 0;
+
+fail_vnrele:
+ if (sb->s_root) {
+ dput(sb->s_root);
+ sb->s_root = NULL;
+ } else {
+ VN_RELE(rootvp);
+ }
+
+fail_unmount:
+ VFS_UNMOUNT(vfsp, 0, NULL, error);
+
+fail_vfsop:
+ vfs_deallocate(vfsp);
+ kmem_free(args, sizeof(*args));
+ return -error;
+}
+
STATIC struct super_block *
linvfs_get_sb(
struct file_system_type *fs_type,
@@ -960,15 +900,6 @@ linvfs_get_sb(
return get_sb_bdev(fs_type, flags, dev_name, data, linvfs_fill_super);
}
-STATIC int
-linvfs_show_options(
- struct seq_file *m,
- struct vfsmount *mnt)
-{
- vfs_t *vfsp = LINVFS_GET_VFS(mnt->mnt_sb);
-
- return xfs_showargs(vfsp, m);
-}
STATIC struct export_operations linvfs_export_ops = {
.get_parent = linvfs_get_parent,
@@ -989,6 +920,13 @@ STATIC struct super_operations linvfs_sops = {
.show_options = linvfs_show_options,
};
+STATIC struct quotactl_ops linvfs_qops = {
+ .get_xstate = linvfs_getxstate,
+ .set_xstate = linvfs_setxstate,
+ .get_xquota = linvfs_getxquota,
+ .set_xquota = linvfs_setxquota,
+};
+
STATIC struct file_system_type xfs_fs_type = {
.owner = THIS_MODULE,
.name = "xfs",
@@ -997,6 +935,7 @@ STATIC struct file_system_type xfs_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
+
STATIC int __init
init_xfs_fs( void )
{
@@ -1008,37 +947,44 @@ init_xfs_fs( void )
printk(message);
- error = init_inodecache();
- if (error < 0)
- return error;
-
si_meminfo(&si);
xfs_physmem = si.totalram;
+ error = init_inodecache();
+ if (error < 0)
+ goto undo_inodecache;
+
error = pagebuf_init();
if (error < 0)
- goto out;
+ goto undo_pagebuf;
vn_init();
xfs_init();
- dmapi_init();
+ vfs_initdmapi();
+ vfs_initquota();
error = register_filesystem(&xfs_fs_type);
if (error)
- goto out;
+ goto undo_register;
return 0;
-out:
+undo_register:
+ pagebuf_terminate();
+
+undo_pagebuf:
destroy_inodecache();
+
+undo_inodecache:
return error;
}
STATIC void __exit
exit_xfs_fs( void )
{
- dmapi_uninit();
- xfs_cleanup();
unregister_filesystem(&xfs_fs_type);
+ xfs_cleanup();
+ vfs_exitquota();
+ vfs_exitdmapi();
pagebuf_terminate();
destroy_inodecache();
}
@@ -1047,5 +993,6 @@ module_init(init_xfs_fs);
module_exit(exit_xfs_fs);
MODULE_AUTHOR("SGI <sgi.com>");
-MODULE_DESCRIPTION("SGI XFS " XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled");
+MODULE_DESCRIPTION(
+ "SGI XFS " XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled");
MODULE_LICENSE("GPL");
diff --git a/fs/xfs/linux/xfs_super.h b/fs/xfs/linux/xfs_super.h
index f0b2372d008b..72bedd79a0ef 100644
--- a/fs/xfs/linux/xfs_super.h
+++ b/fs/xfs/linux/xfs_super.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -32,28 +32,38 @@
#ifndef __XFS_SUPER_H__
#define __XFS_SUPER_H__
-#ifdef CONFIG_XFS_POSIX_ACL
-# define XFS_ACL_STRING "ACLs, "
+#ifdef CONFIG_XFS_DMAPI
+# define vfs_insertdmapi(vfs) vfs_insertops(vfsp, &xfs_dmops)
+# define vfs_initdmapi() dmapi_init()
+# define vfs_exitdmapi() dmapi_uninit()
#else
-# define XFS_ACL_STRING
+# define vfs_insertdmapi(vfs) do { } while (0)
+# define vfs_initdmapi() do { } while (0)
+# define vfs_exitdmapi() do { } while (0)
#endif
-#ifdef CONFIG_XFS_DMAPI
-# define XFS_DMAPI_STRING "DMAPI, "
+#ifdef CONFIG_XFS_QUOTA
+# define vfs_insertquota(vfs) vfs_insertops(vfsp, &xfs_qmops)
+# define vfs_initquota() xfs_qm_init()
+# define vfs_exitquota() xfs_qm_exit()
#else
-# define XFS_DMAPI_STRING
+# define vfs_insertquota(vfs) do { } while (0)
+# define vfs_initquota() do { } while (0)
+# define vfs_exitquota() do { } while (0)
#endif
-#ifdef CONFIG_XFS_QUOTA
-# define XFS_QUOTA_STRING "quota, "
+#ifdef CONFIG_XFS_POSIX_ACL
+# define XFS_ACL_STRING "ACLs, "
+# define set_posix_acl_flag(sb) ((sb)->s_flags |= MS_POSIXACL)
#else
-# define XFS_QUOTA_STRING
+# define XFS_ACL_STRING
+# define set_posix_acl_flag(sb) do { } while (0)
#endif
#ifdef CONFIG_XFS_RT
-# define XFS_RT_STRING "realtime, "
+# define XFS_REALTIME_STRING "realtime, "
#else
-# define XFS_RT_STRING
+# define XFS_REALTIME_STRING
#endif
#ifdef CONFIG_XFS_VNODE_TRACING
@@ -68,9 +78,9 @@
# define XFS_DBG_STRING "no debug"
#endif
-#define XFS_BUILD_OPTIONS XFS_ACL_STRING XFS_DMAPI_STRING \
- XFS_RT_STRING \
- XFS_QUOTA_STRING XFS_VNTRACE_STRING \
+#define XFS_BUILD_OPTIONS XFS_ACL_STRING \
+ XFS_REALTIME_STRING \
+ XFS_VNTRACE_STRING \
XFS_DBG_STRING /* DBG must be last */
#define LINVFS_GET_VFS(s) \
@@ -82,6 +92,8 @@ struct xfs_mount;
struct pb_target;
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 int xfs_blkdev_get(struct xfs_mount *, const char *,
diff --git a/fs/xfs/linux/xfs_vfs.c b/fs/xfs/linux/xfs_vfs.c
new file mode 100644
index 000000000000..17e6988bc7f8
--- /dev/null
+++ b/fs/xfs/linux/xfs_vfs.c
@@ -0,0 +1,285 @@
+/*
+ * 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(
+ struct bhv_desc *bdp,
+ struct xfs_mount_args *args,
+ struct cred *cr)
+{
+ struct bhv_desc *next = bdp;
+
+ ASSERT(next);
+ while (! (bhvtovfsops(next))->vfs_mount)
+ next = BHV_NEXT(next);
+ return ((*bhvtovfsops(next)->vfs_mount)(next, args, cr));
+}
+
+int
+vfs_parseargs(
+ struct bhv_desc *bdp,
+ char *s,
+ struct xfs_mount_args *args,
+ int f)
+{
+ struct bhv_desc *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(
+ struct bhv_desc *bdp,
+ struct seq_file *m)
+{
+ struct bhv_desc *next = bdp;
+
+ ASSERT(next);
+ while (! (bhvtovfsops(next))->vfs_showargs)
+ next = BHV_NEXT(next);
+ return ((*bhvtovfsops(next)->vfs_showargs)(next, m));
+}
+
+int
+vfs_unmount(
+ struct bhv_desc *bdp,
+ int fl,
+ struct cred *cr)
+{
+ struct bhv_desc *next = bdp;
+
+ ASSERT(next);
+ while (! (bhvtovfsops(next))->vfs_unmount)
+ next = BHV_NEXT(next);
+ return ((*bhvtovfsops(next)->vfs_unmount)(next, fl, cr));
+}
+
+int
+vfs_root(
+ struct bhv_desc *bdp,
+ struct vnode **vpp)
+{
+ struct bhv_desc *next = bdp;
+
+ ASSERT(next);
+ while (! (bhvtovfsops(next))->vfs_root)
+ next = BHV_NEXT(next);
+ return ((*bhvtovfsops(next)->vfs_root)(next, vpp));
+}
+
+int
+vfs_statvfs(
+ struct bhv_desc *bdp,
+ struct statfs *sp,
+ struct vnode *vp)
+{
+ struct bhv_desc *next = bdp;
+
+ ASSERT(next);
+ while (! (bhvtovfsops(next))->vfs_statvfs)
+ next = BHV_NEXT(next);
+ return ((*bhvtovfsops(next)->vfs_statvfs)(next, sp, vp));
+}
+
+int
+vfs_sync(
+ struct bhv_desc *bdp,
+ int fl,
+ struct cred *cr)
+{
+ struct bhv_desc *next = bdp;
+
+ ASSERT(next);
+ while (! (bhvtovfsops(next))->vfs_sync)
+ next = BHV_NEXT(next);
+ return ((*bhvtovfsops(next)->vfs_sync)(next, fl, cr));
+}
+
+int
+vfs_vget(
+ struct bhv_desc *bdp,
+ struct vnode **vpp,
+ struct fid *fidp)
+{
+ struct bhv_desc *next = bdp;
+
+ ASSERT(next);
+ while (! (bhvtovfsops(next))->vfs_vget)
+ next = BHV_NEXT(next);
+ return ((*bhvtovfsops(next)->vfs_vget)(next, vpp, fidp));
+}
+
+int
+vfs_dmapiops(
+ struct bhv_desc *bdp,
+ caddr_t addr)
+{
+ struct bhv_desc *next = bdp;
+
+ ASSERT(next);
+ while (! (bhvtovfsops(next))->vfs_dmapiops)
+ next = BHV_NEXT(next);
+ return ((*bhvtovfsops(next)->vfs_dmapiops)(next, addr));
+}
+
+int
+vfs_quotactl(
+ struct bhv_desc *bdp,
+ int cmd,
+ int id,
+ caddr_t addr)
+{
+ struct bhv_desc *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(
+ struct bhv_desc *bdp,
+ struct vnode *vp,
+ struct bhv_desc *bp,
+ int unlock)
+{
+ struct bhv_desc *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(
+ struct bhv_desc *bdp,
+ int fl,
+ char *file,
+ int line)
+{
+ struct bhv_desc *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 )
+{
+ struct vfs *vfsp;
+
+ vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP);
+ bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
+ return vfsp;
+}
+
+void
+vfs_deallocate(
+ struct vfs *vfsp)
+{
+ bhv_head_destroy(VFS_BHVHEAD(vfsp));
+ kmem_free(vfsp, sizeof(vfs_t));
+}
+
+void
+vfs_insertops(
+ struct vfs *vfsp,
+ struct bhv_vfsops *vfsops)
+{
+ struct bhv_desc *bdp;
+
+ bdp = kmem_alloc(sizeof(struct bhv_desc), KM_SLEEP);
+ bhv_desc_init(bdp, NULL, vfsp, vfsops);
+ bhv_insert(&vfsp->vfs_bh, bdp);
+}
+
+void
+vfs_insertbhv(
+ struct vfs *vfsp,
+ struct bhv_desc *bdp,
+ struct vfsops *vfsops,
+ void *mount)
+{
+ bhv_desc_init(bdp, mount, vfsp, vfsops);
+ bhv_insert_initial(&vfsp->vfs_bh, bdp);
+}
+
+void
+bhv_remove_vfsops(
+ struct vfs *vfsp,
+ int pos)
+{
+ struct bhv_desc *bhv;
+
+ bhv = bhv_lookup_range(&vfsp->vfs_bh, pos, pos);
+ if (!bhv)
+ return;
+ bhv_remove(&vfsp->vfs_bh, bhv);
+ kmem_free(bhv, sizeof(*bhv));
+}
+
+void
+bhv_remove_all_vfsops(
+ struct vfs *vfsp,
+ int freebase)
+{
+ struct xfs_mount *mp;
+
+ bhv_remove_vfsops(vfsp, VFS_POSITION_QM);
+ bhv_remove_vfsops(vfsp, VFS_POSITION_DM);
+ if (!freebase)
+ return;
+ mp = XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfsp), &xfs_vfsops));
+ VFS_REMOVEBHV(vfsp, &mp->m_bhv);
+ xfs_mount_free(mp, 0);
+}
+
+void
+bhv_insert_all_vfsops(
+ struct vfs *vfsp)
+{
+ struct xfs_mount *mp;
+
+ mp = xfs_mount_init();
+ vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
+ vfs_insertdmapi(vfsp);
+ vfs_insertquota(vfsp);
+}
diff --git a/fs/xfs/linux/xfs_vfs.h b/fs/xfs/linux/xfs_vfs.h
index e2b1bfe025d9..b18e6424b67c 100644
--- a/fs/xfs/linux/xfs_vfs.h
+++ b/fs/xfs/linux/xfs_vfs.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -34,162 +34,154 @@
#include <linux/vfs.h>
-struct statfs;
-struct vnode;
+struct fid;
struct cred;
+struct vnode;
+struct statfs;
+struct seq_file;
struct super_block;
-struct fid;
-struct dm_fcntl_vector;
struct xfs_mount_args;
typedef struct vfs {
- u_int vfs_flag; /* flags */
- fsid_t vfs_fsid; /* file system id */
- fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
- bhv_head_t vfs_bh; /* head of vfs behavior chain */
- struct super_block *vfs_super; /* pointer to super block structure */
+ u_int vfs_flag; /* flags */
+ fsid_t vfs_fsid; /* file system ID */
+ fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
+ bhv_head_t vfs_bh; /* head of vfs behavior chain */
+ struct super_block *vfs_super; /* Linux superblock structure */
} vfs_t;
-#define vfs_fbhv vfs_bh.bh_first /* 1st on vfs behavior chain */
-#define VFS_FOPS(vfsp) \
- ((vfsops_t *)((vfsp)->vfs_fbhv->bd_ops))/* ops for 1st behavior */
-
-
-#define bhvtovfs(bdp) ((struct vfs *)BHV_VOBJ(bdp))
-#define VFS_BHVHEAD(vfsp) (&(vfsp)->vfs_bh)
-
-
-#define VFS_RDONLY 0x0001 /* read-only vfs */
-#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
-#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
-
-#define SYNC_ATTR 0x0001 /* sync attributes */
-#define SYNC_CLOSE 0x0002 /* close file system down */
-#define SYNC_DELWRI 0x0004 /* look at delayed writes */
-#define SYNC_WAIT 0x0008 /* wait for i/o to complete */
-#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
-#define SYNC_BDFLUSH 0x0010 /* BDFLUSH is calling -- don't block */
-
+#define vfs_fbhv vfs_bh.bh_first /* 1st on vfs behavior chain */
+
+#define bhvtovfs(bdp) ( (struct vfs *)BHV_VOBJ(bdp) )
+#define bhvtovfsops(bdp) ( (struct vfsops *)BHV_OPS(bdp) )
+#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh )
+#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
+
+#define VFS_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
+#define VFS_POSITION_TOP BHV_POSITION_TOP /* chain top */
+#define VFS_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
+
+typedef enum {
+ VFS_BHV_UNKNOWN, /* not specified */
+ VFS_BHV_XFS, /* xfs */
+ VFS_BHV_DM, /* data migration */
+ VFS_BHV_QM, /* quota manager */
+ VFS_BHV_IO, /* IO path */
+ VFS_BHV_END /* housekeeping end-of-range */
+} vfs_bhv_t;
+
+#define VFS_POSITION_XFS (BHV_POSITION_BASE)
+#define VFS_POSITION_DM (VFS_POSITION_BASE+10)
+#define VFS_POSITION_QM (VFS_POSITION_BASE+20)
+#define VFS_POSITION_IO (VFS_POSITION_BASE+30)
+
+#define VFS_RDONLY 0x0001 /* read-only vfs */
+#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
+#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
+#define VFS_END 0x0004 /* max flag */
+
+#define SYNC_ATTR 0x0001 /* sync attributes */
+#define SYNC_CLOSE 0x0002 /* close file system down */
+#define SYNC_DELWRI 0x0004 /* look at delayed writes */
+#define SYNC_WAIT 0x0008 /* wait for i/o to complete */
+#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
+#define SYNC_BDFLUSH 0x0010 /* BDFLUSH is calling -- don't block */
+
+typedef int (*vfs_mount_t)(bhv_desc_t *,
+ struct xfs_mount_args *, struct cred *);
+typedef int (*vfs_parseargs_t)(bhv_desc_t *, char *,
+ struct xfs_mount_args *, int);
+typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *);
+typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
+typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **);
+typedef int (*vfs_statvfs_t)(bhv_desc_t *, struct statfs *, struct vnode *);
+typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
+typedef int (*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *);
+typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
+typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
+typedef void (*vfs_init_vnode_t)(bhv_desc_t *,
+ struct vnode *, bhv_desc_t *, int);
+typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
typedef struct vfsops {
- int (*vfs_mount)(struct vfs *, struct xfs_mount_args *,
- struct cred *);
- /* mount file system */
- int (*vfs_unmount)(bhv_desc_t *, int, struct cred *);
- /* unmount file system */
- int (*vfs_root)(bhv_desc_t *, struct vnode **);
- /* get root vnode */
- int (*vfs_statvfs)(bhv_desc_t *, struct statfs *, struct vnode *);
- /* get file system statistics */
- int (*vfs_sync)(bhv_desc_t *, int, struct cred *);
- /* flush files */
- int (*vfs_vget)(bhv_desc_t *, struct vnode **, struct fid *);
- /* get vnode from fid */
- int (*vfs_dmapi_mount)(struct vfs *, char *, char *);
- /* send dmapi mount event */
- int (*vfs_dmapi_fsys_vector)(bhv_desc_t *,
- struct dm_fcntl_vector *);
- void (*vfs_init_vnode)(bhv_desc_t *, struct vnode *,
- bhv_desc_t *, int);
- void (*vfs_force_shutdown)(bhv_desc_t *,
- int, char *, int);
+ bhv_position_t vf_position; /* behavior chain position */
+ vfs_mount_t vfs_mount; /* mount file system */
+ vfs_parseargs_t vfs_parseargs; /* parse mount options */
+ vfs_showargs_t vfs_showargs; /* unparse mount options */
+ vfs_unmount_t vfs_unmount; /* unmount file system */
+ vfs_root_t vfs_root; /* get root vnode */
+ vfs_statvfs_t vfs_statvfs; /* file system statistics */
+ vfs_sync_t vfs_sync; /* flush files */
+ vfs_vget_t vfs_vget; /* get vnode from fid */
+ vfs_dmapiops_t vfs_dmapiops; /* data migration */
+ vfs_quotactl_t vfs_quotactl; /* disk quota */
+ vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */
+ vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */
} vfsops_t;
-#define VFS_UNMOUNT(vfsp,f,cr, rv) \
-{ \
- rv = (*(VFS_FOPS(vfsp)->vfs_unmount))((vfsp)->vfs_fbhv, f, cr); \
-}
-#define VFS_ROOT(vfsp, vpp, rv) \
-{ \
- rv = (*(VFS_FOPS(vfsp)->vfs_root))((vfsp)->vfs_fbhv, vpp); \
-}
-#define VFS_STATVFS(vfsp, sp, vp, rv) \
-{ \
- rv = (*(VFS_FOPS(vfsp)->vfs_statvfs))((vfsp)->vfs_fbhv, sp, vp);\
-}
-#define VFS_SYNC(vfsp, flag, cr, rv) \
-{ \
- rv = (*(VFS_FOPS(vfsp)->vfs_sync))((vfsp)->vfs_fbhv, flag, cr); \
-}
-#define VFS_VGET(vfsp, vpp, fidp, rv) \
-{ \
- rv = (*(VFS_FOPS(vfsp)->vfs_vget))((vfsp)->vfs_fbhv, vpp, fidp); \
-}
-
-#define VFS_INIT_VNODE(vfsp, vp, bhv, unlock) \
-{ \
- (*(VFS_FOPS(vfsp)->vfs_init_vnode))((vfsp)->vfs_fbhv, vp, bhv, unlock);\
-}
-
-/* No behavior lock here */
-#define VFS_FORCE_SHUTDOWN(vfsp, flags) \
- (*(VFS_FOPS(vfsp)->vfs_force_shutdown))((vfsp)->vfs_fbhv, flags, __FILE__, __LINE__);
-
-#define VFS_DMAPI_FSYS_VECTOR(vfsp, df, rv) \
-{ \
- rv = (*(VFS_FOPS(vfsp)->vfs_dmapi_fsys_vector))((vfsp)->vfs_fbhv, df); \
-}
-
-
-#define VFSOPS_DMAPI_MOUNT(vfs_op, vfsp, dir_name, fsname, rv) \
- rv = (*(vfs_op)->vfs_dmapi_mount)(vfsp, dir_name, fsname)
-#define VFSOPS_MOUNT(vfs_op, vfsp, args, cr, rv) \
- rv = (*(vfs_op)->vfs_mount)(vfsp, args, cr)
-
-#define VFS_REMOVEBHV(vfsp, bdp)\
-{ \
- bhv_remove(VFS_BHVHEAD(vfsp), bdp); \
-}
-
-#define PVFS_UNMOUNT(bdp,f,cr, rv) \
-{ \
- rv = (*((vfsops_t *)(bdp)->bd_ops)->vfs_unmount)(bdp, f, cr); \
-}
-
-#define PVFS_SYNC(bdp, flag, cr, rv) \
-{ \
- rv = (*((vfsops_t *)(bdp)->bd_ops)->vfs_sync)(bdp, flag, cr); \
-}
-
-
-static __inline vfs_t *
-vfs_allocate(void)
-{
- vfs_t *vfsp;
-
- vfsp = kmalloc(sizeof(vfs_t), GFP_KERNEL);
- if (vfsp) {
- memset(vfsp, 0, sizeof(vfs_t));
- bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
- }
- return (vfsp);
-}
-
-static __inline void
-vfs_deallocate(
- vfs_t *vfsp)
-{
- bhv_head_destroy(VFS_BHVHEAD(vfsp));
- kfree(vfsp);
-}
+/*
+ * VFS's. Operates on vfs structure pointers (starts at bhv head).
+ */
+#define VHEAD(v) ((v)->vfs_fbhv)
+#define VFS_MOUNT(v, ma,cr, rv) ((rv) = vfs_mount(VHEAD(v), ma,cr))
+#define VFS_PARSEARGS(v, o,ma,f, rv) ((rv) = vfs_parseargs(VHEAD(v), o,ma,f))
+#define VFS_SHOWARGS(v, m, rv) ((rv) = vfs_showargs(VHEAD(v), m))
+#define VFS_UNMOUNT(v, f,cr, rv) ((rv) = vfs_unmount(VHEAD(v), f,cr))
+#define VFS_ROOT(v, vpp, rv) ((rv) = vfs_root(VHEAD(v), vpp))
+#define VFS_STATVFS(v, sp,vp, rv) ((rv) = vfs_statvfs(VHEAD(v), sp,vp))
+#define VFS_SYNC(v, flag,cr, rv) ((rv) = vfs_sync(VHEAD(v), flag,cr))
+#define VFS_VGET(v, vpp,fidp, rv) ((rv) = vfs_vget(VHEAD(v), vpp,fidp))
+#define VFS_DMAPIOPS(v, p, rv) ((rv) = vfs_dmapiops(VHEAD(v), p))
+#define VFS_QUOTACTL(v, c,id,p, rv) ((rv) = vfs_quotactl(VHEAD(v), c,id,p))
+#define VFS_INIT_VNODE(v, vp,b,ul) ( vfs_init_vnode(VHEAD(v), vp,b,ul) )
+#define VFS_FORCE_SHUTDOWN(v, fl,f,l) ( vfs_force_shutdown(VHEAD(v), fl,f,l) )
/*
- * Called by fs dependent VFS_MOUNT code to link the VFS base file system
- * dependent behavior with the VFS virtual object.
+ * PVFS's. Operates on behavior descriptor pointers.
*/
-static __inline void
-vfs_insertbhv(
- vfs_t *vfsp,
- bhv_desc_t *bdp,
- vfsops_t *vfsops,
- void *mount)
-{
- /*
- * Initialize behavior desc with ops and data and then
- * attach it to the vfs.
- */
- bhv_desc_init(bdp, mount, vfsp, vfsops);
- bhv_insert_initial(&vfsp->vfs_bh, bdp);
-}
+#define PVFS_MOUNT(b, ma,cr, rv) ((rv) = vfs_mount(b, ma,cr))
+#define PVFS_PARSEARGS(b, o,ma,f, rv) ((rv) = vfs_parseargs(b, o,ma,f))
+#define PVFS_SHOWARGS(b, m, rv) ((rv) = vfs_showargs(b, m))
+#define PVFS_UNMOUNT(b, f,cr, rv) ((rv) = vfs_unmount(b, f,cr))
+#define PVFS_ROOT(b, vpp, rv) ((rv) = vfs_root(b, vpp))
+#define PVFS_STATVFS(b, sp,vp, rv) ((rv) = vfs_statvfs(b, sp,vp))
+#define PVFS_SYNC(b, flag,cr, rv) ((rv) = vfs_sync(b, flag,cr))
+#define PVFS_VGET(b, vpp,fidp, rv) ((rv) = vfs_vget(b, vpp,fidp))
+#define PVFS_DMAPIOPS(b, p, rv) ((rv) = vfs_dmapiops(b, p))
+#define PVFS_QUOTACTL(b, c,id,p, rv) ((rv) = vfs_quotactl(b, c,id,p))
+#define PVFS_INIT_VNODE(b, vp,b2,ul) ( vfs_init_vnode(b, vp,b2,ul) )
+#define PVFS_FORCE_SHUTDOWN(b, fl,f,l) ( vfs_force_shutdown(b, fl,f,l) )
+
+extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
+extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
+extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
+extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
+extern int vfs_root(bhv_desc_t *, struct vnode **);
+extern int vfs_statvfs(bhv_desc_t *, struct statfs *, struct vnode *);
+extern int vfs_sync(bhv_desc_t *, int, struct cred *);
+extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *);
+extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
+extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
+extern void vfs_init_vnode(bhv_desc_t *, struct vnode *, bhv_desc_t *, int);
+extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
+
+typedef struct bhv_vfsops {
+ struct vfsops bhv_common;
+ void * bhv_custom;
+} bhv_vfsops_t;
+
+#define vfs_bhv_lookup(v, id) ( bhv_lookup_range(&(v)->vfs_bh, (id), (id)) )
+#define vfs_bhv_custom(b) ( ((bhv_vfsops_t *)BHV_OPS(b))->bhv_custom )
+#define vfs_bhv_set_custom(b,o) ( (b)->bhv_custom = (void *)(o))
+#define vfs_bhv_clr_custom(b) ( (b)->bhv_custom = NULL )
+
+extern vfs_t *vfs_allocate(void);
+extern void vfs_deallocate(vfs_t *);
+extern void vfs_insertops(vfs_t *, bhv_vfsops_t *);
+extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *);
+
+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_VFS_H__ */
diff --git a/fs/xfs/linux/xfs_vnode.c b/fs/xfs/linux/xfs_vnode.c
index ff78d13e750f..c976fda746bb 100644
--- a/fs/xfs/linux/xfs_vnode.c
+++ b/fs/xfs/linux/xfs_vnode.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,6 @@
*/
#include <xfs.h>
-#include <linux/pagemap.h>
uint64_t vn_generation; /* vnode generation number */
@@ -73,19 +72,19 @@ vn_init(void)
* Clean a vnode of filesystem-specific data and prepare it for reuse.
*/
STATIC int
-vn_reclaim(struct vnode *vp)
+vn_reclaim(
+ struct vnode *vp)
{
- int error;
+ int error;
XFS_STATS_INC(xfsstats.vn_reclaim);
-
vn_trace_entry(vp, "vn_reclaim", (inst_t *)__return_address);
/*
* Only make the VOP_RECLAIM call if there are behaviors
* to call.
*/
- if (vp->v_fbhv != NULL) {
+ if (vp->v_fbhv) {
VOP_RECLAIM(vp, error);
if (error)
return -error;
@@ -108,18 +107,19 @@ vn_reclaim(struct vnode *vp)
}
STATIC void
-vn_wakeup(struct vnode *vp)
+vn_wakeup(
+ struct vnode *vp)
{
VN_LOCK(vp);
- if (vp->v_flag & VWAIT) {
+ if (vp->v_flag & VWAIT)
sv_broadcast(vptosync(vp));
- }
vp->v_flag &= ~(VRECLM|VWAIT|VMODIFIED);
VN_UNLOCK(vp, 0);
}
int
-vn_wait(struct vnode *vp)
+vn_wait(
+ struct vnode *vp)
{
VN_LOCK(vp);
if (vp->v_flag & (VINACT | VRECLM)) {
@@ -132,7 +132,8 @@ vn_wait(struct vnode *vp)
}
struct vnode *
-vn_initialize(struct inode *inode)
+vn_initialize(
+ struct inode *inode)
{
struct vnode *vp = LINVFS_GET_VP(inode);
@@ -165,7 +166,9 @@ vn_initialize(struct inode *inode)
* Get a reference on a vnode.
*/
vnode_t *
-vn_get(struct vnode *vp, vmap_t *vmap)
+vn_get(
+ struct vnode *vp,
+ vmap_t *vmap)
{
struct inode *inode;
@@ -175,7 +178,7 @@ vn_get(struct vnode *vp, vmap_t *vmap)
return NULL;
inode = ilookup(vmap->v_vfsp->vfs_super, vmap->v_ino);
- if (inode == NULL) /* Inode not present */
+ if (!inode) /* Inode not present */
return NULL;
vn_trace_exit(vp, "vn_get", (inst_t *)__return_address);
@@ -187,16 +190,17 @@ vn_get(struct vnode *vp, vmap_t *vmap)
* Revalidate the Linux inode from the vnode.
*/
int
-vn_revalidate(struct vnode *vp)
+vn_revalidate(
+ struct vnode *vp)
{
- int error;
struct inode *inode;
vattr_t va;
+ int error;
vn_trace_entry(vp, "vn_revalidate", (inst_t *)__return_address);
ASSERT(vp->v_fbhv != NULL);
- va.va_mask = XFS_AT_STAT|XFS_AT_GENCOUNT;
+ va.va_mask = XFS_AT_STAT;
VOP_GETATTR(vp, &va, 0, NULL, error);
if (!error) {
inode = LINVFS_GET_IP(vp);
@@ -206,12 +210,9 @@ vn_revalidate(struct vnode *vp)
inode->i_gid = va.va_gid;
inode->i_size = va.va_size;
inode->i_blocks = va.va_nblocks;
- inode->i_mtime.tv_sec = va.va_mtime.tv_sec;
- inode->i_mtime.tv_nsec = va.va_mtime.tv_nsec;
- inode->i_ctime.tv_sec = va.va_ctime.tv_sec;
- inode->i_ctime.tv_nsec = va.va_ctime.tv_nsec;
- inode->i_atime.tv_sec = va.va_atime.tv_sec;
- inode->i_atime.tv_nsec = va.va_atime.tv_nsec;
+ inode->i_mtime = va.va_mtime;
+ inode->i_ctime = va.va_ctime;
+ inode->i_atime = va.va_atime;
VUNMODIFY(vp);
}
return -error;
@@ -224,7 +225,9 @@ vn_revalidate(struct vnode *vp)
* get a handle (via vn_get) on the vnode (usually done via a mount/vfs lock).
*/
void
-vn_purge(struct vnode *vp, vmap_t *vmap)
+vn_purge(
+ struct vnode *vp,
+ vmap_t *vmap)
{
vn_trace_entry(vp, "vn_purge", (inst_t *)__return_address);
@@ -284,9 +287,10 @@ again:
* Add a reference to a referenced vnode.
*/
struct vnode *
-vn_hold(struct vnode *vp)
+vn_hold(
+ struct vnode *vp)
{
- struct inode *inode;
+ struct inode *inode;
XFS_STATS_INC(xfsstats.vn_hold);
@@ -302,10 +306,11 @@ vn_hold(struct vnode *vp)
* Call VOP_INACTIVE on last reference.
*/
void
-vn_rele(struct vnode *vp)
+vn_rele(
+ struct vnode *vp)
{
- int vcnt;
- int cache;
+ int vcnt;
+ int cache;
XFS_STATS_INC(xfsstats.vn_rele);
@@ -319,7 +324,7 @@ vn_rele(struct vnode *vp)
* that i_count won't be decremented after we
* return.
*/
- if (vcnt == 0) {
+ if (!vcnt) {
/*
* As soon as we turn this on, noone can find us in vn_get
* until we turn off VINACT or VRECLM
@@ -331,19 +336,14 @@ vn_rele(struct vnode *vp)
* Do not make the VOP_INACTIVE call if there
* are no behaviors attached to the vnode to call.
*/
- if (vp->v_fbhv != NULL) {
+ if (vp->v_fbhv)
VOP_INACTIVE(vp, NULL, cache);
- }
VN_LOCK(vp);
- if (vp->v_flag & VWAIT) {
- if (vp->v_flag & VWAIT) {
- sv_broadcast(vptosync(vp));
- }
- }
+ if (vp->v_flag & VWAIT)
+ sv_broadcast(vptosync(vp));
vp->v_flag &= ~(VINACT|VWAIT|VRECLM|VMODIFIED);
-
}
VN_UNLOCK(vp, 0);
@@ -355,17 +355,16 @@ vn_rele(struct vnode *vp)
* Finish the removal of a vnode.
*/
void
-vn_remove(struct vnode *vp)
+vn_remove(
+ struct vnode *vp)
{
- /* REFERENCED */
- vmap_t vmap;
+ vmap_t vmap;
/* Make sure we don't do this to the same vnode twice */
if (!(vp->v_fbhv))
return;
XFS_STATS_INC(xfsstats.vn_remove);
-
vn_trace_exit(vp, "vn_remove", (inst_t *)__return_address);
/*
diff --git a/fs/xfs/linux/xfs_vnode.h b/fs/xfs/linux/xfs_vnode.h
index f8078d6771bb..5d247729c2bc 100644
--- a/fs/xfs/linux/xfs_vnode.h
+++ b/fs/xfs/linux/xfs_vnode.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -85,10 +85,16 @@ typedef struct vnode {
typedef enum {
VN_BHV_UNKNOWN, /* not specified */
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_t;
#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.
@@ -96,7 +102,6 @@ typedef enum {
#define BHV_TO_VNODE(bdp) ((vnode_t *)BHV_VOBJ(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_init(bhp,name) bhv_head_init(bhp,name)
#define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp)
@@ -127,16 +132,6 @@ extern ushort vttoif_tab[];
#define VWAIT 0x4 /* waiting for VINACT/VRECLM to end */
#define VMODIFIED 0x8 /* XFS inode state possibly differs */
/* 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,
VRWLOCK_WRITE, VRWLOCK_WRITE_DIRECT,
@@ -267,163 +262,92 @@ typedef struct vnodeops {
*/
#define _VOP_(op, vp) (*((vnodeops_t *)(vp)->v_fops)->op)
-#define VOP_READ(vp,file,iov,segs,offset,cr,rv) \
-{ \
- 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_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_READ(vp,file,iov,segs,offset,cr,rv) \
+ 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_SENDFILE(vp,f,off,cnt,act,targ,cr,rv) \
+ rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,cnt,act,targ,cr)
#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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr); \
-}
+ rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr)
#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) \
-{ \
- rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp); \
-}
+ rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp)
#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) \
_VOP_(vop_rwlock, vp)((vp)->v_fbhv, 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- 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) \
-{ \
- (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) \
-{ \
- (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.
* 'last' parameter is unused and left in for IRIX compatibility
*/
#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
*/
#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
*/
#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) \
-{ \
- 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) \
-{ \
- rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags); \
-}
+ rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags)
/*
* Flags for VOP_IFLUSH call
diff --git a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c
index 5d2e91067b79..f50803bd2570 100644
--- a/fs/xfs/pagebuf/page_buf.c
+++ b/fs/xfs/pagebuf/page_buf.c
@@ -1290,7 +1290,7 @@ bio_end_io_pagebuf(
if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
pb->pb_locked = 0;
- pagebuf_iodone(pb, 0, 1);
+ pagebuf_iodone(pb, (pb->pb_flags & PBF_FS_DATAIOD), 1);
}
bio_put(bio);
@@ -1434,7 +1434,7 @@ io_submitted:
if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
pb->pb_locked = 0;
- pagebuf_iodone(pb, 0, 0);
+ pagebuf_iodone(pb, (pb->pb_flags & PBF_FS_DATAIOD), 1);
}
return 0;
@@ -1612,15 +1612,13 @@ pagebuf_daemon(
refrigerator(PF_IOTHREAD);
if (pbd_active == 1) {
- del_timer(&pb_daemon_timer);
- pb_daemon_timer.expires = jiffies +
- pb_params.p_un.flush_interval;
- add_timer(&pb_daemon_timer);
+ mod_timer(&pb_daemon_timer,
+ jiffies + pb_params.p_un.flush_interval);
interruptible_sleep_on(&pbd_waitq);
}
if (pbd_active == 0) {
- del_timer(&pb_daemon_timer);
+ del_timer_sync(&pb_daemon_timer);
}
spin_lock(&pbd_delwrite_lock);
diff --git a/fs/xfs/pagebuf/page_buf.h b/fs/xfs/pagebuf/page_buf.h
index 834410affe8e..0ab5297e6f75 100644
--- a/fs/xfs/pagebuf/page_buf.h
+++ b/fs/xfs/pagebuf/page_buf.h
@@ -96,6 +96,7 @@ typedef enum page_buf_flags_e { /* pb_flags values */
PBF_MAPPABLE = (1 << 9),/* use directly-addressable pages */
PBF_STALE = (1 << 10), /* buffer has been staled, do not find it */
PBF_FS_MANAGED = (1 << 11), /* filesystem controls freeing memory */
+ PBF_FS_DATAIOD = (1 << 12), /* schedule IO completion on fs datad */
/* flags used only as arguments to access routines */
PBF_LOCK = (1 << 13), /* lock requested */
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 2a8c831e5716..bd7e1e614391 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
*/
#include <xfs.h>
-#include <xfs_quota_priv.h>
+#include "xfs_qm.h"
/*
@@ -290,37 +290,45 @@ xfs_qm_dqwarn(
warned = 0;
if (INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
- (INT_GET(d->d_bcount, ARCH_CONVERT) >= INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
+ (INT_GET(d->d_bcount, ARCH_CONVERT) >=
+ INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
if (flags & XFS_QMOPT_DOWARN) {
INT_MOD(d->d_bwarns, ARCH_CONVERT, +1);
warned++;
}
} else {
if (INT_ISZERO(d->d_blk_softlimit, ARCH_CONVERT) ||
- (INT_GET(d->d_bcount, ARCH_CONVERT) < INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
+ (INT_GET(d->d_bcount, ARCH_CONVERT) <
+ INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
INT_ZERO(d->d_bwarns, ARCH_CONVERT);
}
}
if (INT_GET(d->d_ino_softlimit, ARCH_CONVERT) > 0 &&
- (INT_GET(d->d_icount, ARCH_CONVERT) >= INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
+ (INT_GET(d->d_icount, ARCH_CONVERT) >=
+ INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
if (flags & XFS_QMOPT_DOWARN) {
INT_MOD(d->d_iwarns, ARCH_CONVERT, +1);
warned++;
}
} else {
if ((INT_ISZERO(d->d_ino_softlimit, ARCH_CONVERT)) ||
- (INT_GET(d->d_icount, ARCH_CONVERT) < INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
+ (INT_GET(d->d_icount, ARCH_CONVERT) <
+ INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
INT_ZERO(d->d_iwarns, ARCH_CONVERT);
}
}
#ifdef QUOTADEBUG
if (INT_GET(d->d_iwarns, ARCH_CONVERT))
- printk("--------@@Inode warnings running : %Lu >= %Lu\n",
- INT_GET(d->d_icount, ARCH_CONVERT), INT_GET(d->d_ino_softlimit, ARCH_CONVERT));
+ cmn_err(CE_DEBUG,
+ "--------@@Inode warnings running : %Lu >= %Lu",
+ INT_GET(d->d_icount, ARCH_CONVERT),
+ INT_GET(d->d_ino_softlimit, ARCH_CONVERT));
if (INT_GET(d->d_bwarns, ARCH_CONVERT))
- printk("--------@@Blks warnings running : %Lu >= %Lu\n",
- INT_GET(d->d_bcount, ARCH_CONVERT), INT_GET(d->d_blk_softlimit, ARCH_CONVERT));
+ cmn_err(CE_DEBUG,
+ "--------@@Blks warnings running : %Lu >= %Lu",
+ INT_GET(d->d_bcount, ARCH_CONVERT),
+ INT_GET(d->d_blk_softlimit, ARCH_CONVERT));
#endif
return (warned);
}
@@ -869,7 +877,7 @@ xfs_qm_dqget(
if (xfs_do_dqerror) {
if ((xfs_dqerror_dev == mp->m_dev) &&
(xfs_dqreq_num++ % xfs_dqerror_mod) == 0) {
- printk("Returning error in dqget\n");
+ cmn_err(CE_DEBUG, "Returning error in dqget");
return (EIO);
}
}
@@ -894,7 +902,7 @@ xfs_qm_dqget(
* The chain is kept locked during lookup.
*/
if (xfs_qm_dqlookup(mp, id, h, O_dqpp) == 0) {
- XFS_STATS_INC(xfsstats.xs_qm_dqcachehits);
+ XQM_STATS_INC(xqmstats.xs_qm_dqcachehits);
/*
* The dquot was found, moved to the front of the chain,
* taken off the freelist if it was on it, and locked
@@ -906,7 +914,7 @@ xfs_qm_dqget(
xfs_dqtrace_entry(*O_dqpp, "DQGET DONE (FROM CACHE)");
return (0); /* success */
}
- XFS_STATS_INC(xfsstats.xs_qm_dqcachemisses);
+ XQM_STATS_INC(xqmstats.xs_qm_dqcachemisses);
/*
* Dquot cache miss. We don't want to keep the inode lock across
@@ -1006,7 +1014,7 @@ xfs_qm_dqget(
xfs_qm_dqput(tmpdqp);
XFS_DQ_HASH_UNLOCK(h);
xfs_qm_dqdestroy(dqp);
- XFS_STATS_INC(xfsstats.xs_qm_dquot_dups);
+ XQM_STATS_INC(xqmstats.xs_qm_dquot_dups);
goto again;
}
}
@@ -1373,18 +1381,6 @@ xfs_dqlock2(
/*
- * A rarely used accessor. This exists because we don't really want
- * to expose the internals of a dquot to the outside world.
- */
-xfs_dqid_t
-xfs_qm_dqid(
- xfs_dquot_t *dqp)
-{
- return (INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
-}
-
-
-/*
* Take a dquot out of the mount's dqlist as well as the hashlist.
* This is called via unmount as well as quotaoff, and the purge
* will always succeed unless there are soft (temp) references
@@ -1483,145 +1479,41 @@ xfs_qm_dqpurge(
}
-/*
- * Do some primitive error checking on ondisk dquot
- * data structures. Not just for debugging, actually;
- * this can be useful for detecting data corruption mainly due to
- * disk failures.
- */
-/* ARGSUSED */
-int
-xfs_qm_dqcheck(
- xfs_disk_dquot_t *ddq,
- xfs_dqid_t id,
- uint type, /* used only when IO_dorepair is true */
- uint flags,
- char *str)
-{
- int errs;
-
- errs = 0;
- /* ASSERT(flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN)); */
- /*
- * We can encounter an uninitialized dquot buffer for 2 reasons:
- * 1. If we crash while deleting the quotainode(s), and those blks get used
- * for some user data. This is because we take the path of regular
- * file deletion; however, the size field of quotainodes is never
- * updated, so all the tricks that we play in itruncate_finish
- * don't quite matter.
- *
- * 2. We don't play the quota buffers when there's a quotaoff logitem.
- * But the allocation will be replayed so we'll end up with an
- * uninitialized quota block.
- *
- * This is all fine; things are still consistent, and we haven't lost
- * any quota information. Just don't complain about bad dquot blks.
- */
- if (INT_GET(ddq->d_magic, ARCH_CONVERT) != XFS_DQUOT_MAGIC) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x",
- str, id, INT_GET(ddq->d_magic, ARCH_CONVERT), XFS_DQUOT_MAGIC);
- errs++;
- }
- if (INT_GET(ddq->d_version, ARCH_CONVERT) != XFS_DQUOT_VERSION) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : XFS dquot ID 0x%x, version 0x%x != 0x%x",
- str, id, INT_GET(ddq->d_magic, ARCH_CONVERT), XFS_DQUOT_VERSION);
- errs++;
- }
-
- if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER && INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : XFS dquot ID 0x%x, unknown flags 0x%x",
- str, id, INT_GET(ddq->d_flags, ARCH_CONVERT));
- errs++;
- }
-
- if (id != -1 && id != INT_GET(ddq->d_id, ARCH_CONVERT)) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : ondisk-dquot 0x%x, ID mismatch: "
- "0x%x expected, found id 0x%x",
- str, ddq, id, INT_GET(ddq->d_id, ARCH_CONVERT));
- errs++;
- }
-
- if (! errs) {
- if (INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT) &&
- INT_GET(ddq->d_bcount, ARCH_CONVERT) >= INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT)) {
- if (INT_ISZERO(ddq->d_btimer, ARCH_CONVERT) && !INT_ISZERO(ddq->d_id, ARCH_CONVERT)) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : Dquot ID 0x%x (0x%x) "
- "BLK TIMER NOT STARTED",
- str, (int) INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
- errs++;
- }
- }
- if (INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT) &&
- INT_GET(ddq->d_icount, ARCH_CONVERT) >= INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT)) {
- if (INT_ISZERO(ddq->d_itimer, ARCH_CONVERT) && !INT_ISZERO(ddq->d_id, ARCH_CONVERT)) {
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_ALERT,
- "%s : Dquot ID 0x%x (0x%x) "
- "INODE TIMER NOT STARTED",
- str, (int) INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
- errs++;
- }
- }
- }
-
- if (!errs || !(flags & XFS_QMOPT_DQREPAIR))
- return (errs);
-
- if (flags & XFS_QMOPT_DOWARN)
- cmn_err(CE_NOTE, "Re-initializing dquot ID 0x%x", id);
-
- /*
- * Typically, a repair is only requested by quotacheck.
- */
- ASSERT(id != -1);
- ASSERT(flags & XFS_QMOPT_DQREPAIR);
- memset(ddq, 0, sizeof(xfs_dqblk_t));
- xfs_qm_dqinit_core(id, type, (xfs_dqblk_t *)ddq);
- return (errs);
-}
-
#ifdef QUOTADEBUG
void
xfs_qm_dqprint(xfs_dquot_t *dqp)
{
- printk( "-----------KERNEL DQUOT----------------\n");
- printk( "---- dquot ID = %d\n", (int) INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
- printk( "---- type = %s\n", XFS_QM_ISUDQ(dqp) ? "USR" : "GRP");
- printk( "---- fs = 0x%p\n", dqp->q_mount);
- printk( "---- blkno = 0x%x\n", (int) dqp->q_blkno);
- printk( "---- boffset = 0x%x\n", (int) dqp->q_bufoffset);
- printk( "---- blkhlimit = %Lu (0x%x)\n",
- INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT),
- (int) INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT));
- printk( "---- blkslimit = %Lu (0x%x)\n",
- INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT),
- (int)INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT));
- printk( "---- inohlimit = %Lu (0x%x)\n",
- INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT),
- (int)INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT));
- printk( "---- inoslimit = %Lu (0x%x)\n",
- INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT),
- (int)INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT));
- printk( "---- bcount = %Lu (0x%x)\n",
- INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT),
- (int)INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
- printk( "---- icount = %Lu (0x%x)\n",
- INT_GET(dqp->q_core.d_icount, ARCH_CONVERT),
- (int)INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
- printk( "---- btimer = %d\n", (int)INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT));
- printk( "---- itimer = %d\n", (int)INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT));
-
- printk( "---------------------------\n");
+ cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------");
+ cmn_err(CE_DEBUG, "---- dquotID = %d",
+ (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
+ cmn_err(CE_DEBUG, "---- type = %s",
+ XFS_QM_ISUDQ(dqp) ? "USR" : "GRP");
+ cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount);
+ cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno);
+ cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset);
+ cmn_err(CE_DEBUG, "---- blkhlimit = %Lu (0x%x)",
+ INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT),
+ (int) INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT));
+ cmn_err(CE_DEBUG, "---- blkslimit = %Lu (0x%x)",
+ INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT),
+ (int)INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT));
+ cmn_err(CE_DEBUG, "---- inohlimit = %Lu (0x%x)",
+ INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT),
+ (int)INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT));
+ cmn_err(CE_DEBUG, "---- inoslimit = %Lu (0x%x)",
+ INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT),
+ (int)INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT));
+ cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)",
+ INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT),
+ (int)INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
+ cmn_err(CE_DEBUG, "---- icount = %Lu (0x%x)",
+ INT_GET(dqp->q_core.d_icount, ARCH_CONVERT),
+ (int)INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
+ cmn_err(CE_DEBUG, "---- btimer = %d",
+ (int)INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT));
+ cmn_err(CE_DEBUG, "---- itimer = %d",
+ (int)INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT));
+ cmn_err(CE_DEBUG, "---------------------------");
}
#endif
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index 455830aee721..9d68757447e0 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -146,6 +146,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
}
#endif
+
/*
* The following three routines simply manage the q_flock
* semaphore embedded in the dquot. This semaphore synchronizes
@@ -197,7 +198,6 @@ extern void xfs_qm_dqprint(xfs_dquot_t *);
#define xfs_qm_dqprint(a)
#endif
-extern xfs_dquot_t *xfs_qm_dqinit(xfs_mount_t *, xfs_dqid_t, uint);
extern void xfs_qm_dqdestroy(xfs_dquot_t *);
extern int xfs_qm_dqflush(xfs_dquot_t *, uint);
extern int xfs_qm_dqpurge(xfs_dquot_t *, uint);
@@ -206,7 +206,15 @@ extern int xfs_qm_dqlock_nowait(xfs_dquot_t *);
extern int xfs_qm_dqflock_nowait(xfs_dquot_t *);
extern void xfs_qm_dqflock_pushbuf_wait(xfs_dquot_t *dqp);
extern void xfs_qm_adjust_dqtimers(xfs_mount_t *,
- xfs_disk_dquot_t *);
+ xfs_disk_dquot_t *);
extern int xfs_qm_dqwarn(xfs_disk_dquot_t *, uint);
+extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *,
+ xfs_dqid_t, uint, uint, xfs_dquot_t **);
+extern void xfs_qm_dqput(xfs_dquot_t *);
+extern void xfs_qm_dqrele(xfs_dquot_t *);
+extern void xfs_dqlock(xfs_dquot_t *);
+extern void xfs_dqlock2(xfs_dquot_t *, xfs_dquot_t *);
+extern void xfs_dqunlock(xfs_dquot_t *);
+extern void xfs_dqunlock_nonotify(xfs_dquot_t *);
#endif /* __XFS_DQUOT_H__ */
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index 2d5c619543a2..a0562849bca6 100644
--- a/fs/xfs/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
*/
#include <xfs.h>
-#include <xfs_quota_priv.h>
+#include "xfs_qm.h"
/*
diff --git a/fs/xfs/xfs_dquot_item.h b/fs/xfs/quota/xfs_dquot_item.h
index a11987e5efc8..9c6500dabcaa 100644
--- a/fs/xfs/xfs_dquot_item.h
+++ b/fs/xfs/quota/xfs_dquot_item.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2001 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
* under the terms of version 2 of the GNU General Public License as
@@ -32,58 +32,22 @@
#ifndef __XFS_DQUOT_ITEM_H__
#define __XFS_DQUOT_ITEM_H__
-/*
- * These are the structures used to lay out dquots and quotaoff
- * records on the log. Quite similar to those of inodes.
- */
-
-/*
- * log format struct for dquots.
- * The first two fields must be the type and size fitting into
- * 32 bits : log_recovery code assumes that.
- */
-typedef struct xfs_dq_logformat {
- __uint16_t qlf_type; /* dquot log item type */
- __uint16_t qlf_size; /* size of this item */
- xfs_dqid_t qlf_id; /* usr/grp id number : 32 bits */
- __int64_t qlf_blkno; /* blkno of dquot buffer */
- __int32_t qlf_len; /* len of dquot buffer */
- __uint32_t qlf_boffset; /* off of dquot in buffer */
-} xfs_dq_logformat_t;
-
-/*
- * log format struct for QUOTAOFF records.
- * The first two fields must be the type and size fitting into
- * 32 bits : log_recovery code assumes that.
- * We write two LI_QUOTAOFF logitems per quotaoff, the last one keeps a pointer
- * to the first and ensures that the first logitem is taken out of the AIL
- * only when the last one is securely committed.
- */
-typedef struct xfs_qoff_logformat {
- unsigned short qf_type; /* quotaoff log item type */
- unsigned short qf_size; /* size of this item */
- unsigned int qf_flags; /* USR and/or GRP */
- char qf_pad[12]; /* padding for future */
-} xfs_qoff_logformat_t;
-
-
-#ifdef __KERNEL__
-
struct xfs_dquot;
struct xfs_trans;
struct xfs_mount;
+struct xfs_qoff_logitem;
+
typedef struct xfs_dq_logitem {
xfs_log_item_t qli_item; /* common portion */
struct xfs_dquot *qli_dquot; /* dquot ptr */
xfs_lsn_t qli_flush_lsn; /* lsn at last flush */
- unsigned short qli_pushbuf_flag; /* one bit used in push_ail */
+ unsigned short qli_pushbuf_flag; /* 1 bit used in push_ail */
#ifdef DEBUG
uint64_t qli_push_owner;
#endif
xfs_dq_logformat_t qli_format; /* logged structure */
} xfs_dq_logitem_t;
-
typedef struct xfs_qoff_logitem {
xfs_log_item_t qql_item; /* common portion */
struct xfs_qoff_logitem *qql_start_lip; /* qoff-start logitem, if any */
@@ -93,12 +57,10 @@ typedef struct xfs_qoff_logitem {
extern void xfs_qm_dquot_logitem_init(struct xfs_dquot *);
extern xfs_qoff_logitem_t *xfs_qm_qoff_logitem_init(struct xfs_mount *,
- xfs_qoff_logitem_t *, uint);
+ struct xfs_qoff_logitem *, uint);
extern xfs_qoff_logitem_t *xfs_trans_get_qoff_item(struct xfs_trans *,
- xfs_qoff_logitem_t *, uint);
+ struct xfs_qoff_logitem *, uint);
extern void xfs_trans_log_quotaoff_item(struct xfs_trans *,
- xfs_qoff_logitem_t *);
-
-#endif /* __KERNEL__ */
+ struct xfs_qoff_logitem *);
#endif /* __XFS_DQUOT_ITEM_H__ */
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 5971def62882..5b16a1772d61 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -31,8 +31,17 @@
*/
#include <xfs.h>
-#include <xfs_quota_priv.h>
+#include "xfs_qm.h"
+/*
+ * The global quota manager. There is only one of these for the entire
+ * system, _not_ one per file system. XQM keeps track of the overall
+ * quota functionality, including maintaining the freelist and hash
+ * tables of dquots.
+ */
+mutex_t xfs_Gqm_lock;
+struct xfs_qm *xfs_Gqm;
+EXPORT_SYMBOL(xfs_Gqm); /* used by xfsidbg */
kmem_zone_t *qm_dqzone;
kmem_zone_t *qm_dqtrxzone;
@@ -51,24 +60,27 @@ extern mutex_t qcheck_lock;
#ifdef QUOTADEBUG
#define XQM_LIST_PRINT(l, NXT, title) \
{ \
- xfs_dquot_t *dqp; int i = 0;\
- printk("%s (#%d)\n", title, (int) (l)->qh_nelems); \
- for (dqp = (l)->qh_next; dqp != NULL; dqp = dqp->NXT) { \
- printk("\t%d.\t\"%d (%s)\"\t bcnt = %d, icnt = %d refs = %d\n", \
- ++i, (int) INT_GET(dqp->q_core.d_id, ARCH_CONVERT), \
- DQFLAGTO_TYPESTR(dqp), \
- (int) INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT), \
- (int) INT_GET(dqp->q_core.d_icount, ARCH_CONVERT), \
- (int) dqp->q_nrefs); } \
+ xfs_dquot_t *dqp; int i = 0; \
+ cmn_err(CE_DEBUG, "%s (#%d)", title, (int) (l)->qh_nelems); \
+ for (dqp = (l)->qh_next; dqp != NULL; dqp = dqp->NXT) { \
+ cmn_err(CE_DEBUG, " %d. \"%d (%s)\" " \
+ "bcnt = %d, icnt = %d, refs = %d", \
+ ++i, (int) INT_GET(dqp->q_core.d_id, ARCH_CONVERT), \
+ DQFLAGTO_TYPESTR(dqp), \
+ (int) INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT), \
+ (int) INT_GET(dqp->q_core.d_icount, ARCH_CONVERT), \
+ (int) dqp->q_nrefs); } \
}
+#else
+#define XQM_LIST_PRINT(l, NXT, title) do { } while (0)
#endif
/*
* Initialize the XQM structure.
* Note that there is not one quota manager per file system.
*/
-struct xfs_qm *
-xfs_qm_init(void)
+STATIC struct xfs_qm *
+xfs_Gqm_init(void)
{
xfs_qm_t *xqm;
int hsize, i;
@@ -83,11 +95,6 @@ xfs_qm_init(void)
XFS_QM_HASHSIZE_LOW : XFS_QM_HASHSIZE_HIGH;
xqm->qm_dqhashmask = hsize - 1;
- /*
- * XXXsup We could keep reference counts on usr and grp quotas
- * inside XQM separately, and avoid having two hashtables even
- * when only one 'type' is active in the system.
- */
xqm->qm_usr_dqhtable = (xfs_dqhash_t *)kmem_zalloc(hsize *
sizeof(xfs_dqhash_t),
KM_SLEEP);
@@ -135,7 +142,7 @@ xfs_qm_init(void)
#ifdef DEBUG
mutex_init(&qcheck_lock, MUTEX_DEFAULT, "qchk");
#endif
- return (xqm);
+ return xqm;
}
/*
@@ -143,9 +150,9 @@ xfs_qm_init(void)
*/
void
xfs_qm_destroy(
- struct xfs_qm *xqm)
+ struct xfs_qm *xqm)
{
- int hsize, i;
+ int hsize, i;
ASSERT(xqm != NULL);
ASSERT(xqm->qm_nrefs == 0);
@@ -186,7 +193,7 @@ xfs_qm_hold_quotafs_ref(
XFS_QM_LOCK(xfs_Gqm);
if (xfs_Gqm == NULL) {
- if ((xfs_Gqm = xfs_qm_init()) == NULL) {
+ if ((xfs_Gqm = xfs_Gqm_init()) == NULL) {
return (XFS_ERROR(EINVAL));
}
}
@@ -295,7 +302,8 @@ void
xfs_qm_unmount_quotadestroy(
xfs_mount_t *mp)
{
- xfs_qm_destroy_quotainfo(mp);
+ if (mp->m_quotainfo)
+ xfs_qm_destroy_quotainfo(mp);
}
@@ -416,23 +424,18 @@ xfs_qm_unmount_quotas(
xfs_mount_t *mp)
{
xfs_inode_t *uqp, *gqp;
- int error;
-
- error = 0;
+ int error = 0;
/*
* Release the dquots that root inode, et al might be holding,
* before we flush quotas and blow away the quotainfo structure.
*/
ASSERT(mp->m_rootip);
- if (mp->m_rootip->i_udquot || mp->m_rootip->i_gdquot)
- xfs_qm_dqdettach_inode(mp->m_rootip);
- if (mp->m_rbmip &&
- (mp->m_rbmip->i_udquot || mp->m_rbmip->i_gdquot))
- xfs_qm_dqdettach_inode(mp->m_rbmip);
- if (mp->m_rsumip &&
- (mp->m_rsumip->i_udquot || mp->m_rsumip->i_gdquot))
- xfs_qm_dqdettach_inode(mp->m_rsumip);
+ xfs_qm_dqdetach(mp->m_rootip);
+ if (mp->m_rbmip)
+ xfs_qm_dqdetach(mp->m_rbmip);
+ if (mp->m_rsumip)
+ xfs_qm_dqdetach(mp->m_rsumip);
/*
* Flush out the quota inodes.
@@ -579,10 +582,10 @@ xfs_qm_detach_gdquots(
* parameter. This is used when turning off quota accounting for
* users and/or groups, as well as when the filesystem is unmounting.
*/
-int
-xfs_qm_dqpurge_all(
- xfs_mount_t *mp,
- uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/GQUOTA */
+STATIC int
+xfs_qm_dqpurge_int(
+ xfs_mount_t *mp,
+ uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/GQUOTA */
{
xfs_dquot_t *dqp;
uint dqtype;
@@ -652,7 +655,26 @@ xfs_qm_dqpurge_all(
dqp = nextdqp;
}
xfs_qm_mplist_unlock(mp);
- return (nmisses);
+ return nmisses;
+}
+
+int
+xfs_qm_dqpurge_all(
+ xfs_mount_t *mp,
+ uint flags)
+{
+ int ndquots;
+
+ /*
+ * Purge the dquot cache.
+ * None of the dquots should really be busy at this point.
+ */
+ if (mp->m_quotainfo) {
+ while ((ndquots = xfs_qm_dqpurge_int(mp, flags))) {
+ delay(ndquots * 10);
+ }
+ }
+ return 0;
}
STATIC int
@@ -710,7 +732,6 @@ xfs_qm_dqattach_one(
xfs_dqunlock(dqp);
xfs_dqunlock(udqhint);
}
- /* XXX XFS_STATS */
goto done;
}
/*
@@ -871,43 +892,45 @@ xfs_qm_dqattach_grouphint(
*/
int
xfs_qm_dqattach(
- xfs_inode_t *ip,
- uint flags)
+ xfs_inode_t *ip,
+ uint flags)
{
- int error;
- xfs_mount_t *mp;
- uint nquotas;
+ xfs_mount_t *mp = ip->i_mount;
+ uint nquotas = 0;
+ int error = 0;
- mp = ip->i_mount;
- ASSERT(ip->i_ino != mp->m_sb.sb_uquotino &&
- ip->i_ino != mp->m_sb.sb_gquotino);
+ if ((! XFS_IS_QUOTA_ON(mp)) ||
+ (! XFS_NOT_DQATTACHED(mp, ip)) ||
+ (ip->i_ino == mp->m_sb.sb_uquotino) ||
+ (ip->i_ino == mp->m_sb.sb_gquotino))
+ return (0);
ASSERT((flags & XFS_QMOPT_ILOCKED) == 0 ||
XFS_ISLOCKED_INODE_EXCL(ip));
- nquotas = 0;
- error = 0;
if (! (flags & XFS_QMOPT_ILOCKED))
xfs_ilock(ip, XFS_ILOCK_EXCL);
if (XFS_IS_UQUOTA_ON(mp)) {
- if ((error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
+ error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
flags & XFS_QMOPT_DQALLOC,
flags & XFS_QMOPT_DQLOCK,
- NULL, &ip->i_udquot)))
+ NULL, &ip->i_udquot);
+ if (error)
goto done;
nquotas++;
}
ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
if (XFS_IS_GQUOTA_ON(mp)) {
- if ((error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
+ error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
flags & XFS_QMOPT_DQALLOC,
flags & XFS_QMOPT_DQLOCK,
- ip->i_udquot, &ip->i_gdquot)))
- /*
- * Don't worry about the udquot that we may have
- * attached above. It'll get dettached, if not already.
- */
+ ip->i_udquot, &ip->i_gdquot);
+ /*
+ * Don't worry about the udquot that we may have
+ * attached above. It'll get detached, if not already.
+ */
+ if (error)
goto done;
nquotas++;
}
@@ -975,9 +998,12 @@ xfs_qm_dqattach(
* xfs_ireclaim.
*/
void
-xfs_qm_dqdettach_inode(
+xfs_qm_dqdetach(
xfs_inode_t *ip)
{
+ if (!(ip->i_udquot || ip->i_gdquot))
+ return;
+
ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino);
ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino);
if (ip->i_udquot)
@@ -992,33 +1018,8 @@ xfs_qm_dqdettach_inode(
}
}
-int
-xfs_qm_unmount(
- xfs_mount_t *mp)
-{
- vnode_t *vp;
-
- if (XFS_IS_UQUOTA_ON(mp)) {
- vp = XFS_ITOV(XFS_QI_UQIP(mp));
- VN_RELE(vp);
- if (vn_count(vp) > 1)
- cmn_err(CE_WARN, "UQUOTA busy vp=0x%x count=%d",
- vp, vn_count(vp));
- }
- if (XFS_IS_GQUOTA_ON(mp)) {
- vp = XFS_ITOV(XFS_QI_GQIP(mp));
- VN_RELE(vp);
- if (vn_count(vp) > 1)
- cmn_err(CE_WARN, "GQUOTA busy vp=0x%x count=%d",
- vp, vn_count(vp));
- }
-
- return (0);
-}
-
-
/*
- * This is called by xfs_sync and flags arg determines the caller,
+ * This is called by VFS_SYNC and flags arg determines the caller,
* and its motives, as done in xfs_sync.
*
* vfs_sync: SYNC_FSDATA|SYNC_ATTR|SYNC_BDFLUSH 0x31
@@ -1923,9 +1924,7 @@ xfs_qm_quotacheck(
mp->m_qflags &= ~(XFS_GQUOTA_CHKD | XFS_UQUOTA_CHKD);
mp->m_qflags |= flags;
-#ifdef QUOTADEBUG
XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++");
-#endif
error_return:
cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname);
@@ -2033,7 +2032,7 @@ xfs_qm_shake_freelist(
nflushes = 0;
#ifdef QUOTADEBUG
- printk("Shake free 0x%x\n", howmany);
+ cmn_err(CE_DEBUG, "Shake free 0x%x", howmany);
#endif
/* lock order is : hashchainlock, freelistlock, mplistlock */
tryagain:
@@ -2053,7 +2052,7 @@ xfs_qm_shake_freelist(
xfs_qm_freelist_unlock(xfs_Gqm);
if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
return (nreclaimed != howmany);
- XFS_STATS_INC(xfsstats.xs_qm_dqwants);
+ XQM_STATS_INC(xqmstats.xs_qm_dqwants);
goto tryagain;
}
@@ -2067,7 +2066,7 @@ xfs_qm_shake_freelist(
ASSERT(! XFS_DQ_IS_DIRTY(dqp));
ASSERT(dqp->HL_PREVP == NULL);
ASSERT(dqp->MPL_PREVP == NULL);
- XFS_STATS_INC(xfsstats.xs_qm_dqinact_reclaims);
+ XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims);
nextdqp = dqp->dq_flnext;
goto off_freelist;
}
@@ -2132,7 +2131,8 @@ xfs_qm_shake_freelist(
}
xfs_dqtrace_entry(dqp, "DQSHAKE: UNLINKING");
#ifdef QUOTADEBUG
- printk("Shake 0x%p, ID 0x%x\n", dqp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
+ cmn_err(CE_DEBUG, "Shake 0x%p, ID 0x%x\n",
+ dqp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
#endif
ASSERT(dqp->q_nrefs == 0);
nextdqp = dqp->dq_flnext;
@@ -2146,7 +2146,7 @@ xfs_qm_shake_freelist(
XQM_FREELIST_REMOVE(dqp);
xfs_dqunlock(dqp);
nreclaimed++;
- XFS_STATS_INC(xfsstats.xs_qm_dqshake_reclaims);
+ XQM_STATS_INC(xqmstats.xs_qm_dqshake_reclaims);
xfs_qm_dqdestroy(dqp);
dqp = nextdqp;
}
@@ -2220,7 +2220,7 @@ xfs_qm_dqreclaim_one(void)
xfs_qm_freelist_unlock(xfs_Gqm);
if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
return (NULL);
- XFS_STATS_INC(xfsstats.xs_qm_dqwants);
+ XQM_STATS_INC(xqmstats.xs_qm_dqwants);
goto startagain;
}
@@ -2237,7 +2237,7 @@ xfs_qm_dqreclaim_one(void)
XQM_FREELIST_REMOVE(dqp);
xfs_dqunlock(dqp);
dqpout = dqp;
- XFS_STATS_INC(xfsstats.xs_qm_dqinact_reclaims);
+ XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims);
break;
}
@@ -2323,7 +2323,7 @@ xfs_qm_dqalloc_incore(
* Try to recycle a dquot from the freelist.
*/
if ((dqp = xfs_qm_dqreclaim_one())) {
- XFS_STATS_INC(xfsstats.xs_qm_dqreclaims);
+ XQM_STATS_INC(xqmstats.xs_qm_dqreclaims);
/*
* Just zero the core here. The rest will get
* reinitialized by caller. XXX we shouldn't even
@@ -2333,7 +2333,7 @@ xfs_qm_dqalloc_incore(
*O_dqpp = dqp;
return (B_FALSE);
}
- XFS_STATS_INC(xfsstats.xs_qm_dqreclaim_misses);
+ XQM_STATS_INC(xqmstats.xs_qm_dqreclaim_misses);
}
/*
@@ -2361,9 +2361,7 @@ xfs_qm_write_sb_changes(
int error;
#ifdef QUOTADEBUG
- cmn_err(CE_NOTE,
- "Writing superblock quota changes :%s",
- mp->m_fsname);
+ cmn_err(CE_NOTE, "Writing superblock quota changes :%s", mp->m_fsname);
#endif
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
if ((error = xfs_trans_reserve(tp, 0,
@@ -2408,6 +2406,9 @@ xfs_qm_vop_dqalloc(
xfs_dquot_t *uq, *gq;
uint lockflags;
+ if (!XFS_IS_QUOTA_ON(mp))
+ return 0;
+
lockflags = XFS_ILOCK_EXCL;
xfs_ilock(ip, lockflags);
@@ -2564,7 +2565,7 @@ xfs_qm_vop_chown_reserve(
xfs_inode_t *ip,
xfs_dquot_t *udqp,
xfs_dquot_t *gdqp,
- uint privileged)
+ uint flags)
{
int error;
xfs_mount_t *mp;
@@ -2600,13 +2601,11 @@ xfs_qm_vop_chown_reserve(
}
}
- if ((error = xfs_trans_reserve_quota(tp, delblksudq,
- delblksgdq,
- ip->i_d.di_nblocks, 1,
- privileged)))
+ if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
+ delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
+ flags | XFS_QMOPT_RES_REGBLKS)))
return (error);
-
/*
* Do the delayed blks reservations/unreservations now. Since, these
* are done without the help of a transaction, if a reservation fails
@@ -2619,15 +2618,13 @@ xfs_qm_vop_chown_reserve(
*/
ASSERT(delblksudq || delblksgdq);
ASSERT(unresudq || unresgdq);
- if ((error = xfs_trans_reserve_quota(NULL,
- delblksudq, delblksgdq,
- (xfs_qcnt_t)delblks, 0,
- privileged)))
+ if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
+ delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
+ flags | XFS_QMOPT_RES_REGBLKS)))
return (error);
- (void) xfs_trans_unreserve_quota(NULL,
- unresudq, unresgdq,
- (xfs_qcnt_t)delblks, 0,
- 0);
+ xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
+ unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
+ XFS_QMOPT_RES_REGBLKS);
}
return (0);
@@ -2643,6 +2640,9 @@ xfs_qm_vop_rename_dqattach(
ip = i_tab[0];
+ if (! XFS_IS_QUOTA_ON(ip->i_mount))
+ return (0);
+
if (XFS_NOT_DQATTACHED(ip->i_mount, ip)) {
error = xfs_qm_dqattach(ip, 0);
if (error)
@@ -2670,6 +2670,9 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
xfs_dquot_t *udqp,
xfs_dquot_t *gdqp)
{
+ if (!XFS_IS_QUOTA_ON(tp->t_mountp))
+ return;
+
ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp));
@@ -2714,7 +2717,7 @@ xfs_qm_freelist_destroy(xfs_frlist_t *ql)
xfs_dqlock(dqp);
nextdqp = dqp->dq_flnext;
#ifdef QUOTADEBUG
- printk("FREELIST destroy 0x%p\n", dqp);
+ cmn_err(CE_DEBUG, "FREELIST destroy 0x%p", dqp);
#endif
XQM_FREELIST_REMOVE(dqp);
xfs_dqunlock(dqp);
@@ -2753,25 +2756,6 @@ xfs_qm_freelist_unlink(xfs_dquot_t *dq)
xfs_Gqm->qm_dqfreelist.qh_version++;
}
-#ifdef QUOTADEBUG
-void
-xfs_qm_freelist_print(xfs_frlist_t *qlist, char *title)
-{
- xfs_dquot_t *dq;
- int i = 0;
- printk("%s (#%d)\n", title, (int) qlist->qh_nelems);
- FOREACH_DQUOT_IN_FREELIST(dq, qlist) {
- printk("\t%d.\t\"%d (%s:0x%p)\"\t bcnt = %d, icnt = %d "
- "refs = %d\n",
- ++i, INT_GET(dq->q_core.d_id, ARCH_CONVERT),
- DQFLAGTO_TYPESTR(dq), dq,
- (int) INT_GET(dq->q_core.d_bcount, ARCH_CONVERT),
- (int) INT_GET(dq->q_core.d_icount, ARCH_CONVERT),
- (int) dq->q_nrefs);
- }
-}
-#endif
-
void
xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq)
{
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index 1c2c02530862..c4bc3abdd608 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -32,10 +32,16 @@
#ifndef __XFS_QM_H__
#define __XFS_QM_H__
-struct xfs_dqhash;
-struct xfs_inode;
-struct xfs_dquot;
+#include "xfs_dquot_item.h"
+#include "xfs_dquot.h"
+#include "xfs_quota_priv.h"
+#include "xfs_qm_stats.h"
+struct xfs_qm;
+struct xfs_inode;
+
+extern mutex_t xfs_Gqm_lock;
+extern struct xfs_qm *xfs_Gqm;
extern kmem_zone_t *qm_dqzone;
extern kmem_zone_t *qm_dqtrxzone;
@@ -136,24 +142,13 @@ typedef struct xfs_quotainfo {
} xfs_quotainfo_t;
-/*
- * The structure kept inside the xfs_trans_t keep track of dquot changes
- * within a transaction and apply them later.
- */
-typedef struct xfs_dqtrx {
- struct xfs_dquot *qt_dquot; /* the dquot this refers to */
- ulong qt_blk_res; /* blks reserved on a dquot */
- ulong qt_blk_res_used; /* blks used from the reservation */
- ulong qt_ino_res; /* inode reserved on a dquot */
- ulong qt_ino_res_used; /* inodes used from the reservation */
- long qt_bcount_delta; /* dquot blk count changes */
- long qt_delbcnt_delta; /* delayed dquot blk count changes */
- long qt_icount_delta; /* dquot inode count changes */
- ulong qt_rtblk_res; /* # blks reserved on a dquot */
- ulong qt_rtblk_res_used;/* # blks used from reservation */
- long qt_rtbcount_delta;/* dquot realtime blk changes */
- long qt_delrtb_delta; /* delayed RT blk count changes */
-} xfs_dqtrx_t;
+extern xfs_dqtrxops_t xfs_trans_dquot_ops;
+
+extern void xfs_trans_mod_dquot(xfs_trans_t *, xfs_dquot_t *, uint, long);
+extern int xfs_trans_reserve_quota_bydquots(xfs_trans_t *, xfs_mount_t *,
+ xfs_dquot_t *, xfs_dquot_t *, long, long, uint);
+extern void xfs_trans_dqjoin(xfs_trans_t *, xfs_dquot_t *);
+extern void xfs_trans_log_dquot(xfs_trans_t *, xfs_dquot_t *);
/*
* We keep the usr and grp dquots separately so that locking will be easier
@@ -184,9 +179,33 @@ typedef struct xfs_dquot_acct {
extern int xfs_qm_init_quotainfo(xfs_mount_t *);
extern void xfs_qm_destroy_quotainfo(xfs_mount_t *);
+extern int xfs_qm_mount_quotas(xfs_mount_t *);
+extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint);
+extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *);
+extern int xfs_qm_unmount_quotas(xfs_mount_t *);
+extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
+extern int xfs_qm_sync(xfs_mount_t *, short);
+
+/* dquot stuff */
extern void xfs_qm_dqunlink(xfs_dquot_t *);
extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **);
-extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
+extern int xfs_qm_dqattach(xfs_inode_t *, uint);
+extern void xfs_qm_dqdetach(xfs_inode_t *);
+extern int xfs_qm_dqpurge_all(xfs_mount_t *, uint);
+extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
+
+/* vop stuff */
+extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *,
+ uid_t, gid_t, uint,
+ xfs_dquot_t **, xfs_dquot_t **);
+extern void xfs_qm_vop_dqattach_and_dqmod_newinode(
+ xfs_trans_t *, xfs_inode_t *,
+ xfs_dquot_t *, xfs_dquot_t *);
+extern int xfs_qm_vop_rename_dqattach(xfs_inode_t **);
+extern xfs_dquot_t * xfs_qm_vop_chown(xfs_trans_t *, xfs_inode_t *,
+ xfs_dquot_t **, xfs_dquot_t *);
+extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *,
+ xfs_dquot_t *, xfs_dquot_t *, uint);
/* list stuff */
extern void xfs_qm_freelist_init(xfs_frlist_t *);
@@ -199,10 +218,7 @@ extern int xfs_qm_mplist_nowait(xfs_mount_t *);
extern int xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
/* system call interface */
-extern int linvfs_getxstate(struct super_block *, struct fs_quota_stat *);
-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 *);
+extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t);
#ifdef DEBUG
extern int xfs_qm_internalqcheck(xfs_mount_t *);
@@ -210,10 +226,4 @@ extern int xfs_qm_internalqcheck(xfs_mount_t *);
#define xfs_qm_internalqcheck(mp) (0)
#endif
-#ifdef QUOTADEBUG
-extern void xfs_qm_freelist_print(xfs_frlist_t *, char *);
-#else
-#define xfs_qm_freelist_print(a, b) do { } while (0)
-#endif
-
#endif /* __XFS_QM_H__ */
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
new file mode 100644
index 000000000000..665de8bb45e0
--- /dev/null
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -0,0 +1,379 @@
+/*
+ * 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>
+#include <linux/init.h>
+#include "xfs_qm.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_USRQUOTA) :
+ seq_puts(m, "," MNTOPT_UQUOTANOENF);
+ }
+
+ if (mp->m_qflags & XFS_GQUOTA_ACCT) {
+ (mp->m_qflags & XFS_GQUOTA_ENFD) ?
+ seq_puts(m, "," MNTOPT_GRPQUOTA) :
+ 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;
+}
+
+/*
+ * When xfsquotas isn't installed and the superblock had quotas, we need to
+ * clear the quotaflags from superblock.
+ */
+STATIC void
+xfs_mount_reset_sbqflags(
+ xfs_mount_t *mp)
+{
+ xfs_trans_t *tp;
+ unsigned long s;
+
+ mp->m_qflags = 0;
+ /*
+ * It is OK to look at sb_qflags here in mount path,
+ * without SB_LOCK.
+ */
+ if (mp->m_sb.sb_qflags == 0)
+ return;
+ s = XFS_SB_LOCK(mp);
+ mp->m_sb.sb_qflags = 0;
+ XFS_SB_UNLOCK(mp, s);
+
+ /*
+ * if the fs is readonly, let the incore superblock run
+ * with quotas off but don't flush the update out to disk
+ */
+ if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
+ return;
+#ifdef QUOTADEBUG
+ xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes");
+#endif
+ tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
+ if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
+ XFS_DEFAULT_LOG_COUNT)) {
+ xfs_trans_cancel(tp, 0);
+ return;
+ }
+ xfs_mod_sb(tp, XFS_SB_QFLAGS);
+ xfs_trans_commit(tp, 0, NULL);
+}
+
+STATIC int
+xfs_qm_newmount(
+ xfs_mount_t *mp,
+ uint *needquotamount,
+ uint *quotaflags)
+{
+ uint quotaondisk;
+ uint uquotaondisk = 0, gquotaondisk = 0;
+
+ *quotaflags = 0;
+ *needquotamount = B_FALSE;
+
+ quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
+ mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT);
+
+ if (quotaondisk) {
+ uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT;
+ gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
+ }
+
+ /*
+ * If the device itself is read-only, we can't allow
+ * the user to change the state of quota on the mount -
+ * this would generate a transaction on the ro device,
+ * which would lead to an I/O error and shutdown
+ */
+
+ if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
+ (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) ||
+ (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
+ (!gquotaondisk && XFS_IS_GQUOTA_ON(mp))) &&
+ xfs_dev_is_read_only(mp, "changing quota state")) {
+ cmn_err(CE_WARN,
+ "XFS: please mount with%s%s%s.",
+ (!quotaondisk ? "out quota" : ""),
+ (uquotaondisk ? " usrquota" : ""),
+ (gquotaondisk ? " grpquota" : ""));
+ return XFS_ERROR(EPERM);
+ }
+
+ if (XFS_IS_QUOTA_ON(mp) || quotaondisk) {
+ /*
+ * Call mount_quotas at this point only if we won't have to do
+ * a quotacheck.
+ */
+ if (quotaondisk && !XFS_QM_NEED_QUOTACHECK(mp)) {
+ /*
+ * If the xfs quota code isn't installed,
+ * we have to reset the quotachk'd bit.
+ * If an error occured, qm_mount_quotas code
+ * has already disabled quotas. So, just finish
+ * mounting, and get on with the boring life
+ * without disk quotas.
+ */
+ if (xfs_qm_mount_quotas(mp))
+ xfs_mount_reset_sbqflags(mp);
+ } else {
+ /*
+ * Clear the quota flags, but remember them. This
+ * is so that the quota code doesn't get invoked
+ * before we're ready. This can happen when an
+ * inode goes inactive and wants to free blocks,
+ * or via xfs_log_mount_finish.
+ */
+ *needquotamount = B_TRUE;
+ *quotaflags = mp->m_qflags;
+ mp->m_qflags = 0;
+ }
+ }
+
+ return 0;
+}
+
+STATIC int
+xfs_qm_endmount(
+ xfs_mount_t *mp,
+ uint needquotamount,
+ uint quotaflags)
+{
+ if (needquotamount) {
+ ASSERT(mp->m_qflags == 0);
+ mp->m_qflags = quotaflags;
+ if (xfs_qm_mount_quotas(mp))
+ xfs_mount_reset_sbqflags(mp);
+ }
+
+#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
+ if (! (XFS_IS_QUOTA_ON(mp)))
+ xfs_fs_cmn_err(CE_NOTE, mp, "Disk quotas not turned on");
+ else
+ xfs_fs_cmn_err(CE_NOTE, mp, "Disk quotas turned on");
+#endif
+
+#ifdef QUOTADEBUG
+ if (XFS_IS_QUOTA_ON(mp) && xfs_qm_internalqcheck(mp))
+ cmn_err(CE_WARN, "XFS: mount internalqcheck failed");
+#endif
+
+ return 0;
+}
+
+STATIC void
+xfs_qm_dqrele_null(
+ xfs_dquot_t *dq)
+{
+ /*
+ * Called from XFS, where we always check first for a NULL dquot.
+ */
+ if (!dq)
+ return;
+ xfs_qm_dqrele(dq);
+}
+
+
+struct xfs_qmops xfs_qmcore_xfs = {
+ .xfs_qminit = xfs_qm_newmount,
+ .xfs_qmdone = xfs_qm_unmount_quotadestroy,
+ .xfs_qmmount = xfs_qm_endmount,
+ .xfs_qmunmount = xfs_qm_unmount_quotas,
+ .xfs_dqrele = xfs_qm_dqrele_null,
+ .xfs_dqattach = xfs_qm_dqattach,
+ .xfs_dqdetach = xfs_qm_dqdetach,
+ .xfs_dqpurgeall = xfs_qm_dqpurge_all,
+ .xfs_dqvopalloc = xfs_qm_vop_dqalloc,
+ .xfs_dqvopcreate = xfs_qm_vop_dqattach_and_dqmod_newinode,
+ .xfs_dqvoprename = xfs_qm_vop_rename_dqattach,
+ .xfs_dqvopchown = xfs_qm_vop_chown,
+ .xfs_dqvopchownresv = xfs_qm_vop_chown_reserve,
+ .xfs_dqtrxops = &xfs_trans_dquot_ops,
+};
+
+struct bhv_vfsops xfs_qmops = { {
+ 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, },
+};
+
+
+void __init
+xfs_qm_init(void)
+{
+ static char message[] __initdata =
+ KERN_INFO "SGI XFS Quota Management subsystem\n";
+
+ printk(message);
+ mutex_init(&xfs_Gqm_lock, MUTEX_DEFAULT, "xfs_qmlock");
+ vfs_bhv_set_custom(&xfs_qmops, &xfs_qmcore_xfs);
+ xfs_qm_init_procfs();
+}
+
+void __exit
+xfs_qm_exit(void)
+{
+ vfs_bhv_clr_custom(&xfs_qmops);
+ xfs_qm_cleanup_procfs();
+ if (qm_dqzone)
+ kmem_cache_destroy(qm_dqzone);
+ if (qm_dqtrxzone)
+ kmem_cache_destroy(qm_dqtrxzone);
+}
diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c
new file mode 100644
index 000000000000..af0ee82189bb
--- /dev/null
+++ b/fs/xfs/quota/xfs_qm_stats.c
@@ -0,0 +1,117 @@
+/*
+ * 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>
+#include <linux/proc_fs.h>
+#include "xfs_qm.h"
+
+struct xqmstats xqmstats;
+
+STATIC int
+xfs_qm_read_xfsquota(
+ char *buffer,
+ char **start,
+ off_t offset,
+ int count,
+ int *eof,
+ void *data)
+{
+ int len;
+
+ /* maximum; incore; ratio free to inuse; freelist */
+ len = sprintf(buffer, "%d\t%d\t%d\t%u\n",
+ ndquot,
+ xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0,
+ xfs_Gqm? xfs_Gqm->qm_dqfree_ratio : 0,
+ xfs_Gqm? xfs_Gqm->qm_dqfreelist.qh_nelems : 0);
+
+ if (offset >= len) {
+ *start = buffer;
+ *eof = 1;
+ return 0;
+ }
+ *start = buffer + offset;
+ if ((len -= offset) > count)
+ return count;
+ *eof = 1;
+
+ return len;
+}
+
+STATIC int
+xfs_qm_read_stats(
+ char *buffer,
+ char **start,
+ off_t offset,
+ int count,
+ int *eof,
+ void *data)
+{
+ int len;
+
+ /* quota performance statistics */
+ len = sprintf(buffer, "qm %u %u %u %u %u %u %u %u\n",
+ xqmstats.xs_qm_dqreclaims,
+ xqmstats.xs_qm_dqreclaim_misses,
+ xqmstats.xs_qm_dquot_dups,
+ xqmstats.xs_qm_dqcachemisses,
+ xqmstats.xs_qm_dqcachehits,
+ xqmstats.xs_qm_dqwants,
+ xqmstats.xs_qm_dqshake_reclaims,
+ xqmstats.xs_qm_dqinact_reclaims);
+
+ if (offset >= len) {
+ *start = buffer;
+ *eof = 1;
+ return 0;
+ }
+ *start = buffer + offset;
+ if ((len -= offset) > count)
+ return count;
+ *eof = 1;
+
+ return len;
+}
+
+void
+xfs_qm_init_procfs(void)
+{
+ create_proc_read_entry("fs/xfs/xqmstat", 0, 0, xfs_qm_read_stats, NULL);
+ create_proc_read_entry("fs/xfs/xqm", 0, 0, xfs_qm_read_xfsquota, NULL);
+}
+
+void
+xfs_qm_cleanup_procfs(void)
+{
+ remove_proc_entry("fs/xfs/xqm", NULL);
+ remove_proc_entry("fs/xfs/xqmstat", NULL);
+}
diff --git a/fs/xfs/quota/xfs_qm_stats.h b/fs/xfs/quota/xfs_qm_stats.h
new file mode 100644
index 000000000000..8093c5c284ec
--- /dev/null
+++ b/fs/xfs/quota/xfs_qm_stats.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2002 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/
+ */
+#ifndef __XFS_QM_STATS_H__
+#define __XFS_QM_STATS_H__
+
+
+#if defined(CONFIG_PROC_FS) && !defined(XFS_STATS_OFF)
+
+/*
+ * XQM global statistics
+ */
+struct xqmstats {
+ __uint32_t xs_qm_dqreclaims;
+ __uint32_t xs_qm_dqreclaim_misses;
+ __uint32_t xs_qm_dquot_dups;
+ __uint32_t xs_qm_dqcachemisses;
+ __uint32_t xs_qm_dqcachehits;
+ __uint32_t xs_qm_dqwants;
+ __uint32_t xs_qm_dqshake_reclaims;
+ __uint32_t xs_qm_dqinact_reclaims;
+};
+
+extern struct xqmstats xqmstats;
+
+# define XQM_STATS_INC(count) ( (count)++ )
+
+extern void xfs_qm_init_procfs(void);
+extern void xfs_qm_cleanup_procfs(void);
+
+#else
+
+# define XQM_STATS_INC(count) do { } while (0)
+
+static __inline void xfs_qm_init_procfs(void) { };
+static __inline void xfs_qm_cleanup_procfs(void) { };
+
+#endif
+
+#endif /* __XFS_QM_STATS_H__ */
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 92e165dc2032..c5d4939d9b94 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -31,12 +31,12 @@
*/
#include <xfs.h>
-#include <xfs_quota_priv.h>
+#include "xfs_qm.h"
#ifdef DEBUG
-# define qdprintk(s, args...) printk(s, ## args)
+# define qdprintk(s, args...) cmn_err(CE_DEBUG, s, ## args)
#else
-# define qdprintk(s, args...) do { } while (0)
+# define qdprintk(s, args...) do { } while (0)
#endif
STATIC int xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
@@ -58,95 +58,123 @@ STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *,
fs_disk_quota_t *);
+/*
+ * The main distribution switch of all XFS quotactl system calls.
+ */
int
-linvfs_getxstate(
- struct super_block *sb,
- struct fs_quota_stat *fqs)
+xfs_qm_quotactl(
+ struct bhv_desc *bdp,
+ int cmd,
+ int id,
+ xfs_caddr_t addr)
{
- xfs_mount_t *mp;
- vfs_t *vfsp;
+ xfs_mount_t *mp;
+ int error;
+ struct vfs *vfsp;
- vfsp = LINVFS_GET_VFS(sb);
- mp = XFS_BHVTOM(vfsp->vfs_fbhv);
- return -xfs_qm_scall_getqstat(mp, fqs);
-}
+ vfsp = bhvtovfs(bdp);
+ mp = XFS_VFSTOM(vfsp);
-int
-linvfs_setxstate(
- struct super_block *sb,
- unsigned int flags,
- int op)
-{
- xfs_mount_t *mp;
- vfs_t *vfsp;
- uint qflags;
-
- vfsp = LINVFS_GET_VFS(sb);
- mp = XFS_BHVTOM(vfsp->vfs_fbhv);
- if (vfsp->vfs_flag & VFS_RDONLY)
- return -EROFS;
-
- switch (op) {
- case Q_XQUOTARM:
- if (XFS_IS_QUOTA_ON(mp)) {
- qdprintk("cannot remove, quota on: flags=%x\n", flags);
- return -EINVAL;
- }
- qflags = xfs_qm_import_qtype_flags(flags);
- return -xfs_qm_scall_trunc_qfiles(mp, qflags);
- case Q_XQUOTAON:
- qflags = xfs_qm_import_flags(flags);
- return -xfs_qm_scall_quotaon(mp, qflags);
- case Q_XQUOTAOFF:
- qflags = xfs_qm_import_flags(flags);
- if (!XFS_IS_QUOTA_ON(mp))
- return -ESRCH;
- return -xfs_qm_scall_quotaoff(mp, qflags, B_FALSE);
+ if (addr == NULL && cmd != Q_SYNC)
+ return XFS_ERROR(EINVAL);
+ if (id < 0 && cmd != Q_SYNC)
+ return XFS_ERROR(EINVAL);
+
+ /*
+ * The following commands are valid even when quotaoff.
+ */
+ switch (cmd) {
+ /*
+ * truncate quota files. quota must be off.
+ */
+ case Q_XQUOTARM:
+ if (XFS_IS_QUOTA_ON(mp) || addr == NULL)
+ return XFS_ERROR(EINVAL);
+ if (vfsp->vfs_flag & VFS_RDONLY)
+ return XFS_ERROR(EROFS);
+ return (xfs_qm_scall_trunc_qfiles(mp,
+ xfs_qm_import_qtype_flags(*(uint *)addr)));
+ /*
+ * Get quota status information.
+ */
+ case Q_XGETQSTAT:
+ return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));
+
+ /*
+ * QUOTAON for root f/s and quota enforcement on others..
+ * Quota accounting for non-root f/s's must be turned on
+ * at mount time.
+ */
+ case Q_XQUOTAON:
+ if (addr == NULL)
+ return XFS_ERROR(EINVAL);
+ if (vfsp->vfs_flag & VFS_RDONLY)
+ return XFS_ERROR(EROFS);
+ return (xfs_qm_scall_quotaon(mp,
+ xfs_qm_import_flags(*(uint *)addr)));
+ case Q_XQUOTAOFF:
+ if (vfsp->vfs_flag & VFS_RDONLY)
+ return XFS_ERROR(EROFS);
+ break;
+
+ default:
+ break;
}
- qdprintk("cannot set state, invalid op: op=%x flags=%x\n", op, flags);
- return -EINVAL;
-}
-int
-linvfs_getxquota(
- struct super_block *sb,
- int type,
- qid_t id,
- struct fs_disk_quota *fdq)
-{
- xfs_mount_t *mp;
- vfs_t *vfsp;
- int qtype;
-
- vfsp = LINVFS_GET_VFS(sb);
- mp = XFS_BHVTOM(vfsp->vfs_fbhv);
- if (!XFS_IS_QUOTA_ON(mp))
- return -ESRCH;
- qtype = (type == GRPQUOTA)? XFS_DQ_GROUP : XFS_DQ_USER;
- return -xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, qtype, fdq);
-}
+ if (! XFS_IS_QUOTA_ON(mp))
+ return XFS_ERROR(ESRCH);
-int
-linvfs_setxquota(
- struct super_block *sb,
- int type,
- qid_t id,
- struct fs_disk_quota *fdq)
-{
- xfs_mount_t *mp;
- vfs_t *vfsp;
- int qtype;
-
- vfsp = LINVFS_GET_VFS(sb);
- mp = XFS_BHVTOM(vfsp->vfs_fbhv);
- if (!XFS_IS_QUOTA_ON(mp))
- return -ESRCH;
- if (vfsp->vfs_flag & VFS_RDONLY)
- return -EROFS;
- qtype = (type == GRPQUOTA)? XFS_DQ_GROUP : XFS_DQ_USER;
- return xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, qtype, fdq);
-}
+ switch (cmd) {
+ case Q_XQUOTAOFF:
+ if (vfsp->vfs_flag & VFS_RDONLY)
+ return XFS_ERROR(EROFS);
+ error = xfs_qm_scall_quotaoff(mp,
+ xfs_qm_import_flags(*(uint *)addr),
+ B_FALSE);
+ break;
+
+ /*
+ * Defaults to XFS_GETUQUOTA.
+ */
+ case Q_XGETQUOTA:
+ error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
+ (fs_disk_quota_t *)addr);
+ break;
+ /*
+ * Set limits, both hard and soft. Defaults to Q_SETUQLIM.
+ */
+ case Q_XSETQLIM:
+ if (vfsp->vfs_flag & VFS_RDONLY)
+ return XFS_ERROR(EROFS);
+ error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
+ (fs_disk_quota_t *)addr);
+ break;
+
+ case Q_XSETGQLIM:
+ if (vfsp->vfs_flag & VFS_RDONLY)
+ return XFS_ERROR(EROFS);
+ error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
+ (fs_disk_quota_t *)addr);
+ break;
+
+
+ case Q_XGETGQUOTA:
+ error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
+ (fs_disk_quota_t *)addr);
+ break;
+ /*
+ * Quotas are entirely undefined after quotaoff in XFS quotas.
+ * For instance, there's no way to set limits when quotaoff.
+ */
+
+ default:
+ error = XFS_ERROR(EINVAL);
+ break;
+ }
+
+ return (error);
+}
/*
* Turn off quota accounting and/or enforcement for all udquots and/or
@@ -487,6 +515,7 @@ xfs_qm_scall_getqstat(
out->qs_pad = 0;
out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
+
if (mp->m_quotainfo) {
uip = mp->m_quotainfo->qi_uquotaip;
gip = mp->m_quotainfo->qi_gquotaip;
@@ -1048,10 +1077,10 @@ mutex_t qcheck_lock;
#define DQTEST_LIST_PRINT(l, NXT, title) \
{ \
xfs_dqtest_t *dqp; int i = 0;\
- printk("%s (#%d)\n", title, (int) (l)->qh_nelems); \
+ cmn_err(CE_DEBUG, "%s (#%d)", title, (int) (l)->qh_nelems); \
for (dqp = (xfs_dqtest_t *)(l)->qh_next; dqp != NULL; \
dqp = (xfs_dqtest_t *)dqp->NXT) { \
- printk("\t%d\.\t\"%d (%s)\"\t bcnt = %d, icnt = %d\n", \
+ cmn_err(CE_DEBUG, " %d\. \"%d (%s)\" bcnt = %d, icnt = %d", \
++i, dqp->d_id, DQFLAGTO_TYPESTR(dqp), \
dqp->d_bcount, dqp->d_icount); } \
}
@@ -1081,13 +1110,15 @@ STATIC void
xfs_qm_dqtest_print(
xfs_dqtest_t *d)
{
- printk("-----------DQTEST DQUOT----------------\n");
- printk("---- dquot ID = %d\n", d->d_id);
- printk("---- type = %s\n", XFS_QM_ISUDQ(d) ? "USR" : "GRP");
- printk("---- fs = 0x%p\n", d->q_mount);
- printk("---- bcount = %Lu (0x%x)\n", d->d_bcount, (int)d->d_bcount);
- printk("---- icount = %Lu (0x%x)\n", d->d_icount, (int)d->d_icount);
- printk("---------------------------\n");
+ cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------");
+ cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id);
+ cmn_err(CE_DEBUG, "---- type = %s", XFS_QM_ISUDQ(d)? "USR" : "GRP");
+ cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount);
+ cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)",
+ d->d_bcount, (int)d->d_bcount);
+ cmn_err(CE_DEBUG, "---- icount = %Lu (0x%x)",
+ d->d_icount, (int)d->d_icount);
+ cmn_err(CE_DEBUG, "---------------------------");
}
STATIC void
@@ -1101,10 +1132,10 @@ xfs_qm_dqtest_failed(
{
qmtest_nfails++;
if (error)
- printk("quotacheck failed for %d, error = %d\nreason = %s\n",
+ cmn_err(CE_DEBUG, "quotacheck failed id=%d, err=%d\nreason: %s",
INT_GET(d->d_id, ARCH_CONVERT), error, reason);
else
- printk("quotacheck failed for %d (%s) [%d != %d]\n",
+ cmn_err(CE_DEBUG, "quotacheck failed id=%d (%s) [%d != %d]",
INT_GET(d->d_id, ARCH_CONVERT), reason, (int)a, (int)b);
xfs_qm_dqtest_print(d);
if (dqp)
@@ -1119,36 +1150,42 @@ xfs_dqtest_cmp2(
int err = 0;
if (INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) != d->d_icount) {
xfs_qm_dqtest_failed(d, dqp, "icount mismatch",
- INT_GET(dqp->q_core.d_icount, ARCH_CONVERT), d->d_icount, 0);
+ INT_GET(dqp->q_core.d_icount, ARCH_CONVERT),
+ d->d_icount, 0);
err++;
}
if (INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT) != d->d_bcount) {
xfs_qm_dqtest_failed(d, dqp, "bcount mismatch",
- INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT), d->d_bcount, 0);
+ INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT),
+ d->d_bcount, 0);
err++;
}
if (INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT) &&
- INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT) >= INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT)) {
+ INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT) >=
+ INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT)) {
if (INT_ISZERO(dqp->q_core.d_btimer, ARCH_CONVERT) &&
!INT_ISZERO(dqp->q_core.d_id, ARCH_CONVERT)) {
- printk("%d [%s] [0x%p] BLK TIMER NOT STARTED\n",
- d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount);
+ cmn_err(CE_DEBUG,
+ "%d [%s] [0x%p] BLK TIMER NOT STARTED",
+ d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount);
err++;
}
}
if (INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT) &&
- INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT)) {
+ INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >=
+ INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT)) {
if (INT_ISZERO(dqp->q_core.d_itimer, ARCH_CONVERT) &&
!INT_ISZERO(dqp->q_core.d_id, ARCH_CONVERT)) {
- printk("%d [%s] [0x%p] INO TIMER NOT STARTED\n",
- d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount);
+ cmn_err(CE_DEBUG,
+ "%d [%s] [0x%p] INO TIMER NOT STARTED",
+ d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount);
err++;
}
}
-#if 0
+#ifdef QUOTADEBUG
if (!err) {
- printk("%d [%s] [0x%p] qchecked\n",
- d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount);
+ cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked",
+ d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount);
}
#endif
return (err);
@@ -1338,10 +1375,9 @@ xfs_qm_internalqcheck(
}
} while (! done);
if (error) {
- printk("Bulkstat returned error 0x%x\n",
- error);
+ cmn_err(CE_DEBUG, "Bulkstat returned error 0x%x", error);
}
- printk("Checking results against system dquots\n");
+ cmn_err(CE_DEBUG, "Checking results against system dquots");
for (i = 0; i < qmtest_hashmask; i++) {
h1 = &qmtest_udqtab[i];
for (d = (xfs_dqtest_t *) h1->qh_next; d != NULL; ) {
@@ -1360,10 +1396,10 @@ xfs_qm_internalqcheck(
}
if (qmtest_nfails) {
- printk("************** quotacheck failed **************\n");
- printk("failures = %d\n", qmtest_nfails);
+ cmn_err(CE_DEBUG, "******** quotacheck failed ********");
+ cmn_err(CE_DEBUG, "failures = %d", qmtest_nfails);
} else {
- printk("************** quotacheck successful! **************\n");
+ cmn_err(CE_DEBUG, "******** quotacheck successful! ********");
}
kmem_free(qmtest_udqtab, qmtest_hashmask * sizeof(xfs_dqhash_t));
kmem_free(qmtest_gdqtab, qmtest_hashmask * sizeof(xfs_dqhash_t));
diff --git a/fs/xfs/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h
index d016d2b6cf8a..eeda93a2b951 100644
--- a/fs/xfs/xfs_quota_priv.h
+++ b/fs/xfs/quota/xfs_quota_priv.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -67,8 +67,8 @@
#define XQMLCK(h) (mutex_lock(&((h)->qh_lock), PINOD))
#define XQMUNLCK(h) (mutex_unlock(&((h)->qh_lock)))
#ifdef DEBUG
-static inline int
-XQMISLCKD(xfs_dqhash_t *h)
+struct xfs_dqhash;
+static inline int XQMISLCKD(struct xfs_dqhash *h)
{
if (mutex_trylock(&h->qh_lock)) {
mutex_unlock(&h->qh_lock);
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 19c83f9d4700..bf91133c9ae4 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -31,8 +31,9 @@
*/
#include <xfs.h>
-#include <xfs_quota_priv.h>
+#include "xfs_qm.h"
+STATIC void xfs_trans_alloc_dqinfo(xfs_trans_t *);
/*
* Add the locked dquot to the transaction.
@@ -95,7 +96,7 @@ xfs_trans_log_dquot(
* Carry forward whatever is left of the quota blk reservation to
* the spanky new transaction
*/
-void
+STATIC void
xfs_trans_dup_dqinfo(
xfs_trans_t *otp,
xfs_trans_t *ntp)
@@ -104,6 +105,9 @@ xfs_trans_dup_dqinfo(
int i,j;
xfs_dqtrx_t *oqa, *nqa;
+ if (!otp->t_dqinfo)
+ return;
+
xfs_trans_alloc_dqinfo(ntp);
oqa = otp->t_dqinfo->dqa_usrdquots;
nqa = ntp->t_dqinfo->dqa_usrdquots;
@@ -155,15 +159,23 @@ xfs_trans_mod_dquot_byino(
uint field,
long delta)
{
+ xfs_mount_t *mp;
+
ASSERT(tp);
+ mp = tp->t_mountp;
+
+ if (!XFS_IS_QUOTA_ON(mp) ||
+ ip->i_ino == mp->m_sb.sb_uquotino ||
+ ip->i_ino == mp->m_sb.sb_gquotino)
+ return;
if (tp->t_dqinfo == NULL)
xfs_trans_alloc_dqinfo(tp);
- if (XFS_IS_UQUOTA_ON(tp->t_mountp) && ip->i_udquot) {
+ if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) {
(void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
}
- if (XFS_IS_GQUOTA_ON(tp->t_mountp) && ip->i_gdquot) {
+ if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) {
(void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
}
}
@@ -318,7 +330,7 @@ xfs_trans_dqlockedjoin(
* xfs_trans_apply_sb_deltas().
* Go thru all the dquots belonging to this transaction and modify the
* INCORE dquot to reflect the actual usages.
- * Unreserve just the reservations done by this transaction
+ * Unreserve just the reservations done by this transaction.
* dquot is still left locked at exit.
*/
void
@@ -332,6 +344,9 @@ xfs_trans_apply_dquot_deltas(
long totalbdelta;
long totalrtbdelta;
+ if (! (tp->t_flags & XFS_TRANS_DQ_DIRTY))
+ return;
+
ASSERT(tp->t_dqinfo);
qa = tp->t_dqinfo->dqa_usrdquots;
for (j = 0; j < 2; j++) {
@@ -481,13 +496,15 @@ xfs_trans_apply_dquot_deltas(
#ifdef QUOTADEBUG
if (qtrx->qt_rtblk_res != 0)
- printk("RT res %d for 0x%p\n",
- (int) qtrx->qt_rtblk_res,
- dqp);
+ cmn_err(CE_DEBUG, "RT res %d for 0x%p\n",
+ (int) qtrx->qt_rtblk_res, dqp);
#endif
- ASSERT(dqp->q_res_bcount >= INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
- ASSERT(dqp->q_res_icount >= INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
- ASSERT(dqp->q_res_rtbcount >= INT_GET(dqp->q_core.d_rtbcount, ARCH_CONVERT));
+ ASSERT(dqp->q_res_bcount >=
+ INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
+ ASSERT(dqp->q_res_icount >=
+ INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
+ ASSERT(dqp->q_res_rtbcount >=
+ INT_GET(dqp->q_core.d_rtbcount, ARCH_CONVERT));
}
/*
* Do the group quotas next
@@ -503,16 +520,18 @@ xfs_trans_apply_dquot_deltas(
* we simply throw those away, since that's the expected behavior
* when a transaction is curtailed without a commit.
*/
-void
+STATIC void
xfs_trans_unreserve_and_mod_dquots(
- xfs_trans_t *tp)
+ xfs_trans_t *tp)
{
int i, j;
xfs_dquot_t *dqp;
xfs_dqtrx_t *qtrx, *qa;
boolean_t locked;
- ASSERT(tp->t_dqinfo);
+ if (!tp->t_dqinfo || !(tp->t_flags & XFS_TRANS_DQ_DIRTY))
+ return;
+
qa = tp->t_dqinfo->dqa_usrdquots;
for (j = 0; j < 2; j++) {
@@ -604,8 +623,8 @@ xfs_trans_dqresv(
!INT_ISZERO(dqp->q_core.d_id, ARCH_CONVERT) &&
XFS_IS_QUOTA_ENFORCED(dqp->q_mount)) {
#ifdef QUOTADEBUG
- printk("BLK Res: nblks=%ld + resbcount=%Ld > hardlimit=%Ld?\n",
- nblks, *resbcountp, hardlimit);
+ cmn_err(CE_DEBUG, "BLK Res: nblks=%ld + resbcount=%Ld"
+ " > hardlimit=%Ld?", nblks, *resbcountp, hardlimit);
#endif
if (nblks > 0) {
/*
@@ -713,6 +732,7 @@ error_return:
int
xfs_trans_reserve_quota_bydquots(
xfs_trans_t *tp,
+ xfs_mount_t *mp,
xfs_dquot_t *udqp,
xfs_dquot_t *gdqp,
long nblks,
@@ -721,6 +741,9 @@ xfs_trans_reserve_quota_bydquots(
{
int resvd;
+ if (! XFS_IS_QUOTA_ON(mp))
+ return (0);
+
if (tp && tp->t_dqinfo == NULL)
xfs_trans_alloc_dqinfo(tp);
@@ -760,15 +783,22 @@ xfs_trans_reserve_quota_bydquots(
*
* Returns 0 on success, EDQUOT or other errors otherwise
*/
-int
+STATIC int
xfs_trans_reserve_quota_nblks(
xfs_trans_t *tp,
+ xfs_mount_t *mp,
xfs_inode_t *ip,
long nblks,
long ninos,
uint type)
{
- int error;
+ int error;
+
+ if (!XFS_IS_QUOTA_ON(mp))
+ return (0);
+
+ ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
+ ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
#ifdef QUOTADEBUG
if (ip->i_udquot)
@@ -785,7 +815,7 @@ xfs_trans_reserve_quota_nblks(
/*
* Reserve nblks against these dquots, with trans as the mediator.
*/
- error = xfs_trans_reserve_quota_bydquots(tp,
+ error = xfs_trans_reserve_quota_bydquots(tp, mp,
ip->i_udquot, ip->i_gdquot,
nblks, ninos,
type);
@@ -836,17 +866,29 @@ xfs_trans_log_quotaoff_item(
lidp->lid_flags |= XFS_LID_DIRTY;
}
-void
+STATIC void
xfs_trans_alloc_dqinfo(
xfs_trans_t *tp)
{
(tp)->t_dqinfo = kmem_zone_zalloc(xfs_Gqm->qm_dqtrxzone, KM_SLEEP);
}
-void
+STATIC void
xfs_trans_free_dqinfo(
xfs_trans_t *tp)
{
+ if (!tp->t_dqinfo)
+ return;
kmem_zone_free(xfs_Gqm->qm_dqtrxzone, (tp)->t_dqinfo);
(tp)->t_dqinfo = NULL;
}
+
+xfs_dqtrxops_t xfs_trans_dquot_ops = {
+ .qo_dup_dqinfo = xfs_trans_dup_dqinfo,
+ .qo_free_dqinfo = xfs_trans_free_dqinfo,
+ .qo_mod_dquot_byino = xfs_trans_mod_dquot_byino,
+ .qo_apply_dquot_deltas = xfs_trans_apply_dquot_deltas,
+ .qo_reserve_quota_nblks = xfs_trans_reserve_quota_nblks,
+ .qo_reserve_quota_bydquots = xfs_trans_reserve_quota_bydquots,
+ .qo_unreserve_and_mod_dquots = xfs_trans_unreserve_and_mod_dquots,
+};
diff --git a/fs/xfs/support/atomic.h b/fs/xfs/support/atomic.h
index 1cf5eecbf4fe..ac7705d2f5f9 100644
--- a/fs/xfs/support/atomic.h
+++ b/fs/xfs/support/atomic.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -43,20 +43,20 @@
* This is used for two variables in XFS, one of which is a debug trace
* buffer index. They are not accessed via any other atomic operations
* so this is safe. All other atomic increments and decrements in XFS
- * now use the linux built in functions.
+ * now use the Linux built-in functions.
*/
-extern spinlock_t Atomic_spin;
+extern spinlock_t xfs_atomic_spin;
static __inline__ int atomicIncWithWrap(int *ip, int val)
{
unsigned long flags;
int ret;
- spin_lock_irqsave(&Atomic_spin, flags);
+ spin_lock_irqsave(&xfs_atomic_spin, flags);
ret = *ip;
(*ip)++;
if (*ip == val) *ip = 0;
- spin_unlock_irqrestore(&Atomic_spin, flags);
+ spin_unlock_irqrestore(&xfs_atomic_spin, flags);
return ret;
}
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index 59c57fe26f83..cb0aa47974f3 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -55,7 +55,7 @@ assfail(char *a, char *f, int l)
BUG();
}
-#if (defined(DEBUG) || defined(INDUCE_IO_ERRROR))
+#if ((defined(DEBUG) || defined(INDUCE_IO_ERRROR)) && !defined(NO_WANT_RANDOM))
unsigned long
random(void)
@@ -79,7 +79,7 @@ get_thread_id(void)
return current->pid;
}
-#endif /* DEBUG */
+#endif /* DEBUG || INDUCE_IO_ERRROR || !NO_WANT_RANDOM */
void
cmn_err(register int level, char *fmt, ...)
diff --git a/fs/xfs/support/mrlock.c b/fs/xfs/support/mrlock.c
index 1558a8e56be1..0a9b36fe8203 100644
--- a/fs/xfs/support/mrlock.c
+++ b/fs/xfs/support/mrlock.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -272,15 +272,3 @@ mrdemote(mrlock_t *mrp)
}
MRUNLOCK(mrp);
}
-
-int
-mrislocked_access(mrlock_t *mrp)
-{
- return(mrp->mr_count > 0);
-}
-
-int
-mrislocked_update(mrlock_t *mrp)
-{
- return(mrp->mr_count < 0);
-}
diff --git a/fs/xfs/support/mrlock.h b/fs/xfs/support/mrlock.h
index 7004e23b31e8..5f8d7c592075 100644
--- a/fs/xfs/support/mrlock.h
+++ b/fs/xfs/support/mrlock.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -80,7 +80,9 @@ extern void mrlock_init(mrlock_t *, int type, char *name, long sequence);
extern void mrfree(mrlock_t *);
#define mrinit(mrp, name) mrlock_init(mrp, MRLOCK_BARRIER, name, -1)
-#define mraccess(mrp) mraccessf(mrp, 0) /* grab for READ/ACCESS */
-#define mrupdate(mrp) mrupdatef(mrp, 0) /* grab for WRITE/UPDATE */
+#define mraccess(mrp) mraccessf(mrp, 0) /* grab for READ/ACCESS */
+#define mrupdate(mrp) mrupdatef(mrp, 0) /* grab for WRITE/UPDATE */
+#define mrislocked_access(mrp) ((mrp)->mr_count > 0)
+#define mrislocked_update(mrp) ((mrp)->mr_count < 0)
#endif /* __XFS_SUPPORT_MRLOCK_H__ */
diff --git a/fs/xfs/support/mutex.h b/fs/xfs/support/mutex.h
index 346b2d663a08..98bf753e24c8 100644
--- a/fs/xfs/support/mutex.h
+++ b/fs/xfs/support/mutex.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
* Portions Copyright (c) 2002 Christoph Hellwig. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -46,7 +46,6 @@
typedef struct semaphore mutex_t;
#define mutex_init(lock, type, name) sema_init(lock, 1)
-#define init_mutex(ptr, type, name, sequence) sema_init(lock, 1)
#define mutex_destroy(lock) sema_init(lock, -99)
#define mutex_lock(lock, num) down(lock)
#define mutex_trylock(lock) (down_trylock(lock) ? 0 : 1)
diff --git a/fs/xfs/support/time.h b/fs/xfs/support/time.h
index 46b2132cee37..f4c23f80ca5c 100644
--- a/fs/xfs/support/time.h
+++ b/fs/xfs/support/time.h
@@ -45,11 +45,7 @@ static inline void delay(long ticks)
static inline void nanotime(struct timespec *tvp)
{
- struct timeval tv;
-
- do_gettimeofday(&tv);
- tvp->tv_sec = tv.tv_sec;
- tvp->tv_nsec = tv.tv_usec * 1000;
+ *tvp = CURRENT_TIME;
}
#endif /* __XFS_SUPPORT_TIME_H__ */
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h
index eb5370140f53..0c869d102fd0 100644
--- a/fs/xfs/xfs.h
+++ b/fs/xfs/xfs.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -66,6 +66,9 @@
#include <xfs_dir.h>
#include <xfs_dir2.h>
#include <xfs_imap.h>
+#include <xfs_alloc.h>
+#include <xfs_dmapi.h>
+#include <xfs_quota.h>
#include <xfs_mount.h>
#include <xfs_alloc_btree.h>
#include <xfs_bmap_btree.h>
@@ -77,17 +80,11 @@
#include <xfs_dir2_sf.h>
#include <xfs_dinode.h>
#include <xfs_inode.h>
-#include <xfs_alloc.h>
#include <xfs_bmap.h>
#include <xfs_bit.h>
#include <xfs_rtalloc.h>
#include <xfs_error.h>
-#include <xfs_quota.h>
#include <xfs_itable.h>
-#include <xfs_dqblk.h>
-#include <xfs_dquot_item.h>
-#include <xfs_dquot.h>
-#include <xfs_qm.h>
#include <xfs_rw.h>
#include <xfs_da_btree.h>
#include <xfs_dir_leaf.h>
@@ -108,6 +105,5 @@
#include <xfs_trans_priv.h>
#include <xfs_trans_space.h>
#include <xfs_utils.h>
-#include <xfs_dmapi.h>
#endif /* __XFS_H__ */
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index aeebe527657c..9035b4796c3f 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -197,10 +197,8 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
/*
* Attach the dquots to the inode.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- if ((error = xfs_qm_dqattach(dp, 0)))
- return (error);
- }
+ if ((error = XFS_QM_DQATTACH(mp, dp, 0)))
+ return (error);
/*
* If the inode doesn't have an attribute fork, add one.
@@ -280,19 +278,13 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
}
xfs_ilock(dp, XFS_ILOCK_EXCL);
- if (XFS_IS_QUOTA_ON(mp)) {
- if (rsvd) {
- error = xfs_trans_reserve_blkquota_force(args.trans,
- dp, nblks);
- } else {
- error = xfs_trans_reserve_blkquota(args.trans,
- dp, nblks);
- }
- if (error) {
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
- xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES);
- return (error);
- }
+ error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, nblks, 0,
+ rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
+ XFS_QMOPT_RES_REGBLKS);
+ if (error) {
+ xfs_iunlock(dp, XFS_ILOCK_EXCL);
+ xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES);
+ return (error);
}
xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
@@ -483,12 +475,9 @@ xfs_attr_remove(bhv_desc_t *bdp, char *name, int flags, struct cred *cred)
/*
* Attach the dquots to the inode.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- if (XFS_NOT_DQATTACHED(mp, dp)) {
- if ((error = xfs_qm_dqattach(dp, 0)))
- return (error);
- }
- }
+ if ((error = XFS_QM_DQATTACH(mp, dp, 0)))
+ return (error);
+
/*
* Start our first transaction of the day.
*
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 344a52aa9fcd..2f742c82c2d6 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2145,7 +2145,7 @@ xfs_bmap_alloc(
*/
mp = ap->ip->i_mount;
nullfb = ap->firstblock == NULLFSBLOCK;
- rt = (ap->ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && ap->userdata;
+ rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata;
fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
#ifdef __KERNEL__
if (rt) {
@@ -2467,14 +2467,10 @@ xfs_bmap_alloc(
* Adjust the disk quota also. This was reserved
* earlier.
*/
- if (XFS_IS_QUOTA_ON(mp) &&
- ap->ip->i_ino != mp->m_sb.sb_uquotino &&
- ap->ip->i_ino != mp->m_sb.sb_gquotino)
- xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
- ap->wasdel ?
- XFS_TRANS_DQ_DELRTBCOUNT :
+ XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
+ ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
XFS_TRANS_DQ_RTBCOUNT,
- (long)ralen);
+ (long) ralen);
} else
ap->alen = 0;
#endif /* __KERNEL__ */
@@ -2691,14 +2687,10 @@ xfs_bmap_alloc(
* Adjust the disk quota also. This was reserved
* earlier.
*/
- if (XFS_IS_QUOTA_ON(mp) &&
- ap->ip->i_ino != mp->m_sb.sb_uquotino &&
- ap->ip->i_ino != mp->m_sb.sb_gquotino)
- xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
- ap->wasdel ?
- XFS_TRANS_DQ_DELBCOUNT :
+ XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
+ ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT :
XFS_TRANS_DQ_BCOUNT,
- (long)args.len);
+ (long) args.len);
} else {
ap->rval = NULLFSBLOCK;
ap->alen = 0;
@@ -2755,10 +2747,7 @@ xfs_bmap_btree_to_extents(
return error;
xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp);
ip->i_d.di_nblocks--;
- if (XFS_IS_QUOTA_ON(mp) &&
- ip->i_ino != mp->m_sb.sb_uquotino &&
- ip->i_ino != mp->m_sb.sb_gquotino)
- xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
+ XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
xfs_trans_binval(tp, cbp);
if (cur->bc_bufs[0] == cbp)
cur->bc_bufs[0] = NULL;
@@ -2854,10 +2843,7 @@ xfs_bmap_del_extent(
goto done;
do_fx = 0;
nblks = len * mp->m_sb.sb_rextsize;
- if (XFS_IS_QUOTA_ON(mp) &&
- ip->i_ino != mp->m_sb.sb_uquotino &&
- ip->i_ino != mp->m_sb.sb_gquotino)
- qfield = XFS_TRANS_DQ_RTBCOUNT;
+ qfield = XFS_TRANS_DQ_RTBCOUNT;
}
/*
* Ordinary allocation.
@@ -2865,10 +2851,7 @@ xfs_bmap_del_extent(
else {
do_fx = 1;
nblks = del->br_blockcount;
- if (XFS_IS_QUOTA_ON(mp) &&
- ip->i_ino != mp->m_sb.sb_uquotino &&
- ip->i_ino != mp->m_sb.sb_gquotino)
- qfield = XFS_TRANS_DQ_BCOUNT;
+ qfield = XFS_TRANS_DQ_BCOUNT;
}
/*
* Set up del_endblock and cur for later.
@@ -3088,7 +3071,8 @@ xfs_bmap_del_extent(
* Adjust quota data.
*/
if (qfield)
- xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks);
+ XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, qfield, (long)-nblks);
+
/*
* Account for change in delayed indirect blocks.
* Nothing to do for disk quota accounting here.
@@ -3239,10 +3223,7 @@ xfs_bmap_extents_to_btree(
*firstblock = cur->bc_private.b.firstblock = args.fsbno;
cur->bc_private.b.allocated++;
ip->i_d.di_nblocks++;
- if (XFS_IS_QUOTA_ON(mp) &&
- ip->i_ino != mp->m_sb.sb_uquotino &&
- ip->i_ino != mp->m_sb.sb_gquotino)
- xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
+ XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0);
/*
* Fill in the child block.
@@ -3385,11 +3366,8 @@ xfs_bmap_local_to_extents(
xfs_bmap_trace_post_update(fname, "new", ip, 0, whichfork);
XFS_IFORK_NEXT_SET(ip, whichfork, 1);
ip->i_d.di_nblocks = 1;
- if (XFS_IS_QUOTA_ON(args.mp) &&
- ip->i_ino != args.mp->m_sb.sb_uquotino &&
- ip->i_ino != args.mp->m_sb.sb_gquotino)
- xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT,
- 1L);
+ XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip,
+ XFS_TRANS_DQ_BCOUNT, 1L);
flags |= XFS_ILOG_FEXT(whichfork);
} else
ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
@@ -3772,18 +3750,13 @@ xfs_bmap_add_attrfork(
XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT)))
goto error0;
xfs_ilock(ip, XFS_ILOCK_EXCL);
- if (XFS_IS_QUOTA_ON(mp)) {
- if (rsvd) {
- error = xfs_trans_reserve_blkquota_force(tp, ip, blks);
- } else {
- error = xfs_trans_reserve_blkquota(tp, ip, blks);
- }
-
- if (error) {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
- return error;
- }
+ error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, blks, 0, rsvd ?
+ XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
+ XFS_QMOPT_RES_REGBLKS);
+ if (error) {
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
+ return error;
}
if (XFS_IFORK_Q(ip))
goto error1;
@@ -4655,8 +4628,8 @@ xfs_bmapi(
cur = NULL;
if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
ASSERT(wr && tp);
- if ((error = xfs_bmap_local_to_extents(tp, ip, firstblock, total,
- &logflags, whichfork)))
+ if ((error = xfs_bmap_local_to_extents(tp, ip,
+ firstblock, total, &logflags, whichfork)))
goto error0;
}
if (wr && *firstblock == NULLFSBLOCK) {
@@ -4730,9 +4703,8 @@ xfs_bmapi(
* We return EDQUOT if we haven't allocated
* blks already inside this loop;
*/
- if (XFS_IS_QUOTA_ON(ip->i_mount) &&
- xfs_trans_reserve_blkquota(NULL, ip,
- (long)alen)) {
+ if (XFS_TRANS_RESERVE_BLKQUOTA(
+ mp, NULL, ip, (long)alen)) {
if (n == 0) {
*nmap = 0;
ASSERT(cur == NULL);
@@ -4740,12 +4712,10 @@ xfs_bmapi(
}
break;
}
- if (xfs_mod_incore_sb(ip->i_mount,
- XFS_SBS_FDBLOCKS,
+ if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
-(alen + indlen), rsvd)) {
- if (XFS_IS_QUOTA_ON(ip->i_mount))
- xfs_trans_unreserve_blkquota(
- NULL, ip, (long)alen);
+ XFS_TRANS_UNRESERVE_BLKQUOTA(
+ mp, NULL, ip, (long)alen);
break;
}
ip->i_delayed_blks += alen;
@@ -4808,15 +4778,11 @@ xfs_bmapi(
alen = bma.alen;
aoff = bma.off;
ASSERT(*firstblock == NULLFSBLOCK ||
- XFS_FSB_TO_AGNO(ip->i_mount,
- *firstblock) ==
- XFS_FSB_TO_AGNO(ip->i_mount,
- bma.firstblock) ||
+ XFS_FSB_TO_AGNO(mp, *firstblock) ==
+ XFS_FSB_TO_AGNO(mp, bma.firstblock) ||
(flist->xbf_low &&
- XFS_FSB_TO_AGNO(ip->i_mount,
- *firstblock) <
- XFS_FSB_TO_AGNO(ip->i_mount,
- bma.firstblock)));
+ XFS_FSB_TO_AGNO(mp, *firstblock) <
+ XFS_FSB_TO_AGNO(mp, bma.firstblock)));
*firstblock = bma.firstblock;
if (cur)
cur->bc_private.b.firstblock =
@@ -4824,7 +4790,7 @@ xfs_bmapi(
if (abno == NULLFSBLOCK)
break;
if ((ifp->if_flags & XFS_IFBROOT) && !cur) {
- cur = xfs_btree_init_cursor(ip->i_mount,
+ cur = xfs_btree_init_cursor(mp,
tp, NULL, 0, XFS_BTNUM_BMAP,
ip, whichfork);
cur->bc_private.b.firstblock =
@@ -4941,7 +4907,7 @@ xfs_bmapi(
*/
ASSERT(mval->br_blockcount <= len);
if ((ifp->if_flags & XFS_IFBROOT) && !cur) {
- cur = xfs_btree_init_cursor(ip->i_mount,
+ cur = xfs_btree_init_cursor(mp,
tp, NULL, 0, XFS_BTNUM_BMAP,
ip, whichfork);
cur->bc_private.b.firstblock =
@@ -5063,12 +5029,12 @@ error0:
if (cur) {
if (!error) {
ASSERT(*firstblock == NULLFSBLOCK ||
- XFS_FSB_TO_AGNO(ip->i_mount, *firstblock) ==
- XFS_FSB_TO_AGNO(ip->i_mount,
+ XFS_FSB_TO_AGNO(mp, *firstblock) ==
+ XFS_FSB_TO_AGNO(mp,
cur->bc_private.b.firstblock) ||
(flist->xbf_low &&
- XFS_FSB_TO_AGNO(ip->i_mount, *firstblock) <
- XFS_FSB_TO_AGNO(ip->i_mount,
+ XFS_FSB_TO_AGNO(mp, *firstblock) <
+ XFS_FSB_TO_AGNO(mp,
cur->bc_private.b.firstblock)));
*firstblock = cur->bc_private.b.firstblock;
}
@@ -5378,16 +5344,11 @@ xfs_bunmapi(
ASSERT(STARTBLOCKVAL(del.br_startblock) > 0);
xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
(int)del.br_blockcount, rsvd);
- if (XFS_IS_QUOTA_ON(ip->i_mount)) {
- ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
- ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
- if (!isrt)
- xfs_trans_unreserve_blkquota(NULL, ip,
- (long)del.br_blockcount);
- else
- xfs_trans_unreserve_rtblkquota(NULL, ip,
- (long)del.br_blockcount);
- }
+ /* Unreserve our quota space */
+ XFS_TRANS_RESERVE_QUOTA_NBLKS(
+ mp, NULL, ip, -((long)del.br_blockcount), 0,
+ isrt ? XFS_QMOPT_RES_RTBLKS :
+ XFS_QMOPT_RES_REGBLKS);
ip->i_delayed_blks -= del.br_blockcount;
if (cur)
cur->bc_private.b.flags |=
@@ -5556,8 +5517,7 @@ xfs_getbmap(
&& DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)
&& whichfork == XFS_DATA_FORK) {
- error = xfs_dm_send_data_event(DM_EVENT_READ, bdp,
- 0, 0, 0, NULL);
+ error = XFS_SEND_DATA(mp, DM_EVENT_READ, bdp, 0, 0, 0, NULL);
if (error)
return XFS_ERROR(error);
}
@@ -5579,7 +5539,6 @@ xfs_getbmap(
ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
return XFS_ERROR(EINVAL);
-
if (whichfork == XFS_DATA_FORK) {
if (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) {
prealloced = 1;
@@ -5928,10 +5887,13 @@ xfs_check_block(
thispa = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
xfs_bmbt, block, j, dmxr);
}
- if (INT_GET(*thispa, ARCH_CONVERT) == INT_GET(*pp, ARCH_CONVERT)) {
- printk("xfs_check_block: thispa(%d) == pp(%d) %Ld\n",
- j, i, INT_GET(*thispa, ARCH_CONVERT));
- panic("xfs_check_block: ptrs are equal in node\n");
+ if (INT_GET(*thispa, ARCH_CONVERT) ==
+ INT_GET(*pp, ARCH_CONVERT)) {
+ cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld",
+ __FUNCTION__, j, i,
+ INT_GET(*thispa, ARCH_CONVERT));
+ panic("%s: ptrs are equal in node\n",
+ __FUNCTION__);
}
}
}
@@ -6089,12 +6051,13 @@ xfs_bmap_check_leaf_extents(
return;
error0:
- printk("at error0\n");
+ cmn_err(CE_WARN, "%s: at error0", __FUNCTION__);
if (bp_release)
xfs_trans_brelse(NULL, bp);
error_norelse:
- printk("xfs_bmap_check_leaf_extents: BAD after btree leaves for %d extents\n", i);
- panic("xfs_bmap_check_leaf_extents: CORRUPTED BTREE OR SOMETHING");
+ cmn_err(CE_WARN, "%s: BAD after btree leaves for %d extents",
+ i, __FUNCTION__);
+ panic("%s: CORRUPTED BTREE OR SOMETHING", __FUNCTION__);
return;
}
#endif
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index cb0dc44fb9df..a41ea99c034b 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -76,10 +76,6 @@ typedef struct xfs_bmap_free
#define XFS_BMAPI_IGSTATE 0x200 /* Ignore state - */
/* combine contig. space */
#define XFS_BMAPI_CONTIG 0x400 /* must allocate only one extent */
-#define XFS_BMAPI_DIRECT_IO 0x800 /* Flag from cxfs client, not used
- * by xfs directly. Indicates alloc
- * request is for direct I/O not
- * extent conversion by server */
#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAPI_AFLAG)
int xfs_bmapi_aflag(int w);
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index f49fc3fd305e..43a0680371f4 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -629,8 +629,8 @@ xfs_bmbt_delrec(
xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS);
if (INT_GET(left->bb_rightsib, ARCH_CONVERT) != NULLDFSBNO) {
if ((error = xfs_btree_read_bufl(mp, cur->bc_tp,
- INT_GET(left->bb_rightsib, ARCH_CONVERT), 0, &rrbp,
- XFS_BMAP_BTREE_REF))) {
+ INT_GET(left->bb_rightsib, ARCH_CONVERT),
+ 0, &rrbp, XFS_BMAP_BTREE_REF))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
goto error0;
}
@@ -646,10 +646,7 @@ xfs_bmbt_delrec(
cur->bc_private.b.flist, mp);
cur->bc_private.b.ip->i_d.di_nblocks--;
xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
- if (XFS_IS_QUOTA_ON(mp) &&
- cur->bc_private.b.ip->i_ino != mp->m_sb.sb_uquotino &&
- cur->bc_private.b.ip->i_ino != mp->m_sb.sb_gquotino)
- xfs_trans_mod_dquot_byino(cur->bc_tp, cur->bc_private.b.ip,
+ XFS_TRANS_MOD_DQUOT_BYINO(mp, cur->bc_tp, cur->bc_private.b.ip,
XFS_TRANS_DQ_BCOUNT, -1L);
xfs_trans_binval(cur->bc_tp, rbp);
if (bp != lbp) {
@@ -986,13 +983,10 @@ xfs_bmbt_killroot(
#endif
memcpy(pp, cpp, INT_GET(block->bb_numrecs, ARCH_CONVERT) * sizeof(*pp));
xfs_bmap_add_free(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(cbp)), 1,
- cur->bc_private.b.flist, cur->bc_mp);
+ cur->bc_private.b.flist, cur->bc_mp);
ip->i_d.di_nblocks--;
- if (XFS_IS_QUOTA_ON(cur->bc_mp) &&
- ip->i_ino != cur->bc_mp->m_sb.sb_uquotino &&
- ip->i_ino != cur->bc_mp->m_sb.sb_gquotino)
- xfs_trans_mod_dquot_byino(cur->bc_tp, ip, XFS_TRANS_DQ_BCOUNT,
- -1L);
+ XFS_TRANS_MOD_DQUOT_BYINO(cur->bc_mp, cur->bc_tp, ip,
+ XFS_TRANS_DQ_BCOUNT, -1L);
xfs_trans_binval(cur->bc_tp, cbp);
cur->bc_bufs[level - 1] = NULL;
INT_MOD(block->bb_level, ARCH_CONVERT, -1);
@@ -1589,10 +1583,7 @@ xfs_bmbt_split(
cur->bc_private.b.allocated++;
cur->bc_private.b.ip->i_d.di_nblocks++;
xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
- if (XFS_IS_QUOTA_ON(args.mp) &&
- cur->bc_private.b.ip->i_ino != args.mp->m_sb.sb_uquotino &&
- cur->bc_private.b.ip->i_ino != args.mp->m_sb.sb_gquotino)
- xfs_trans_mod_dquot_byino(args.tp, cur->bc_private.b.ip,
+ XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip,
XFS_TRANS_DQ_BCOUNT, 1L);
rbp = xfs_btree_get_bufl(args.mp, args.tp, args.fsbno, 0);
right = XFS_BUF_TO_BMBT_BLOCK(rbp);
@@ -2390,11 +2381,8 @@ xfs_bmbt_newroot(
cur->bc_private.b.firstblock = args.fsbno;
cur->bc_private.b.allocated++;
cur->bc_private.b.ip->i_d.di_nblocks++;
- if (XFS_IS_QUOTA_ON(args.mp) &&
- cur->bc_private.b.ip->i_ino != args.mp->m_sb.sb_uquotino &&
- cur->bc_private.b.ip->i_ino != args.mp->m_sb.sb_gquotino)
- xfs_trans_mod_dquot_byino(args.tp, cur->bc_private.b.ip,
- XFS_TRANS_DQ_BCOUNT, 1L);
+ XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip,
+ XFS_TRANS_DQ_BCOUNT, 1L);
bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0);
cblock = XFS_BUF_TO_BMBT_BLOCK(bp);
*cblock = *block;
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 3f926f6034de..900f6cb80e8e 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -124,6 +124,9 @@ typedef struct page_buf_s xfs_buf_t;
typedef struct pb_target xfs_buftarg_t;
#define xfs_buftarg pb_target
+#define XFS_BUF_DATAIO(x) ((x)->pb_flags |= PBF_FS_DATAIOD)
+#define XFS_BUF_UNDATAIO(x) ((x)->pb_flags &= ~PBF_FS_DATAIOD)
+
#define XFS_BUF_IODONE_FUNC(buf) (buf)->pb_iodone
#define XFS_BUF_SET_IODONE_FUNC(buf, func) \
(buf)->pb_iodone = (func)
@@ -244,7 +247,7 @@ static inline void xfs_buf_relse(page_buf_t *bp)
#define xfs_biodone(pb) \
- pagebuf_iodone(pb, 0, 0)
+ pagebuf_iodone(pb, (pb->pb_flags & PBF_FS_DATAIOD), 0)
#define xfs_incore(buftarg,blkno,len,lockit) \
pagebuf_find(buftarg, blkno ,len, lockit)
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h
index fd7d80ebe2ef..689cbac1b793 100644
--- a/fs/xfs/xfs_clnt.h
+++ b/fs/xfs/xfs_clnt.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -64,16 +64,6 @@ struct xfs_mount_args {
int sunit; /* stripe unit (BBs) */
int swidth; /* stripe width (BBs), multiple of sunit */
uchar_t iosizelog; /* log2 of the preferred I/O size */
-
- /* The remainder is for CXFS support. */
- char **servlist; /* Table of hosts which may be servers */
- int *servlistlen; /* Table of hostname lengths. */
- int slcount; /* Count of hosts which may be servers. */
- int stimeout; /* Server timeout in milliseconds */
- int ctimeout; /* Client timeout in milliseconds */
- char *server; /* Designated server hostname (for remount). */
- int servlen; /* Length of server hostname (for remount). */
- int servcell; /* Server cell (internal testing only) */
};
/*
@@ -101,17 +91,6 @@ struct xfs_mount_args {
#define XFSMNT_IOSIZE 0x00002000 /* optimize for I/O size */
#define XFSMNT_OSYNCISOSYNC 0x00004000 /* o_sync is REALLY o_sync */
/* (osyncisdsync is now default) */
-#define XFSMNT_CLNTONLY 0x00008000 /* cxfs mount as client only */
-#define XFSMNT_UNSHARED 0x00010000 /* cxfs filesystem mounted
- * unshared */
-#define XFSMNT_CHGCLNTONLY 0x00020000 /* changing client only flag */
- /* (for remount only) */
-#define XFSMNT_SERVCELL 0x00040000 /* setting server cell */
- /* (allowed on remount) */
-#define XFSMNT_MAKESERVER 0x00080000 /* become the server (remount */
- /* only) */
-#define XFSMNT_NOTSERVER 0x00100000 /* give up being the server */
- /* (remount only) */
#define XFSMNT_32BITINODES 0x00200000 /* restrict inodes to 32
* bits of address space */
#define XFSMNT_GQUOTA 0x00400000 /* group quota accounting */
@@ -121,10 +100,4 @@ struct xfs_mount_args {
#define XFSMNT_DMAPI 0x02000000 /* enable dmapi/xdsm */
#define XFSMNT_NOLOGFLUSH 0x04000000 /* Don't flush for log blocks */
-/* Did we get any args for CXFS to consume? */
-#define XFSARGS_FOR_CXFSARR(ap) \
- ((ap)->servlist || (ap)->slcount >= 0 || \
- (ap)->stimeout >= 0 || (ap)->ctimeout >= 0 || \
- (ap)->flags & (XFSMNT_CLNTONLY | XFSMNT_UNSHARED))
-
#endif /* __XFS_CLNT_H__ */
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 49dced89c03c..184e0e46bc12 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -32,11 +32,6 @@
#ifndef __XFS_DMAPI_H__
#define __XFS_DMAPI_H__
-#ifdef CONFIG_XFS_DMAPI
-
-#include <dmapi/dmapi.h>
-#include <dmapi/dmapi_kern.h>
-
/* Values used to define the on-disk version of dm_attrname_t. All
* on-disk attribute names start with the 8-byte string "SGI_DMI_".
*
@@ -48,6 +43,42 @@
#define DMATTR_PREFIXLEN 8
#define DMATTR_PREFIXSTRING "SGI_DMI_"
+typedef enum {
+ DM_EVENT_INVALID = -1,
+ DM_EVENT_CANCEL = 0, /* not supported */
+ DM_EVENT_MOUNT = 1,
+ DM_EVENT_PREUNMOUNT = 2,
+ DM_EVENT_UNMOUNT = 3,
+ DM_EVENT_DEBUT = 4, /* not supported */
+ DM_EVENT_CREATE = 5,
+ DM_EVENT_CLOSE = 6, /* not supported */
+ DM_EVENT_POSTCREATE = 7,
+ DM_EVENT_REMOVE = 8,
+ DM_EVENT_POSTREMOVE = 9,
+ DM_EVENT_RENAME = 10,
+ DM_EVENT_POSTRENAME = 11,
+ DM_EVENT_LINK = 12,
+ DM_EVENT_POSTLINK = 13,
+ DM_EVENT_SYMLINK = 14,
+ DM_EVENT_POSTSYMLINK = 15,
+ DM_EVENT_READ = 16,
+ DM_EVENT_WRITE = 17,
+ DM_EVENT_TRUNCATE = 18,
+ DM_EVENT_ATTRIBUTE = 19,
+ DM_EVENT_DESTROY = 20,
+ DM_EVENT_NOSPACE = 21,
+ DM_EVENT_USER = 22,
+ DM_EVENT_MAX = 23
+} dm_eventtype_t;
+#define HAVE_DM_EVENTTYPE_T
+
+typedef enum {
+ DM_RIGHT_NULL,
+ DM_RIGHT_SHARED,
+ DM_RIGHT_EXCL
+} dm_right_t;
+#define HAVE_DM_RIGHT_T
+
/* Defines for determining if an event message should be sent. */
#define DM_EVENT_ENABLED(vfsp, ip, event) ( \
unlikely ((vfsp)->vfs_flag & VFS_DMI) && \
@@ -61,21 +92,6 @@
((io)->io_mount->m_dmevmask & (1 << event)) ) \
)
-/*
- * Macros to turn caller specified delay/block flags into
- * dm_send_xxxx_event flag DM_FLAGS_NDELAY.
- */
-
-#define FILP_DELAY_FLAG(filp) ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) ? \
- DM_FLAGS_NDELAY : 0)
-#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
-
-
-
-/* events valid in dm_set_eventlist() when called with a filesystem handle.
- These events are not persistent.
-*/
-
#define DM_XFS_VALID_FS_EVENTS ( \
(1 << DM_EVENT_PREUNMOUNT) | \
(1 << DM_EVENT_UNMOUNT) | \
@@ -120,7 +136,6 @@
(1 << DM_EVENT_ATTRIBUTE) | \
(1 << DM_EVENT_DESTROY) )
-
/* Events supported by the XFS filesystem. */
#define DM_XFS_SUPPORTED_EVENTS ( \
(1 << DM_EVENT_MOUNT) | \
@@ -144,162 +159,34 @@
(1 << DM_EVENT_DESTROY) )
-extern int
-xfs_dm_mount(
- vfs_t *vfsp,
- char *dir_name,
- char *fsname);
-
-extern int
-xfs_dm_get_fsys_vector(
- bhv_desc_t *bdp,
- dm_fcntl_vector_t *vecrq);
-
-extern int
-xfs_dm_send_data_event(
- dm_eventtype_t event,
- bhv_desc_t *bdp,
- xfs_off_t offset,
- size_t length,
- int flags,
- vrwlock_t *locktype);
-
-extern int
-xfs_dm_send_mmap_event(
- struct vm_area_struct *vma,
- unsigned int wantflag);
-
-#else /* CONFIG_XFS_DMAPI */
-
-/*
- * Flags needed to build with dmapi disabled.
- */
-
-typedef enum {
- DM_EVENT_INVALID = -1,
- DM_EVENT_CANCEL = 0, /* not supported */
- DM_EVENT_MOUNT = 1,
- DM_EVENT_PREUNMOUNT = 2,
- DM_EVENT_UNMOUNT = 3,
- DM_EVENT_DEBUT = 4, /* not supported */
- DM_EVENT_CREATE = 5,
- DM_EVENT_CLOSE = 6, /* not supported */
- DM_EVENT_POSTCREATE = 7,
- DM_EVENT_REMOVE = 8,
- DM_EVENT_POSTREMOVE = 9,
- DM_EVENT_RENAME = 10,
- DM_EVENT_POSTRENAME = 11,
- DM_EVENT_LINK = 12,
- DM_EVENT_POSTLINK = 13,
- DM_EVENT_SYMLINK = 14,
- DM_EVENT_POSTSYMLINK = 15,
- DM_EVENT_READ = 16,
- DM_EVENT_WRITE = 17,
- DM_EVENT_TRUNCATE = 18,
- DM_EVENT_ATTRIBUTE = 19,
- DM_EVENT_DESTROY = 20,
- DM_EVENT_NOSPACE = 21,
- DM_EVENT_USER = 22,
- DM_EVENT_MAX = 23
-} dm_eventtype_t;
-
-typedef enum {
- DM_RIGHT_NULL,
- DM_RIGHT_SHARED,
- DM_RIGHT_EXCL
-} dm_right_t;
-
-/*
- * Defines for determining if an event message should be sent.
- */
-#define DM_EVENT_ENABLED(vfsp, ip, event) 0
-#define DM_EVENT_ENABLED_IO(vfsp, io, event) 0
-
-/*
- * Stubbed out DMAPI delay macros.
- */
-
-#define FILP_DELAY_FLAG(filp) 0
-#define AT_DELAY_FLAG(f) 0
-
-/*
- * Events supported by the XFS filesystem.
- */
-
-#define DM_XFS_VALID_FS_EVENTS 0
-#define DM_XFS_VALID_FILE_EVENTS 0
-#define DM_XFS_VALID_DIRECTORY_EVENTS 0
-#define DM_XFS_SUPPORTED_EVENTS 0
-
/*
- * Dummy definitions used for the flags field on dm_send_*_event().
+ * Definitions used for the flags field on dm_send_*_event().
*/
#define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */
#define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */
/*
- * Stubs for XFS DMAPI utility routines.
+ * Macros to turn caller specified delay/block flags into
+ * dm_send_xxxx_event flag DM_FLAGS_NDELAY.
*/
-static __inline int
-xfs_dm_send_data_event(
- dm_eventtype_t event,
- bhv_desc_t *bdp,
- xfs_off_t offset,
- size_t length,
- int flags,
- vrwlock_t *locktype)
-{
- return ENOSYS;
-}
-
-static __inline int
-xfs_dm_send_mmap_event(
- struct vm_area_struct *vma,
- unsigned int wantflag)
-{
- return 0;
-}
+#define FILP_DELAY_FLAG(filp) ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) ? \
+ DM_FLAGS_NDELAY : 0)
+#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
/*
- * Stubs for routines needed for the X/Open version of DMAPI.
+ * Macros to turn caller specified delay/block flags into
+ * dm_send_xxxx_event flag DM_FLAGS_NDELAY.
*/
-static __inline int
-dm_send_destroy_event(
- bhv_desc_t *bdp,
- dm_right_t vp_right)
-{
- return ENOSYS;
-}
+#define FILP_DELAY_FLAG(filp) ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) ? \
+ DM_FLAGS_NDELAY : 0)
+
-static __inline int
-dm_send_namesp_event(
- dm_eventtype_t event,
- bhv_desc_t *bdp1,
- dm_right_t vp1_right,
- bhv_desc_t *bdp2,
- dm_right_t vp2_right,
- char *name1,
- char *name2,
- mode_t mode,
- int retcode,
- int flags)
-{
- return ENOSYS;
-}
+extern struct bhv_vfsops xfs_dmops;
-static __inline void
-dm_send_unmount_event(
- vfs_t *vfsp,
- vnode_t *vp,
- dm_right_t vfsp_right,
- mode_t mode,
- int retcode,
- int flags)
-{
-}
+extern void xfs_dm_init(void);
+extern void xfs_dm_exit(void);
-#endif /* CONFIG_XFS_DMAPI */
#endif /* __XFS_DMAPI_H__ */
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
new file mode 100644
index 000000000000..7448bac1e642
--- /dev/null
+++ b/fs/xfs/xfs_dmops.c
@@ -0,0 +1,42 @@
+/*
+ * 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>
+
+#ifndef CONFIG_XFS_DMAPI
+xfs_dmops_t xfs_dmcore_xfs = {
+ .xfs_send_data = (xfs_send_data_t)fs_nosys,
+ .xfs_send_mmap = (xfs_send_mmap_t)fs_noerr,
+ .xfs_send_destroy = (xfs_send_destroy_t)fs_nosys,
+ .xfs_send_namesp = (xfs_send_namesp_t)fs_nosys,
+ .xfs_send_unmount = (xfs_send_unmount_t)fs_noval,
+};
+#endif /* CONFIG_XFS_DMAPI */
diff --git a/fs/xfs/xfs_dqblk.h b/fs/xfs/xfs_dqblk.h
deleted file mode 100644
index 40f6a4cd4a7b..000000000000
--- a/fs/xfs/xfs_dqblk.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2000-2001 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/
- */
-#ifndef __XFS_DQBLK_H__
-#define __XFS_DQBLK_H__
-
-/*
- * The ondisk form of a dquot structure.
- */
-#define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */
-#define XFS_DQUOT_VERSION (u_int8_t)0x01 /* latest version number */
-
-/*
- * This is the main portion of the on-disk representation of quota
- * information for a user. This is the q_core of the xfs_dquot_t that
- * is kept in kernel memory. We pad this with some more expansion room
- * to construct the on disk structure.
- */
-typedef struct xfs_disk_dquot {
-/*16*/ u_int16_t d_magic; /* dquot magic = XFS_DQUOT_MAGIC */
-/*8 */ u_int8_t d_version; /* dquot version */
-/*8 */ u_int8_t d_flags; /* XFS_DQ_USER/PROJ/GROUP */
-/*32*/ xfs_dqid_t d_id; /* user,project,group id */
-/*64*/ xfs_qcnt_t d_blk_hardlimit;/* absolute limit on disk blks */
-/*64*/ xfs_qcnt_t d_blk_softlimit;/* preferred limit on disk blks */
-/*64*/ xfs_qcnt_t d_ino_hardlimit;/* maximum # allocated inodes */
-/*64*/ xfs_qcnt_t d_ino_softlimit;/* preferred inode limit */
-/*64*/ xfs_qcnt_t d_bcount; /* disk blocks owned by the user */
-/*64*/ xfs_qcnt_t d_icount; /* inodes owned by the user */
-/*32*/ __int32_t d_itimer; /* zero if within inode limits if not,
- this is when we refuse service */
-/*32*/ __int32_t d_btimer; /* similar to above; for disk blocks */
-/*16*/ xfs_qwarncnt_t d_iwarns; /* warnings issued wrt num inodes */
-/*16*/ xfs_qwarncnt_t d_bwarns; /* warnings issued wrt disk blocks */
-/*32*/ __int32_t d_pad0; /* 64 bit align */
-/*64*/ xfs_qcnt_t d_rtb_hardlimit;/* absolute limit on realtime blks */
-/*64*/ xfs_qcnt_t d_rtb_softlimit;/* preferred limit on RT disk blks */
-/*64*/ xfs_qcnt_t d_rtbcount; /* realtime blocks owned */
-/*32*/ __int32_t d_rtbtimer; /* similar to above; for RT disk blocks */
-/*16*/ xfs_qwarncnt_t d_rtbwarns; /* warnings issued wrt RT disk blocks */
-/*16*/ __uint16_t d_pad;
-} xfs_disk_dquot_t;
-
-/*
- * This is what goes on disk. This is separated from the xfs_disk_dquot because
- * carrying the unnecessary padding would be a waste of memory.
- */
-typedef struct xfs_dqblk {
- xfs_disk_dquot_t dd_diskdq; /* portion that lives incore as well */
- char dd_fill[32]; /* filling for posterity */
-} xfs_dqblk_t;
-
-/*
- * flags for q_flags field in the dquot.
- */
-#define XFS_DQ_USER 0x0001 /* a user quota */
-/* #define XFS_DQ_PROJ 0x0002 -- project quota (IRIX) */
-#define XFS_DQ_GROUP 0x0004 /* a group quota */
-#define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */
-#define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */
-#define XFS_DQ_WANT 0x0020 /* for lookup/reclaim race */
-#define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */
-#define XFS_DQ_MARKER 0x0080 /* sentinel */
-
-/*
- * In the worst case, when both user and group quotas are on,
- * we can have a max of three dquots changing in a single transaction.
- */
-#define XFS_DQUOT_LOGRES(mp) (sizeof(xfs_disk_dquot_t) * 3)
-
-#endif /* __XFS_DQBLK_H__ */
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 14a167f6d848..aa65472385cc 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -591,9 +591,7 @@ xfs_ireclaim(xfs_inode_t *ip)
* Release dquots (and their references) if any. An inode may escape
* xfs_inactive and get here via vn_alloc->vn_reclaim path.
*/
- if (ip->i_udquot || ip->i_gdquot) {
- xfs_qm_dqdettach_inode(ip);
- }
+ XFS_QM_DQDETACH(ip->i_mount, ip);
/*
* Pull our behavior descriptor from the vnode chain.
@@ -611,11 +609,8 @@ xfs_ireclaim(xfs_inode_t *ip)
/*
* This routine removes an about-to-be-destroyed inode from
- * all of the lists in which it is lcoated with the exception
- * of the behavior chain. It is used by xfs_ireclaim and
- * by cxfs relocation cocde, in which case, we are removing
- * the xfs_inode but leaving the vnode alone since it has
- * been transformed into a client vnode.
+ * all of the lists in which it is located with the exception
+ * of the behavior chain.
*/
void
xfs_iextract(
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index f0e286e95617..1a354c8589a5 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -1190,25 +1190,6 @@ xfs_ialloc(
ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
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.
*/
@@ -3599,16 +3580,19 @@ xfs_ichgtime(xfs_inode_t *ip,
nanotime(&tv);
if (flags & XFS_ICHGTIME_MOD) {
- inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
- inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
+ inode->i_mtime = tv;
+ ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
+ ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
}
if (flags & XFS_ICHGTIME_ACC) {
- inode->i_atime.tv_sec = ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec;
- inode->i_atime.tv_nsec = ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec;
+ inode->i_atime = tv;
+ ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec;
+ ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec;
}
if (flags & XFS_ICHGTIME_CHG) {
- inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec;
- inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec;
+ inode->i_ctime = tv;
+ ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec;
+ ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec;
}
/*
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 79227f00b1a1..d58b8aa74dd6 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -154,11 +154,7 @@ typedef struct xfs_iocore {
* Flags in the flags field
*/
-#define XFS_IOCORE_ISXFS 0x01
-#define XFS_IOCORE_ISCXFS 0x02
-#define XFS_IOCORE_RT 0x04
-
-#define IO_IS_XFS(io) ((io)->io_flags & XFS_IOCORE_ISXFS)
+#define XFS_IOCORE_RT 0x1
/*
* xfs_iocore prototypes
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index ea669a083e47..38f7d9dde577 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -33,15 +33,25 @@
#include <xfs.h>
-static xfs_fsize_t
+STATIC xfs_fsize_t
xfs_size_fn(
- xfs_inode_t *ip)
+ xfs_inode_t *ip)
{
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_ioinit = (xfs_ioinit_t) fs_noerr,
+ .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit,
.xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi,
.xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof,
.xfs_iomap_write_direct =
@@ -67,11 +77,9 @@ xfs_iocore_inode_reinit(
{
xfs_iocore_t *io = &ip->i_iocore;
- io->io_flags = XFS_IOCORE_ISXFS;
- if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) {
+ io->io_flags = 0;
+ if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
io->io_flags |= XFS_IOCORE_RT;
- }
-
io->io_dmevmask = ip->i_d.di_dmevmask;
io->io_dmstate = ip->i_d.di_dmstate;
}
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 247e842f3299..18eeda703102 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -136,16 +136,15 @@ xlog_bwrite(
/*
* check log record header for recovery
*/
-
static void
xlog_header_check_dump(xfs_mount_t *mp, xlog_rec_header_t *head)
{
int b;
- printk("xlog_header_check_dump:\n SB : uuid = ");
+ printk("%s: SB : uuid = ", __FUNCTION__);
for (b=0;b<16;b++) printk("%02x",((unsigned char *)&mp->m_sb.sb_uuid)[b]);
printk(", fmt = %d\n",XLOG_FMT);
- printk(" log: uuid = ");
+ printk(" log : uuid = ");
for (b=0;b<16;b++) printk("%02x",((unsigned char *)&head->h_fs_uuid)[b]);
printk(", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
}
@@ -1813,7 +1812,6 @@ xlog_recover_do_reg_buffer(xfs_mount_t *mp,
*/
error = 0;
if (buf_f->blf_flags & (XFS_BLI_UDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
- /* OK, if this returns ENOSYS */
error = xfs_qm_dqcheck((xfs_disk_dquot_t *)
item->ri_buf[i].i_addr,
-1, 0, XFS_QMOPT_DOWARN,
@@ -1821,9 +1819,9 @@ xlog_recover_do_reg_buffer(xfs_mount_t *mp,
}
if (!error)
memcpy(xfs_buf_offset(bp,
- (uint)bit << XFS_BLI_SHIFT), /* dest */
- item->ri_buf[i].i_addr, /* source */
- nbits<<XFS_BLI_SHIFT); /* length */
+ (uint)bit << XFS_BLI_SHIFT), /* dest */
+ item->ri_buf[i].i_addr, /* source */
+ nbits<<XFS_BLI_SHIFT); /* length */
i++;
bit += nbits;
}
@@ -1832,6 +1830,120 @@ xlog_recover_do_reg_buffer(xfs_mount_t *mp,
ASSERT(i == item->ri_total);
} /* xlog_recover_do_reg_buffer */
+/*
+ * Do some primitive error checking on ondisk dquot data structures.
+ */
+int
+xfs_qm_dqcheck(
+ xfs_disk_dquot_t *ddq,
+ xfs_dqid_t id,
+ uint type, /* used only when IO_dorepair is true */
+ uint flags,
+ char *str)
+{
+ xfs_dqblk_t *d = (xfs_dqblk_t *)ddq;
+ int errs = 0;
+
+ /*
+ * We can encounter an uninitialized dquot buffer for 2 reasons:
+ * 1. If we crash while deleting the quotainode(s), and those blks got
+ * used for user data. This is because we take the path of regular
+ * file deletion; however, the size field of quotainodes is never
+ * updated, so all the tricks that we play in itruncate_finish
+ * don't quite matter.
+ *
+ * 2. We don't play the quota buffers when there's a quotaoff logitem.
+ * But the allocation will be replayed so we'll end up with an
+ * uninitialized quota block.
+ *
+ * This is all fine; things are still consistent, and we haven't lost
+ * any quota information. Just don't complain about bad dquot blks.
+ */
+ if (INT_GET(ddq->d_magic, ARCH_CONVERT) != XFS_DQUOT_MAGIC) {
+ if (flags & XFS_QMOPT_DOWARN)
+ cmn_err(CE_ALERT,
+ "%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x",
+ str, id,
+ INT_GET(ddq->d_magic, ARCH_CONVERT), XFS_DQUOT_MAGIC);
+ errs++;
+ }
+ if (INT_GET(ddq->d_version, ARCH_CONVERT) != XFS_DQUOT_VERSION) {
+ if (flags & XFS_QMOPT_DOWARN)
+ cmn_err(CE_ALERT,
+ "%s : XFS dquot ID 0x%x, version 0x%x != 0x%x",
+ str, id,
+ INT_GET(ddq->d_magic, ARCH_CONVERT), XFS_DQUOT_VERSION);
+ errs++;
+ }
+
+ if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER &&
+ INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) {
+ if (flags & XFS_QMOPT_DOWARN)
+ cmn_err(CE_ALERT,
+ "%s : XFS dquot ID 0x%x, unknown flags 0x%x",
+ str, id, INT_GET(ddq->d_flags, ARCH_CONVERT));
+ errs++;
+ }
+
+ if (id != -1 && id != INT_GET(ddq->d_id, ARCH_CONVERT)) {
+ if (flags & XFS_QMOPT_DOWARN)
+ cmn_err(CE_ALERT,
+ "%s : ondisk-dquot 0x%x, ID mismatch: "
+ "0x%x expected, found id 0x%x",
+ str, ddq, id, INT_GET(ddq->d_id, ARCH_CONVERT));
+ errs++;
+ }
+
+ if (! errs) {
+ if (INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT) &&
+ INT_GET(ddq->d_bcount, ARCH_CONVERT) >=
+ INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT)) {
+ if (INT_ISZERO(ddq->d_btimer, ARCH_CONVERT) &&
+ !INT_ISZERO(ddq->d_id, ARCH_CONVERT)) {
+ if (flags & XFS_QMOPT_DOWARN)
+ cmn_err(CE_ALERT,
+ "%s : Dquot ID 0x%x (0x%x) "
+ "BLK TIMER NOT STARTED",
+ str, (int)
+ INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
+ errs++;
+ }
+ }
+ if (INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT) &&
+ INT_GET(ddq->d_icount, ARCH_CONVERT) >=
+ INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT)) {
+ if (INT_ISZERO(ddq->d_itimer, ARCH_CONVERT) &&
+ !INT_ISZERO(ddq->d_id, ARCH_CONVERT)) {
+ if (flags & XFS_QMOPT_DOWARN)
+ cmn_err(CE_ALERT,
+ "%s : Dquot ID 0x%x (0x%x) "
+ "INODE TIMER NOT STARTED",
+ str, (int)
+ INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
+ errs++;
+ }
+ }
+ }
+
+ if (!errs || !(flags & XFS_QMOPT_DQREPAIR))
+ return errs;
+
+ if (flags & XFS_QMOPT_DOWARN)
+ cmn_err(CE_NOTE, "Re-initializing dquot ID 0x%x", id);
+
+ /*
+ * Typically, a repair is only requested by quotacheck.
+ */
+ ASSERT(id != -1);
+ ASSERT(flags & XFS_QMOPT_DQREPAIR);
+ memset(d, 0, sizeof(xfs_dqblk_t));
+ INT_SET(d->dd_diskdq.d_magic, ARCH_CONVERT, XFS_DQUOT_MAGIC);
+ INT_SET(d->dd_diskdq.d_version, ARCH_CONVERT, XFS_DQUOT_VERSION);
+ INT_SET(d->dd_diskdq.d_id, ARCH_CONVERT, id);
+ INT_SET(d->dd_diskdq.d_flags, ARCH_CONVERT, type);
+
+ return errs;
+}
/*
* Perform a dquot buffer recovery.
@@ -2335,8 +2447,6 @@ xlog_recover_do_dquot_trans(xlog_t *log,
dq_f->qlf_id,
0, XFS_QMOPT_DOWARN,
"xlog_recover_do_dquot_trans (log copy)"))) {
- if (error == ENOSYS)
- return (0);
return XFS_ERROR(EIO);
}
ASSERT(dq_f->qlf_len == 1);
@@ -2923,8 +3033,6 @@ xlog_recover_process_iunlinks(xlog_t *log)
/*
* Prevent any DMAPI event from being sent while in this function.
- * Not a problem for xfs since the file system isn't mounted
- * yet. It is a problem for cxfs recovery.
*/
mp_dmevmask = mp->m_dmevmask;
mp->m_dmevmask = 0;
@@ -2982,11 +3090,8 @@ xlog_recover_process_iunlinks(xlog_t *log)
* Prevent any DMAPI event from
* being sent when the
* reference on the inode is
- * dropped. Not a problem for
- * xfs since the file system
- * isn't mounted yet. It is a
- * problem for cxfs recovery.
- */
+ * dropped.
+ */
ip->i_d.di_dmevmask = 0;
/*
diff --git a/fs/xfs/xfs_macros.c b/fs/xfs/xfs_macros.c
index 316443b4e4bf..a4b66e0ddbc5 100644
--- a/fs/xfs/xfs_macros.c
+++ b/fs/xfs/xfs_macros.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -358,6 +358,14 @@ xfs_bhvtom(bhv_desc_t *bdp)
}
#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)
int
xfs_bm_maxlevels(xfs_mount_t *mp, int w)
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 398673b87f22..c3f64fb7711f 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -32,16 +32,14 @@
#include <xfs.h>
-STATIC void xfs_mount_reset_sbqflags(xfs_mount_t *);
STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t);
STATIC int xfs_uuid_mount(xfs_mount_t *);
+STATIC void xfs_uuid_unmount(xfs_mount_t *mp);
mutex_t xfs_uuidtabmon; /* monitor for uuidtab */
STATIC int xfs_uuidtab_size;
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);
static struct {
@@ -120,10 +118,9 @@ xfs_mount_init(void)
spinlock_init(&mp->m_freeze_lock, "xfs_freeze");
init_sv(&mp->m_wait_unfreeze, SV_DEFAULT, "xfs_freeze", 0);
atomic_set(&mp->m_active_trans, 0);
- mp->m_cxfstype = XFS_CXFS_NOT;
return mp;
-} /* xfs_mount_init */
+}
/*
* Free up the resources associated with a mount structure. Assume that
@@ -146,34 +143,29 @@ xfs_mount_free(
for (agno = 0; agno < mp->m_maxagi; agno++)
if (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,
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);
spinlock_destroy(&mp->m_sb_lock);
mutex_destroy(&mp->m_ilock);
freesema(&mp->m_growlock);
+ if (mp->m_quotainfo)
+ XFS_QM_DONE(mp);
- if (mp->m_fsname != NULL) {
+ if (mp->m_fsname != NULL)
kmem_free(mp->m_fsname, mp->m_fsname_len);
- }
- if (mp->m_quotainfo != NULL) {
- xfs_qm_unmount_quotadestroy(mp);
- }
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);
sv_destroy(&mp->m_wait_unfreeze);
kmem_free(mp, sizeof(xfs_mount_t));
@@ -605,21 +597,17 @@ xfs_mountfs(
{
xfs_buf_t *bp;
xfs_sb_t *sbp = &(mp->m_sb);
- int error = 0;
xfs_inode_t *rip;
vnode_t *rvp = 0;
- int readio_log;
- int writeio_log;
+ int readio_log, writeio_log;
vmap_t vmap;
xfs_daddr_t d;
- extern xfs_ioops_t xfs_iocore_xfs; /* from xfs_iocore.c */
__uint64_t ret64;
- uint quotaflags, quotaondisk;
- uint uquotaondisk = 0, gquotaondisk = 0;
- boolean_t needquotamount;
__int64_t update_flags;
+ uint quotamount, quotaflags;
int agno, noio;
int uuid_mounted = 0;
+ int error = 0;
noio = dev == 0 && mp->m_sb_bp != NULL;
if (mp->m_sb_bp == NULL) {
@@ -644,7 +632,8 @@ xfs_mountfs(
if ((BBTOB(mp->m_dalign) & mp->m_blockmask) ||
(BBTOB(mp->m_swidth) & mp->m_blockmask)) {
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);
goto error1;
}
@@ -664,7 +653,8 @@ xfs_mountfs(
mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth);
} else {
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);
goto error1;
}
@@ -718,7 +708,8 @@ xfs_mountfs(
* since a single partition filesystem is identical to a single
* 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)) {
error = XFS_ERROR(EINVAL);
goto error1;
@@ -859,9 +850,6 @@ xfs_mountfs(
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
* set "sequence" number out of a UUID.
@@ -953,54 +941,22 @@ xfs_mountfs(
ASSERT(rip != NULL);
rvp = XFS_ITOV(rip);
+ VMAP(rvp, vmap);
+
if (unlikely((rip->i_d.di_mode & IFMT) != IFDIR)) {
cmn_err(CE_WARN, "XFS: corrupted root inode");
- VMAP(rvp, vmap);
prdev("Root inode %llu is not a directory",
mp->m_dev, (unsigned long long)rip->i_ino);
xfs_iunlock(rip, XFS_ILOCK_EXCL);
- VN_RELE(rvp);
- vn_purge(rvp, &vmap);
XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
mp);
error = XFS_ERROR(EFSCORRUPTED);
- goto error3;
+ goto error4;
}
mp->m_rootip = rip; /* save it */
xfs_iunlock(rip, XFS_ILOCK_EXCL);
- quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
- mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT);
-
- if (quotaondisk) {
- uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT;
- gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
- }
-
- /*
- * If the device itself is read-only, we can't allow
- * the user to change the state of quota on the mount -
- * this would generate a transaction on the ro device,
- * which would lead to an I/O error and shutdown
- */
-
- if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
- (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) ||
- (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
- (!gquotaondisk && XFS_IS_GQUOTA_ON(mp))) &&
- xfs_dev_is_read_only(mp, "changing quota state")) {
- cmn_err(CE_WARN,
- "XFS: please mount with%s%s%s.",
- (!quotaondisk ? "out quota" : ""),
- (uquotaondisk ? " usrquota" : ""),
- (gquotaondisk ? " grpquota" : ""));
- VN_RELE(rvp);
- vn_remove(rvp);
- error = XFS_ERROR(EPERM);
- goto error3;
- }
-
/*
* Initialize realtime inode pointers in the mount structure
*/
@@ -1009,10 +965,7 @@ xfs_mountfs(
* Free up the root inode.
*/
cmn_err(CE_WARN, "XFS: failed to read RT inodes");
- VMAP(rvp, vmap);
- VN_RELE(rvp);
- vn_purge(rvp, &vmap);
- goto error3;
+ goto error4;
}
/*
@@ -1022,41 +975,11 @@ xfs_mountfs(
if (update_flags && !(vfsp->vfs_flag & VFS_RDONLY))
xfs_mount_log_sbunit(mp, update_flags);
- quotaflags = 0;
- needquotamount = B_FALSE;
-
/*
- * Figure out if we'll need to do a quotacheck.
+ * Initialise the XFS quota management subsystem for this mount
*/
- if (XFS_IS_QUOTA_ON(mp) || quotaondisk) {
- /*
- * Call mount_quotas at this point only if we won't have to do
- * a quotacheck.
- */
- if (quotaondisk && !XFS_QM_NEED_QUOTACHECK(mp)) {
- /*
- * If the xfs quota code isn't installed,
- * we have to reset the quotachk'd bit.
- * If an error occurred, qm_mount_quotas code
- * has already disabled quotas. So, just finish
- * mounting, and get on with the boring life
- * without disk quotas.
- */
- if (xfs_qm_mount_quotas(mp))
- xfs_mount_reset_sbqflags(mp);
- } else {
- /*
- * Clear the quota flags, but remember them. This
- * is so that the quota code doesn't get invoked
- * before we're ready. This can happen when an
- * inode goes inactive and wants to free blocks,
- * or via xfs_log_mount_finish.
- */
- quotaflags = mp->m_qflags;
- mp->m_qflags = 0;
- needquotamount = B_TRUE;
- }
- }
+ if ((error = XFS_QM_INIT(mp, &quotamount, &quotaflags)))
+ goto error4;
/*
* Finish recovering the file system. This part needed to be
@@ -1066,30 +989,23 @@ xfs_mountfs(
error = xfs_log_mount_finish(mp, mfsi_flags);
if (error) {
cmn_err(CE_WARN, "XFS: log mount finish failed");
- goto error3;
- }
-
- if (needquotamount) {
- ASSERT(mp->m_qflags == 0);
- mp->m_qflags = quotaflags;
- if (xfs_qm_mount_quotas(mp))
- xfs_mount_reset_sbqflags(mp);
+ goto error4;
}
-#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
- if (! (XFS_IS_QUOTA_ON(mp)))
- xfs_fs_cmn_err(CE_NOTE, mp, "Disk quotas not turned on");
- else
- xfs_fs_cmn_err(CE_NOTE, mp, "Disk quotas turned on");
-#endif
-
-#ifdef QUOTADEBUG
- if (XFS_IS_QUOTA_ON(mp) && xfs_qm_internalqcheck(mp))
- cmn_err(CE_WARN, "XFS: mount internalqcheck failed");
-#endif
+ /*
+ * Complete the quota initialisation, post-log-replay component.
+ */
+ if ((error = XFS_QM_MOUNT(mp, quotamount, quotaflags)))
+ goto error4;
- return (0);
+ return 0;
+ error4:
+ /*
+ * Free up the root inode.
+ */
+ VN_RELE(rvp);
+ vn_purge(rvp, &vmap);
error3:
xfs_log_unmount_dealloc(mp);
error2:
@@ -1118,25 +1034,15 @@ xfs_mountfs(
int
xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
{
- int ndquots;
+ struct vfs *vfsp = XFS_MTOVFS(mp);
#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
int64_t fsid;
#endif
xfs_iflush_all(mp, XFS_FLUSH_ALL);
- /*
- * Purge the dquot cache.
- * None of the dquots should really be busy at this point.
- */
- if (mp->m_quotainfo) {
- while ((ndquots = xfs_qm_dqpurge_all(mp,
- XFS_QMOPT_UQUOTA|
- XFS_QMOPT_GQUOTA|
- XFS_QMOPT_UMOUNTING))) {
- delay(ndquots * 10);
- }
- }
+ XFS_QM_DQPURGEALL(mp,
+ XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING);
/*
* Flush out the log synchronously so that we know for sure
@@ -1178,14 +1084,14 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
/*
* clear all error tags on this filesystem
*/
- memcpy(&fsid, &(XFS_MTOVFS(mp)->vfs_fsid), sizeof(int64_t));
- (void) xfs_errortag_clearall_umount(fsid, mp->m_fsname, 0);
+ memcpy(&fsid, &vfsp->vfs_fsid, sizeof(int64_t));
+ xfs_errortag_clearall_umount(fsid, mp->m_fsname, 0);
#endif
-
+ XFS_IODONE(vfsp);
xfs_mount_free(mp, 1);
return 0;
}
-
+
void
xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr)
{
@@ -1652,47 +1558,6 @@ xfs_uuid_unmount(xfs_mount_t *mp)
}
/*
- * When xfsquotas isn't installed and the superblock had quotas, we need to
- * clear the quotaflags from superblock.
- */
-STATIC void
-xfs_mount_reset_sbqflags(
- xfs_mount_t *mp)
-{
- xfs_trans_t *tp;
- unsigned long s;
-
- mp->m_qflags = 0;
- /*
- * It is OK to look at sb_qflags here in mount path,
- * without SB_LOCK.
- */
- if (mp->m_sb.sb_qflags == 0)
- return;
- s = XFS_SB_LOCK(mp);
- mp->m_sb.sb_qflags = 0;
- XFS_SB_UNLOCK(mp, s);
-
- /*
- * if the fs is readonly, let the incore superblock run
- * with quotas off but don't flush the update out to disk
- */
- if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
- return;
-#ifdef QUOTADEBUG
- xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes");
-#endif
- tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
- if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
- XFS_DEFAULT_LOG_COUNT)) {
- xfs_trans_cancel(tp, 0);
- return;
- }
- xfs_mod_sb(tp, XFS_SB_QFLAGS);
- (void)xfs_trans_commit(tp, 0, NULL);
-}
-
-/*
* Used to log changes to the superblock unit and width fields which could
* be altered by the mount options. Only the first superblock is updated.
*/
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 881114ae6c66..62f598e4d533 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -75,7 +75,6 @@ struct xfs_ihash;
struct xfs_chash;
struct xfs_inode;
struct xfs_perag;
-struct xfs_quotainfo;
struct xfs_iocore;
struct xfs_bmbt_irec;
struct xfs_bmap_free;
@@ -87,15 +86,120 @@ struct xfs_bmap_free;
#define AIL_LOCK(mp,s) s=mutex_spinlock(&(mp)->m_ail_lock)
#define AIL_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_ail_lock, s)
+
+/*
+ * Prototypes and functions for the Data Migration subsystem.
+ */
+
+typedef int (*xfs_send_data_t)(int, struct bhv_desc *,
+ xfs_off_t, size_t, int, vrwlock_t *);
+typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
+typedef int (*xfs_send_destroy_t)(struct bhv_desc *, dm_right_t);
+typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_desc *,
+ dm_right_t, struct bhv_desc *, dm_right_t,
+ char *, char *, mode_t, int, int);
+typedef void (*xfs_send_unmount_t)(struct vfs *, struct vnode *,
+ dm_right_t, mode_t, int, int);
+
+typedef struct xfs_dmops {
+ xfs_send_data_t xfs_send_data;
+ xfs_send_mmap_t xfs_send_mmap;
+ xfs_send_destroy_t xfs_send_destroy;
+ xfs_send_namesp_t xfs_send_namesp;
+ xfs_send_unmount_t xfs_send_unmount;
+} xfs_dmops_t;
+
+#define XFS_SEND_DATA(mp, ev,bdp,off,len,fl,lock) \
+ (*(mp)->m_dm_ops.xfs_send_data)(ev,bdp,off,len,fl,lock)
+#define XFS_SEND_MMAP(mp, vma,fl) \
+ (*(mp)->m_dm_ops.xfs_send_mmap)(vma,fl)
+#define XFS_SEND_DESTROY(mp, bdp,right) \
+ (*(mp)->m_dm_ops.xfs_send_destroy)(bdp,right)
+#define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
+ (*(mp)->m_dm_ops.xfs_send_namesp)(ev,b1,r1,b2,r2,n1,n2,mode,rval,fl)
+#define XFS_SEND_UNMOUNT(mp, vfsp,vp,right,mode,rval,fl) \
+ (*(mp)->m_dm_ops.xfs_send_unmount)(vfsp,vp,right,mode,rval,fl)
+
+
+/*
+ * Prototypes and functions for the Quota Management subsystem.
+ */
+
+struct xfs_dquot;
+struct xfs_dqtrxops;
+struct xfs_quotainfo;
+
+typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *);
+typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint);
+typedef int (*xfs_qmunmount_t)(struct xfs_mount *);
+typedef void (*xfs_qmdone_t)(struct xfs_mount *);
+typedef void (*xfs_dqrele_t)(struct xfs_dquot *);
+typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint);
+typedef void (*xfs_dqdetach_t)(struct xfs_inode *);
+typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint);
+typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *,
+ struct xfs_inode *, uid_t, gid_t, uint,
+ struct xfs_dquot **, struct xfs_dquot **);
+typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *,
+ struct xfs_dquot *, struct xfs_dquot *);
+typedef int (*xfs_dqvoprename_t)(struct xfs_inode **);
+typedef struct xfs_dquot * (*xfs_dqvopchown_t)(
+ struct xfs_trans *, struct xfs_inode *,
+ struct xfs_dquot **, struct xfs_dquot *);
+typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *,
+ struct xfs_dquot *, struct xfs_dquot *, uint);
+
+typedef struct xfs_qmops {
+ xfs_qminit_t xfs_qminit;
+ xfs_qmdone_t xfs_qmdone;
+ xfs_qmmount_t xfs_qmmount;
+ xfs_qmunmount_t xfs_qmunmount;
+ xfs_dqrele_t xfs_dqrele;
+ xfs_dqattach_t xfs_dqattach;
+ xfs_dqdetach_t xfs_dqdetach;
+ xfs_dqpurgeall_t xfs_dqpurgeall;
+ xfs_dqvopalloc_t xfs_dqvopalloc;
+ xfs_dqvopcreate_t xfs_dqvopcreate;
+ xfs_dqvoprename_t xfs_dqvoprename;
+ xfs_dqvopchown_t xfs_dqvopchown;
+ xfs_dqvopchownresv_t xfs_dqvopchownresv;
+ struct xfs_dqtrxops *xfs_dqtrxops;
+} xfs_qmops_t;
+
+#define XFS_QM_INIT(mp, mnt, fl) \
+ (*(mp)->m_qm_ops.xfs_qminit)(mp, mnt, fl)
+#define XFS_QM_MOUNT(mp, mnt, fl) \
+ (*(mp)->m_qm_ops.xfs_qmmount)(mp, mnt, fl)
+#define XFS_QM_UNMOUNT(mp) \
+ (*(mp)->m_qm_ops.xfs_qmunmount)(mp)
+#define XFS_QM_DONE(mp) \
+ (*(mp)->m_qm_ops.xfs_qmdone)(mp)
+#define XFS_QM_DQRELE(mp, dq) \
+ (*(mp)->m_qm_ops.xfs_dqrele)(dq)
+#define XFS_QM_DQATTACH(mp, ip, fl) \
+ (*(mp)->m_qm_ops.xfs_dqattach)(ip, fl)
+#define XFS_QM_DQDETACH(mp, ip) \
+ (*(mp)->m_qm_ops.xfs_dqdetach)(ip)
+#define XFS_QM_DQPURGEALL(mp, fl) \
+ (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl)
+#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, fl, dq1, dq2) \
+ (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, fl, dq1, dq2)
+#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
+ (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2)
+#define XFS_QM_DQVOPRENAME(mp, ip) \
+ (*(mp)->m_qm_ops.xfs_dqvoprename)(ip)
+#define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \
+ (*(mp)->m_qm_ops.xfs_dqvopchown)(tp, ip, dqp, dq)
+#define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \
+ (*(mp)->m_qm_ops.xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl)
+
+
/*
* Prototypes and functions for I/O core modularization.
*/
-struct flid;
-struct buf;
-
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 *,
xfs_fileoff_t, xfs_filblks_t, int,
xfs_fsblock_t *, xfs_extlen_t,
@@ -137,61 +241,42 @@ typedef struct xfs_ioops {
xfs_iodone_t xfs_iodone;
} xfs_ioops_t;
-
#define XFS_IOINIT(vfsp, args, flags) \
(*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags)
-
#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist) \
(*(mp)->m_io_ops.xfs_bmapi_func) \
(trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist)
-
#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \
(*(mp)->m_io_ops.xfs_bmap_eof_func) \
((io)->io_obj, endoff, whichfork, eof)
-
#define XFS_IOMAP_WRITE_DIRECT(mp, io, offset, count, flags, mval, nmap, found)\
(*(mp)->m_io_ops.xfs_iomap_write_direct) \
((io)->io_obj, offset, count, flags, mval, nmap, found)
-
#define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \
(*(mp)->m_io_ops.xfs_iomap_write_delay) \
((io)->io_obj, offset, count, flags, mval, nmap)
-
#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, mval, nmap) \
(*(mp)->m_io_ops.xfs_iomap_write_allocate) \
((io)->io_obj, mval, nmap)
-
#define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \
(*(mp)->m_io_ops.xfs_iomap_write_unwritten) \
((io)->io_obj, offset, count)
-
#define XFS_LCK_MAP_SHARED(mp, io) \
(*(mp)->m_io_ops.xfs_lck_map_shared)((io)->io_obj)
-
#define XFS_ILOCK(mp, io, mode) \
(*(mp)->m_io_ops.xfs_ilock)((io)->io_obj, mode)
-
#define XFS_ILOCK_NOWAIT(mp, io, mode) \
(*(mp)->m_io_ops.xfs_ilock_nowait)((io)->io_obj, mode)
-
#define XFS_IUNLOCK(mp, io, mode) \
(*(mp)->m_io_ops.xfs_unlock)((io)->io_obj, mode)
-
#define XFS_ILOCK_DEMOTE(mp, io, mode) \
(*(mp)->m_io_ops.xfs_ilock_demote)((io)->io_obj, mode)
-
#define XFS_SIZE(mp, io) \
(*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
-
#define XFS_IODONE(vfsp) \
(*(mp)->m_io_ops.xfs_iodone)(vfsp)
-/*
- * Prototypes and functions for the XFS realtime subsystem.
- */
-
-
typedef struct xfs_mount {
bhv_desc_t m_bhv; /* vfs xfs behavior */
xfs_tid_t m_tid; /* next unused tid for fs */
@@ -289,13 +374,9 @@ typedef struct xfs_mount {
int m_chsize; /* size of next field */
struct xfs_chash *m_chash; /* fs private inode per-cluster
* hash table */
+ struct xfs_dmops m_dm_ops; /* vector of DMI ops */
+ struct xfs_qmops m_qm_ops; /* vector of XQM ops */
struct xfs_ioops m_io_ops; /* vector of I/O ops */
- struct xfs_expinfo *m_expinfo; /* info to export to other
- cells. */
- uint64_t m_shadow_pinmask;
- /* which bits matter in rpc
- log item pin masks */
- uint m_cxfstype; /* mounted shared, etc. */
lock_t m_freeze_lock; /* Lock for m_frozen */
uint m_frozen; /* FS frozen for shutdown or
* snapshot */
@@ -324,8 +405,7 @@ typedef struct xfs_mount {
#define XFS_MOUNT_NOALIGN 0x00000080 /* turn off stripe alignment
allocations */
/* 0x00000100 -- currently unused */
-#define XFS_MOUNT_REGISTERED 0x00000200 /* registered with cxfs master
- cell logic */
+ /* 0x00000200 -- currently unused */
#define XFS_MOUNT_NORECOVERY 0x00000400 /* no recovery - dirty fs */
#define XFS_MOUNT_SHARED 0x00000800 /* shared mount */
#define XFS_MOUNT_DFLT_IOSIZE 0x00001000 /* set default i/o size */
@@ -336,14 +416,6 @@ typedef struct xfs_mount {
* 32 bits in size */
#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)
/*
@@ -370,15 +442,17 @@ typedef struct xfs_mount {
#define XFS_WSYNC_READIO_LOG 15 /* 32K */
#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.
*/
#define XFS_METADATA_IO_ERROR 0x1
#define XFS_LOG_IO_ERROR 0x2
#define XFS_FORCE_UMOUNT 0x4
-#define XFS_CORRUPT_INCORE 0x8 /* corrupt in-memory data structures */
-#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* shutdown came from remote cell */
+#define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */
+#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */
/*
* xflags for xfs_syncsub
@@ -388,9 +462,7 @@ typedef struct xfs_mount {
/*
* Flags for xfs_mountfs
*/
-#define XFS_MFSI_SECOND 0x01 /* Is a cxfs secondary mount -- skip */
- /* stuff which should only be done */
- /* once. */
+#define XFS_MFSI_SECOND 0x01 /* Secondary mount -- skip stuff */
#define XFS_MFSI_CLIENT 0x02 /* Is a client -- skip lots of stuff */
#define XFS_MFSI_NOUNLINK 0x08 /* Skip unlinked inode processing in */
/* log recovery */
@@ -410,6 +482,13 @@ xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp);
#else
#define XFS_BHVTOM(bdp) ((xfs_mount_t *)BHV_PDATA(bdp))
#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 +526,7 @@ static inline xfs_agblock_t XFS_DADDR_TO_AGBNO(xfs_mount_t *mp, xfs_daddr_t d)
*/
typedef struct xfs_mod_sb {
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;
#define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock), PINOD)
@@ -455,24 +534,26 @@ typedef struct xfs_mod_sb {
#define XFS_SB_LOCK(mp) mutex_spinlock(&(mp)->m_sb_lock)
#define XFS_SB_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_sb_lock,(s))
-void xfs_mod_sb(xfs_trans_t *, __int64_t);
-xfs_mount_t *xfs_mount_init(void);
-void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
-int xfs_mountfs(struct vfs *, xfs_mount_t *mp, dev_t, int);
-
-int xfs_unmountfs(xfs_mount_t *, struct cred *);
-void xfs_unmountfs_close(xfs_mount_t *, struct cred *);
-int xfs_unmountfs_writesb(xfs_mount_t *);
-int xfs_unmount_flush(xfs_mount_t *, int);
-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);
-int xfs_readsb(xfs_mount_t *mp);
-struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
-void xfs_freesb(xfs_mount_t *);
-void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
-int xfs_syncsub(xfs_mount_t *, int, int, int *);
-void xfs_initialize_perag(xfs_mount_t *, int);
-void xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t, __int64_t);
+extern xfs_mount_t *xfs_mount_init(void);
+extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
+extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
+extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, dev_t, int);
+
+extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
+extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *);
+extern int xfs_unmountfs_writesb(xfs_mount_t *);
+extern int xfs_unmount_flush(xfs_mount_t *, int);
+extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int, int);
+extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
+ uint, int);
+extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
+extern int xfs_readsb(xfs_mount_t *mp);
+extern void xfs_freesb(xfs_mount_t *);
+extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
+extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
+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.
@@ -480,11 +561,19 @@ void xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t, __int64_t);
#define XFS_FREEZE_WRITE 1
#define XFS_FREEZE_TRANS 2
-void xfs_start_freeze(xfs_mount_t *, int);
-void xfs_finish_freeze(xfs_mount_t *);
-void xfs_check_frozen(xfs_mount_t *, bhv_desc_t *, int);
+extern void xfs_start_freeze(xfs_mount_t *, int);
+extern void xfs_finish_freeze(xfs_mount_t *);
+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_dmops xfs_dmcore_xfs;
+extern struct xfs_qmops xfs_qmcore_xfs;
+extern struct xfs_ioops xfs_iocore_xfs;
-extern struct vfsops xfs_vfsops;
+extern int xfs_init(void);
+extern void xfs_cleanup(void);
#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
new file mode 100644
index 000000000000..75d1029ceb77
--- /dev/null
+++ b/fs/xfs/xfs_qmops.c
@@ -0,0 +1,60 @@
+/*
+ * 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>
+
+#ifndef CONFIG_XFS_QUOTA
+STATIC struct xfs_dquot *
+xfs_dqvopchown_default(
+ struct xfs_trans *tp,
+ struct xfs_inode *ip,
+ struct xfs_dquot **dqp,
+ struct xfs_dquot *dq)
+{
+ return NULL;
+}
+
+xfs_qmops_t xfs_qmcore_xfs = {
+ .xfs_qminit = (xfs_qminit_t) fs_noerr,
+ .xfs_qmdone = (xfs_qmdone_t) fs_noerr,
+ .xfs_qmmount = (xfs_qmmount_t) fs_noerr,
+ .xfs_qmunmount = (xfs_qmunmount_t) fs_noerr,
+ .xfs_dqrele = (xfs_dqrele_t) fs_noerr,
+ .xfs_dqattach = (xfs_dqattach_t) fs_noerr,
+ .xfs_dqdetach = (xfs_dqdetach_t) fs_noerr,
+ .xfs_dqpurgeall = (xfs_dqpurgeall_t) fs_noerr,
+ .xfs_dqvopalloc = (xfs_dqvopalloc_t) fs_noerr,
+ .xfs_dqvopcreate = (xfs_dqvopcreate_t) fs_noerr,
+ .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr,
+ .xfs_dqvopchown = xfs_dqvopchown_default,
+ .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr,
+};
+#endif /* CONFIG_XFS_QUOTA */
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 37639212e07d..57c2bb304aa3 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2001 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
* under the terms of version 2 of the GNU General Public License as
@@ -33,6 +33,12 @@
#define __XFS_QUOTA_H__
/*
+ * The ondisk form of a dquot structure.
+ */
+#define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */
+#define XFS_DQUOT_VERSION (u_int8_t)0x01 /* latest version number */
+
+/*
* uid_t and gid_t are hard-coded to 32 bits in the inode.
* Hence, an 'id' in a dquot is 32 bits..
*/
@@ -47,6 +53,100 @@ typedef __uint64_t xfs_qcnt_t;
typedef __uint16_t xfs_qwarncnt_t;
/*
+ * This is the main portion of the on-disk representation of quota
+ * information for a user. This is the q_core of the xfs_dquot_t that
+ * is kept in kernel memory. We pad this with some more expansion room
+ * to construct the on disk structure.
+ */
+typedef struct xfs_disk_dquot {
+/*16*/ u_int16_t d_magic; /* dquot magic = XFS_DQUOT_MAGIC */
+/*8 */ u_int8_t d_version; /* dquot version */
+/*8 */ u_int8_t d_flags; /* XFS_DQ_USER/PROJ/GROUP */
+/*32*/ xfs_dqid_t d_id; /* user,project,group id */
+/*64*/ xfs_qcnt_t d_blk_hardlimit;/* absolute limit on disk blks */
+/*64*/ xfs_qcnt_t d_blk_softlimit;/* preferred limit on disk blks */
+/*64*/ xfs_qcnt_t d_ino_hardlimit;/* maximum # allocated inodes */
+/*64*/ xfs_qcnt_t d_ino_softlimit;/* preferred inode limit */
+/*64*/ xfs_qcnt_t d_bcount; /* disk blocks owned by the user */
+/*64*/ xfs_qcnt_t d_icount; /* inodes owned by the user */
+/*32*/ __int32_t d_itimer; /* zero if within inode limits if not,
+ this is when we refuse service */
+/*32*/ __int32_t d_btimer; /* similar to above; for disk blocks */
+/*16*/ xfs_qwarncnt_t d_iwarns; /* warnings issued wrt num inodes */
+/*16*/ xfs_qwarncnt_t d_bwarns; /* warnings issued wrt disk blocks */
+/*32*/ __int32_t d_pad0; /* 64 bit align */
+/*64*/ xfs_qcnt_t d_rtb_hardlimit;/* absolute limit on realtime blks */
+/*64*/ xfs_qcnt_t d_rtb_softlimit;/* preferred limit on RT disk blks */
+/*64*/ xfs_qcnt_t d_rtbcount; /* realtime blocks owned */
+/*32*/ __int32_t d_rtbtimer; /* similar to above; for RT disk blocks */
+/*16*/ xfs_qwarncnt_t d_rtbwarns; /* warnings issued wrt RT disk blocks */
+/*16*/ __uint16_t d_pad;
+} xfs_disk_dquot_t;
+
+/*
+ * This is what goes on disk. This is separated from the xfs_disk_dquot because
+ * carrying the unnecessary padding would be a waste of memory.
+ */
+typedef struct xfs_dqblk {
+ xfs_disk_dquot_t dd_diskdq; /* portion that lives incore as well */
+ char dd_fill[32]; /* filling for posterity */
+} xfs_dqblk_t;
+
+/*
+ * flags for q_flags field in the dquot.
+ */
+#define XFS_DQ_USER 0x0001 /* a user quota */
+/* #define XFS_DQ_PROJ 0x0002 -- project quota (IRIX) */
+#define XFS_DQ_GROUP 0x0004 /* a group quota */
+#define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */
+#define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */
+#define XFS_DQ_WANT 0x0020 /* for lookup/reclaim race */
+#define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */
+#define XFS_DQ_MARKER 0x0080 /* sentinel */
+
+/*
+ * In the worst case, when both user and group quotas are on,
+ * we can have a max of three dquots changing in a single transaction.
+ */
+#define XFS_DQUOT_LOGRES(mp) (sizeof(xfs_disk_dquot_t) * 3)
+
+
+/*
+ * These are the structures used to lay out dquots and quotaoff
+ * records on the log. Quite similar to those of inodes.
+ */
+
+/*
+ * log format struct for dquots.
+ * The first two fields must be the type and size fitting into
+ * 32 bits : log_recovery code assumes that.
+ */
+typedef struct xfs_dq_logformat {
+ __uint16_t qlf_type; /* dquot log item type */
+ __uint16_t qlf_size; /* size of this item */
+ xfs_dqid_t qlf_id; /* usr/grp id number : 32 bits */
+ __int64_t qlf_blkno; /* blkno of dquot buffer */
+ __int32_t qlf_len; /* len of dquot buffer */
+ __uint32_t qlf_boffset; /* off of dquot in buffer */
+} xfs_dq_logformat_t;
+
+/*
+ * log format struct for QUOTAOFF records.
+ * The first two fields must be the type and size fitting into
+ * 32 bits : log_recovery code assumes that.
+ * We write two LI_QUOTAOFF logitems per quotaoff, the last one keeps a pointer
+ * to the first and ensures that the first logitem is taken out of the AIL
+ * only when the last one is securely committed.
+ */
+typedef struct xfs_qoff_logformat {
+ unsigned short qf_type; /* quotaoff log item type */
+ unsigned short qf_size; /* size of this item */
+ unsigned int qf_flags; /* USR and/or GRP */
+ char qf_pad[12]; /* padding for future */
+} xfs_qoff_logformat_t;
+
+
+/*
* Disk quotas status in m_qflags, and also sb_qflags. 16 bits.
*/
#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */
@@ -134,13 +234,14 @@ typedef __uint16_t xfs_qwarncnt_t;
#define XFS_QMOPT_QUOTALL (XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA)
#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
+#ifdef __KERNEL__
/*
* This check is done typically without holding the inode lock;
* that may seem racey, but it is harmless in the context that it is used.
* The inode cannot go inactive as long a reference is kept, and
* therefore if dquot(s) were attached, they'll stay consistent.
* If, for example, the ownership of the inode changes while
- * we didnt have the inode locked, the appropriate dquot(s) will be
+ * we didn't have the inode locked, the appropriate dquot(s) will be
* attached atomically.
*/
#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\
@@ -161,190 +262,93 @@ typedef __uint16_t xfs_qwarncnt_t;
#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \
XFS_GQUOTA_ACTIVE)
-#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
-
-
-#ifdef __KERNEL__
-
-#ifdef CONFIG_XFS_QUOTA
-/*
- * External Interface to the XFS disk quota subsystem.
- */
-struct xfs_disk_dquot;
-struct xfs_dqhash;
-struct xfs_dquot;
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_trans;
-
-/*
- * Quota Manager Interface.
- */
-extern struct xfs_qm *xfs_qm_init(void);
-extern void xfs_qm_destroy(struct xfs_qm *);
-extern int xfs_qm_dqflush_all(struct xfs_mount *, int);
-extern int xfs_qm_dqattach(struct xfs_inode *, uint);
-extern int xfs_qm_dqpurge_all(struct xfs_mount *, uint);
-extern void xfs_qm_mount_quotainit(struct xfs_mount *, uint);
-extern void xfs_qm_unmount_quotadestroy(struct xfs_mount *);
-extern int xfs_qm_mount_quotas(struct xfs_mount *);
-extern int xfs_qm_unmount_quotas(struct xfs_mount *);
-extern void xfs_qm_dqdettach_inode(struct xfs_inode *);
-extern int xfs_qm_sync(struct xfs_mount *, short);
/*
- * Dquot interface.
+ * The structure kept inside the xfs_trans_t keep track of dquot changes
+ * within a transaction and apply them later.
*/
-extern void xfs_dqlock(struct xfs_dquot *);
-extern void xfs_dqunlock(struct xfs_dquot *);
-extern void xfs_dqunlock_nonotify(struct xfs_dquot *);
-extern void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *);
-extern void xfs_qm_dqput(struct xfs_dquot *);
-extern void xfs_qm_dqrele(struct xfs_dquot *);
-extern xfs_dqid_t xfs_qm_dqid(struct xfs_dquot *);
-extern int xfs_qm_dqget(struct xfs_mount *,
- struct xfs_inode *, xfs_dqid_t,
- uint, uint, struct xfs_dquot **);
-extern int xfs_qm_dqcheck(struct xfs_disk_dquot *,
- xfs_dqid_t, uint, uint, char *);
+typedef struct xfs_dqtrx {
+ struct xfs_dquot *qt_dquot; /* the dquot this refers to */
+ ulong qt_blk_res; /* blks reserved on a dquot */
+ ulong qt_blk_res_used; /* blks used from the reservation */
+ ulong qt_ino_res; /* inode reserved on a dquot */
+ ulong qt_ino_res_used; /* inodes used from the reservation */
+ long qt_bcount_delta; /* dquot blk count changes */
+ long qt_delbcnt_delta; /* delayed dquot blk count changes */
+ long qt_icount_delta; /* dquot inode count changes */
+ ulong qt_rtblk_res; /* # blks reserved on a dquot */
+ ulong qt_rtblk_res_used;/* # blks used from reservation */
+ long qt_rtbcount_delta;/* dquot realtime blk changes */
+ long qt_delrtb_delta; /* delayed RT blk count changes */
+} xfs_dqtrx_t;
/*
- * Vnodeops specific code that should actually be _in_ xfs_vnodeops.c, but
- * is here because it's nicer to keep vnodeops (therefore, XFS) lean
- * and clean.
+ * Dquot transaction functions, used if quota is enabled.
*/
-extern struct xfs_dquot * xfs_qm_vop_chown(struct xfs_trans *,
- struct xfs_inode *,
- struct xfs_dquot **,
- struct xfs_dquot *);
-extern int xfs_qm_vop_dqalloc(struct xfs_mount *,
- struct xfs_inode *,
- uid_t, gid_t, uint,
- struct xfs_dquot **,
- struct xfs_dquot **);
-
-extern int xfs_qm_vop_chown_reserve(struct xfs_trans *,
- struct xfs_inode *,
- struct xfs_dquot *,
- struct xfs_dquot *,
- uint);
-
-extern int xfs_qm_vop_rename_dqattach(struct xfs_inode **);
-extern void xfs_qm_vop_dqattach_and_dqmod_newinode(
- struct xfs_trans *,
- struct xfs_inode *,
- struct xfs_dquot *,
- struct xfs_dquot *);
-
-
-/*
- * Dquot Transaction interface
- */
-extern void xfs_trans_alloc_dqinfo(struct xfs_trans *);
-extern void xfs_trans_free_dqinfo(struct xfs_trans *);
-extern void xfs_trans_dup_dqinfo(struct xfs_trans *,
- struct xfs_trans *);
-extern void xfs_trans_mod_dquot(struct xfs_trans *,
- struct xfs_dquot *,
- uint, long);
-extern void xfs_trans_mod_dquot_byino(struct xfs_trans *,
- struct xfs_inode *,
- uint, long);
-extern void xfs_trans_apply_dquot_deltas(struct xfs_trans *);
-extern void xfs_trans_unreserve_and_mod_dquots(struct xfs_trans *);
-
-extern int xfs_trans_reserve_quota_nblks(struct xfs_trans *,
- struct xfs_inode *,
- long, long, uint);
-
-
-extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
- struct xfs_dquot *,
- struct xfs_dquot *,
- long, long, uint);
-extern void xfs_trans_log_dquot(struct xfs_trans *,
- struct xfs_dquot *);
-extern void xfs_trans_dqjoin(struct xfs_trans *,
- struct xfs_dquot *);
-extern void xfs_qm_dqrele_all_inodes(struct xfs_mount *, uint);
-
-# define _XQM_ZONE_DESTROY(z) ((z)? kmem_cache_destroy(z) : (void)0)
-
-#else
-# define xfs_qm_init() (NULL)
-# define xfs_qm_destroy(xqm) do { } while (0)
-# define xfs_qm_dqflush_all(m,t) (ENOSYS)
-# define xfs_qm_dqattach(i,t) (ENOSYS)
-# define xfs_qm_dqpurge_all(m,t) (ENOSYS)
-# define xfs_qm_mount_quotainit(m,t) do { } while (0)
-# define xfs_qm_unmount_quotadestroy(m) do { } while (0)
-# define xfs_qm_mount_quotas(m) (ENOSYS)
-# define xfs_qm_unmount_quotas(m) (ENOSYS)
-# define xfs_qm_dqdettach_inode(i) do { } while (0)
-# define xfs_qm_sync(m,t) (ENOSYS)
-# define xfs_dqlock(d) do { } while (0)
-# define xfs_dqunlock(d) do { } while (0)
-# define xfs_dqunlock_nonotify(d) do { } while (0)
-# define xfs_dqlock2(d1,d2) do { } while (0)
-# define xfs_qm_dqput(d) do { } while (0)
-# define xfs_qm_dqrele(d) do { } while (0)
-# define xfs_qm_dqid(d) (-1)
-# define xfs_qm_dqget(m,i,di,t,f,d) (ENOSYS)
-# define xfs_qm_dqcheck(dd,di,t,f,s) (ENOSYS)
-# define xfs_trans_alloc_dqinfo(t) do { } while (0)
-# define xfs_trans_free_dqinfo(t) do { } while (0)
-# define xfs_trans_dup_dqinfo(t1,t2) do { } while (0)
-# define xfs_trans_mod_dquot(t,d,f,x) do { } while (0)
-# define xfs_trans_mod_dquot_byino(t,i,f,x) do { } while (0)
-# define xfs_trans_apply_dquot_deltas(t) do { } while (0)
-# define xfs_trans_unreserve_and_mod_dquots(t) do { } while (0)
-# define xfs_trans_reserve_quota_nblks(t,i,nb,ni,f) (ENOSYS)
-# define xfs_trans_reserve_quota_bydquots(t,x,y,b,i,f) (ENOSYS)
-# define xfs_trans_log_dquot(t,d) do { } while (0)
-# define xfs_trans_dqjoin(t,d) do { } while (0)
-# define xfs_qm_dqrele_all_inodes(m,t) do { } while (0)
-# define xfs_qm_vop_chown(t,i,d1,d2) (NULL)
-# define xfs_qm_vop_dqalloc(m,i,u,g,f,d1,d2) (ENOSYS)
-# define xfs_qm_vop_chown_reserve(t,i,d1,d2,f) (ENOSYS)
-# define xfs_qm_vop_rename_dqattach(i) (ENOSYS)
-# define xfs_qm_vop_dqattach_and_dqmod_newinode(t,i,x,y) do { } while (0)
-# define _XQM_ZONE_DESTROY(z) do { } while (0)
-#endif /* CONFIG_XFS_QUOTA */
-
-/*
- * Regular disk block quota reservations
- */
-#define xfs_trans_reserve_blkquota(tp, ip, nblks) \
-xfs_trans_reserve_quota_nblks(tp, ip, nblks, 0, XFS_QMOPT_RES_REGBLKS)
-
-#define xfs_trans_reserve_blkquota_force(tp, ip, nblks) \
-xfs_trans_reserve_quota_nblks(tp, ip, nblks, 0, \
- XFS_QMOPT_RES_REGBLKS|XFS_QMOPT_FORCE_RES)
-
-#define xfs_trans_unreserve_blkquota(tp, ip, nblks) \
-(void)xfs_trans_reserve_quota_nblks(tp, ip, -(nblks), 0, XFS_QMOPT_RES_REGBLKS)
-
-#define xfs_trans_reserve_quota(tp, udq, gdq, nb, ni, f) \
-xfs_trans_reserve_quota_bydquots(tp, udq, gdq, nb, ni, f|XFS_QMOPT_RES_REGBLKS)
-
-#define xfs_trans_unreserve_quota(tp, ud, gd, b, i, f) \
-xfs_trans_reserve_quota_bydquots(tp, ud, gd, -(b), -(i), f|XFS_QMOPT_RES_REGBLKS)
-
-/*
- * Realtime disk block quota reservations
- */
-#define xfs_trans_reserve_rtblkquota(mp, tp, ip, nblks) \
-xfs_trans_reserve_quota_nblks(tp, ip, nblks, 0, XFS_QMOPT_RES_RTBLKS)
-
-#define xfs_trans_unreserve_rtblkquota(tp, ip, nblks) \
-(void)xfs_trans_reserve_quota_nblks(tp, ip, -(nblks), 0, XFS_QMOPT_RES_RTBLKS)
-
-#define xfs_trans_reserve_rtquota(mp, tp, uq, pq, blks, f) \
-xfs_trans_reserve_quota_bydquots(mp, tp, uq, pq, blks, 0, f|XFS_QMOPT_RES_RTBLKS)
-
-#define xfs_trans_unreserve_rtquota(tp, uq, pq, blks) \
-xfs_trans_reserve_quota_bydquots(tp, uq, pq, -(blks), XFS_QMOPT_RES_RTBLKS)
-
+typedef void (*qo_dup_dqinfo_t)(struct xfs_trans *, struct xfs_trans *);
+typedef void (*qo_mod_dquot_byino_t)(struct xfs_trans *,
+ struct xfs_inode *, uint, long);
+typedef void (*qo_free_dqinfo_t)(struct xfs_trans *);
+typedef void (*qo_apply_dquot_deltas_t)(struct xfs_trans *);
+typedef void (*qo_unreserve_and_mod_dquots_t)(struct xfs_trans *);
+typedef int (*qo_reserve_quota_nblks_t)(
+ struct xfs_trans *, struct xfs_mount *,
+ struct xfs_inode *, long, long, uint);
+typedef int (*qo_reserve_quota_bydquots_t)(
+ struct xfs_trans *, struct xfs_mount *,
+ struct xfs_dquot *, struct xfs_dquot *,
+ long, long, uint);
+typedef struct xfs_dqtrxops {
+ qo_dup_dqinfo_t qo_dup_dqinfo;
+ qo_free_dqinfo_t qo_free_dqinfo;
+ qo_mod_dquot_byino_t qo_mod_dquot_byino;
+ qo_apply_dquot_deltas_t qo_apply_dquot_deltas;
+ qo_reserve_quota_nblks_t qo_reserve_quota_nblks;
+ qo_reserve_quota_bydquots_t qo_reserve_quota_bydquots;
+ qo_unreserve_and_mod_dquots_t qo_unreserve_and_mod_dquots;
+} xfs_dqtrxops_t;
+
+#define XFS_DQTRXOP(mp, tp, op, args...) \
+ ((mp)->m_qm_ops.xfs_dqtrxops ? \
+ ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : 0)
+
+#define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \
+ XFS_DQTRXOP(mp, otp, qo_dup_dqinfo, ntp)
+#define XFS_TRANS_FREE_DQINFO(mp, tp) \
+ XFS_DQTRXOP(mp, tp, qo_free_dqinfo)
+#define XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, field, delta) \
+ XFS_DQTRXOP(mp, tp, qo_mod_dquot_byino, ip, field, delta)
+#define XFS_TRANS_APPLY_DQUOT_DELTAS(mp, tp) \
+ XFS_DQTRXOP(mp, tp, qo_apply_dquot_deltas)
+#define XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, fl) \
+ XFS_DQTRXOP(mp, tp, qo_reserve_quota_nblks, mp, ip, nblks, ninos, fl)
+#define XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, fl) \
+ XFS_DQTRXOP(mp, tp, qo_reserve_quota_bydquots, mp, ud, gd, nb, ni, fl)
+#define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \
+ XFS_DQTRXOP(mp, tp, qo_unreserve_and_mod_dquots)
+
+#define XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, nblks) \
+ XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \
+ XFS_QMOPT_RES_REGBLKS)
+#define XFS_TRANS_RESERVE_BLKQUOTA_FORCE(mp, tp, ip, nblks) \
+ XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \
+ XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES)
+#define XFS_TRANS_UNRESERVE_BLKQUOTA(mp, tp, ip, nblks) \
+ XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), 0, \
+ XFS_QMOPT_RES_REGBLKS)
+#define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \
+ XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \
+ f | XFS_QMOPT_RES_REGBLKS)
+#define XFS_TRANS_UNRESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \
+ XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, -(nb), -(ni), \
+ f | XFS_QMOPT_RES_REGBLKS)
+
+extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
+
+extern struct bhv_vfsops xfs_qmops;
+
+extern void xfs_qm_init(void);
+extern void xfs_qm_exit(void);
#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 616c1baf2d0a..dc6b2b1dd4d4 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -261,11 +261,12 @@ xfs_rename(
src_dp = XFS_BHVTOI(src_dir_bdp);
target_dp = XFS_BHVTOI(target_dir_bdp);
+ mp = src_dp->i_mount;
if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_RENAME) ||
DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
target_dp, DM_EVENT_RENAME)) {
- error = dm_send_namesp_event(DM_EVENT_RENAME,
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME,
src_dir_bdp, DM_RIGHT_NULL,
target_dir_bdp, DM_RIGHT_NULL,
src_name, target_name,
@@ -323,7 +324,6 @@ xfs_rename(
xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED);
XFS_BMAP_INIT(&free_list, &first_block);
- mp = src_dp->i_mount;
tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME);
cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
spaceres = XFS_RENAME_SPACE_RES(mp, target_namelen);
@@ -343,12 +343,10 @@ xfs_rename(
/*
* Attach the dquots to the inodes
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- if ((error = xfs_qm_vop_rename_dqattach(inodes))) {
- xfs_trans_cancel(tp, cancel_flags);
- rename_which_error_return = __LINE__;
- goto rele_return;
- }
+ if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) {
+ xfs_trans_cancel(tp, cancel_flags);
+ rename_which_error_return = __LINE__;
+ goto rele_return;
}
/*
@@ -625,7 +623,7 @@ std_return:
if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_POSTRENAME) ||
DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
target_dp, DM_EVENT_POSTRENAME)) {
- (void) dm_send_namesp_event(DM_EVENT_POSTRENAME,
+ (void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME,
src_dir_bdp, DM_RIGHT_NULL,
target_dir_bdp, DM_RIGHT_NULL,
src_name, target_name,
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 286436f823d1..19e70410788d 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -1,5 +1,5 @@
/*
- * 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
* under the terms of version 2 of the GNU General Public License as
@@ -35,6 +35,8 @@
struct xfs_mount;
struct xfs_trans;
+#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
+
/* Min and max rt extent sizes, specified in bytes */
#define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */
#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64KB */
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 599ec46ec7a6..fe1050a8ea95 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -173,11 +173,7 @@ xfs_trans_dup(
ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
tp->t_rtx_res = tp->t_rtx_res_used;
- /*
- * dup the dquot stuff too.
- */
- if (tp->t_dqinfo)
- xfs_trans_dup_dqinfo(tp, ntp);
+ XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp);
atomic_inc(&tp->t_mountp->m_active_trans);
return ntp;
@@ -703,9 +699,7 @@ shut_us_down:
* means is that we have some (non-persistent) quota
* reservations that need to be unreserved.
*/
- if (tp->t_dqinfo && (tp->t_flags & XFS_TRANS_DQ_DIRTY)) {
- xfs_trans_unreserve_and_mod_dquots(tp);
- }
+ XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp);
if (tp->t_ticket) {
commit_lsn = xfs_log_done(mp, tp->t_ticket,
NULL, log_flags);
@@ -733,9 +727,7 @@ shut_us_down:
if (tp->t_flags & XFS_TRANS_SB_DIRTY) {
xfs_trans_apply_sb_deltas(tp);
}
- if (tp->t_flags & XFS_TRANS_DQ_DIRTY) {
- xfs_trans_apply_dquot_deltas(tp);
- }
+ XFS_TRANS_APPLY_DQUOT_DELTAS(mp, tp);
/*
* Ask each log item how many log_vector entries it will
@@ -955,9 +947,7 @@ xfs_trans_uncommit(
}
xfs_trans_unreserve_and_mod_sb(tp);
- if (tp->t_dqinfo && (tp->t_flags & XFS_TRANS_DQ_DIRTY)) {
- xfs_trans_unreserve_and_mod_dquots(tp);
- }
+ XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(tp->t_mountp, tp);
xfs_trans_free_items(tp, flags);
xfs_trans_free_busy(tp);
@@ -1079,9 +1069,7 @@ xfs_trans_cancel(
}
#endif
xfs_trans_unreserve_and_mod_sb(tp);
-
- if (tp->t_dqinfo && (tp->t_flags & XFS_TRANS_DQ_DIRTY))
- xfs_trans_unreserve_and_mod_dquots(tp);
+ XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(tp->t_mountp, tp);
if (tp->t_ticket) {
if (flags & XFS_TRANS_RELEASE_LOG_RES) {
@@ -1110,8 +1098,7 @@ xfs_trans_free(
xfs_trans_t *tp)
{
atomic_dec(&tp->t_mountp->m_active_trans);
- if (tp->t_dqinfo)
- xfs_trans_free_dqinfo(tp);
+ XFS_TRANS_FREE_DQINFO(tp->t_mountp, tp);
kmem_zone_free(xfs_trans_zone, tp);
}
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index ed091cb1ce99..23264a5b9cdc 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -64,7 +64,6 @@ typedef struct xfs_trans_header {
#define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */
#define XFS_LI_DQUOT 0x123d
#define XFS_LI_QUOTAOFF 0x123e
-#define XFS_LI_RPC 0x123f /* CXFS RPC return info */
/*
* Transaction types. Used to distinguish types of buffers.
@@ -1014,10 +1013,7 @@ void xfs_trans_log_efd_extent(xfs_trans_t *,
struct xfs_efd_log_item *,
xfs_fsblock_t,
xfs_extlen_t);
-void xfs_trans_log_create_rpc(xfs_trans_t *, int, xfs_ino_t);
-void xfs_trans_log_setattr_rpc(xfs_trans_t *, int);
int xfs_trans_commit(xfs_trans_t *, uint flags, xfs_lsn_t *);
-void xfs_trans_commit_async(struct xfs_mount *);
void xfs_trans_cancel(xfs_trans_t *, int);
void xfs_trans_ail_init(struct xfs_mount *);
xfs_lsn_t xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 9059b4261e89..c4d552a134e3 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -232,7 +232,7 @@ xfs_dir_ialloc(
xfs_buf_relse(ialloc_context);
if (dqinfo) {
tp->t_dqinfo = dqinfo;
- xfs_trans_free_dqinfo(tp);
+ XFS_TRANS_FREE_DQINFO(tp->t_mountp, tp);
}
*tpp = ntp;
*ipp = NULL;
@@ -254,7 +254,7 @@ xfs_dir_ialloc(
*ipp = NULL;
return code;
}
- xfs_trans_bjoin (tp, ialloc_context);
+ xfs_trans_bjoin(tp, ialloc_context);
/*
* Call ialloc again. Since we've locked out all
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index a78344c9113d..dff3827adec4 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -1,7 +1,7 @@
/*
* 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
* under the terms of version 2 of the GNU General Public License as
@@ -68,7 +68,6 @@ xfs_init(void)
spinlock_init(&xfs_dabuf_global_lock, "xfsda");
#endif
mutex_init(&xfs_uuidtabmon, MUTEX_DEFAULT, "xfs_uuidtab");
- mutex_init(&xfs_Gqm_lock, MUTEX_DEFAULT, "xfs_qmlock");
/*
* Initialize all of the zone allocators we use.
@@ -175,8 +174,6 @@ xfs_cleanup(void)
kmem_cache_destroy(xfs_ifork_zone);
kmem_cache_destroy(xfs_ili_zone);
kmem_cache_destroy(xfs_chashlist_zone);
- _XQM_ZONE_DESTROY(qm_dqzone);
- _XQM_ZONE_DESTROY(qm_dqtrxzone);
_ACL_ZONE_DESTROY(xfs_acl_zone);
#if (defined(DEBUG) || defined(CONFIG_XFS_VNODE_TRACING))
ktrace_uninit();
@@ -248,9 +245,6 @@ xfs_start_flags(
if (ap->flags & XFSMNT_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)
mp->m_flags |= XFS_MOUNT_RETERR;
@@ -387,11 +381,13 @@ xfs_finish_flags(
*/
STATIC int
xfs_mount(
- vfs_t *vfsp,
+ struct bhv_desc *bhvp,
struct xfs_mount_args *args,
cred_t *credp)
{
- xfs_mount_t *mp;
+ struct vfs *vfsp = bhvtovfs(bhvp);
+ struct bhv_desc *p;
+ struct xfs_mount *mp = XFS_BHVTOM(bhvp);
struct block_device *ddev, *logdev, *rtdev;
int ronly = (vfsp->vfs_flag & VFS_RDONLY);
int flags = 0, error;
@@ -400,23 +396,18 @@ xfs_mount(
logdev = rtdev = NULL;
/*
- * Allocate VFS private data (xfs mount structure).
- */
- mp = xfs_mount_init();
-
- /*
* Open real time and log devices - order is important.
*/
if (args->logname[0]) {
error = xfs_blkdev_get(mp, args->logname, &logdev);
if (error)
- goto free_mp;
+ return error;
}
if (args->rtname[0]) {
error = xfs_blkdev_get(mp, args->rtname, &rtdev);
if (error) {
xfs_blkdev_put(logdev);
- goto free_mp;
+ return error;
}
if (rtdev == ddev || rtdev == logdev) {
@@ -424,33 +415,47 @@ xfs_mount(
"XFS: Cannot mount filesystem with identical rtdev and ddev/logdev.");
xfs_blkdev_put(logdev);
xfs_blkdev_put(rtdev);
- error = EINVAL;
- goto free_mp;
+ return EINVAL;
}
}
- vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
+ /*
+ * Setup xfs_mount function vectors from available behaviors
+ */
+ p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM);
+ mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_xfs;
+ p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM);
+ mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_xfs;
+ p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
+ mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
+ /*
+ * Setup xfs_mount buffer target pointers
+ */
mp->m_ddev_targp = xfs_alloc_buftarg(ddev);
if (rtdev)
mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev);
mp->m_logdev_targp = (logdev && logdev != ddev) ?
xfs_alloc_buftarg(logdev) : mp->m_ddev_targp;
+ /*
+ * Setup flags based on mount(2) options and then the superblock
+ */
error = xfs_start_flags(args, mp, ronly);
if (error)
goto error;
-
error = xfs_readsb(mp);
if (error)
goto error;
-
error = xfs_finish_flags(args, mp, ronly);
if (error) {
xfs_freesb(mp);
goto error;
}
+ /*
+ * Setup xfs_mount buffer target pointers based on superblock
+ */
xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_sectsize);
if (logdev && logdev != ddev) {
@@ -465,10 +470,8 @@ xfs_mount(
xfs_setsize_buftarg(mp->m_rtdev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_blocksize);
- error = xfs_mountfs(vfsp, mp, ddev->bd_dev, flags);
- if (error)
- goto error;
- return 0;
+ if (!(error = XFS_IOINIT(vfsp, args, flags)))
+ return 0;
error:
xfs_binval(mp->m_ddev_targp);
@@ -479,9 +482,6 @@ xfs_mount(
xfs_binval(mp->m_rtdev_targp);
}
xfs_unmountfs_close(mp, NULL);
-
- free_mp:
- xfs_mount_free(mp, 1);
return error;
}
@@ -523,8 +523,9 @@ xfs_ibusy(
continue;
}
#ifdef DEBUG
- printk("busy vp=0x%p ip=0x%p inum %Ld count=%d\n",
- vp, ip, ip->i_ino, vn_count(vp));
+ cmn_err(CE_WARN, "%s: busy vp=0x%p ip=0x%p "
+ "inum %Ld count=%d",
+ __FUNCTION__, vp, ip, ip->i_ino, vn_count(vp));
#endif
busy++;
}
@@ -543,16 +544,15 @@ xfs_unmount(
int flags,
cred_t *credp)
{
- xfs_mount_t *mp;
- xfs_inode_t *rip;
- vnode_t *rvp = 0;
struct vfs *vfsp = bhvtovfs(bdp);
+ xfs_mount_t *mp = XFS_BHVTOM(bdp);
+ xfs_inode_t *rip;
+ vnode_t *rvp;
int unmount_event_wanted = 0;
int unmount_event_flags = 0;
int xfs_unmountfs_needed = 0;
int error;
- mp = XFS_BHVTOM(bdp);
rip = mp->m_rootip;
rvp = XFS_ITOV(rip);
@@ -560,7 +560,7 @@ xfs_unmount(
bhv_desc_t *rbdp;
rbdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(rvp), &xfs_vnodeops);
- error = dm_send_namesp_event(DM_EVENT_PREUNMOUNT,
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_PREUNMOUNT,
rbdp, DM_RIGHT_NULL, rbdp, DM_RIGHT_NULL,
NULL, NULL, 0, 0,
(mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))?
@@ -577,7 +577,8 @@ xfs_unmount(
*/
if (xfs_ibusy(mp)) {
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;
}
@@ -598,7 +599,7 @@ xfs_unmount(
* we want to make sure we invalidate dirty pages that belong to
* referenced vnodes as well.
*/
- if (XFS_FORCED_SHUTDOWN(mp)) {
+ if (XFS_FORCED_SHUTDOWN(mp)) {
error = xfs_sync(&mp->m_bhv,
(SYNC_WAIT | SYNC_CLOSE), credp);
ASSERT(error != EFSCORRUPTED);
@@ -612,9 +613,9 @@ out:
*/
if (unmount_event_wanted) {
/* Note: mp structure must still exist for
- * dm_send_unmount_event() call.
+ * XFS_SEND_UNMOUNT() call.
*/
- dm_send_unmount_event(vfsp, error == 0 ? rvp : NULL,
+ XFS_SEND_UNMOUNT(mp, vfsp, error == 0 ? rvp : NULL,
DM_RIGHT_NULL, 0, error, unmount_event_flags);
}
if (xfs_unmountfs_needed) {
@@ -641,7 +642,7 @@ xfs_unmount_flush(
{
xfs_inode_t *rip = mp->m_rootip;
xfs_inode_t *rbmip;
- xfs_inode_t *rsumip=NULL;
+ xfs_inode_t *rsumip = NULL;
vnode_t *rvp = XFS_ITOV(rip);
int error;
@@ -675,23 +676,22 @@ xfs_unmount_flush(
}
/*
- * synchronously flush root inode to disk
+ * Synchronously flush root inode to disk
*/
error = xfs_iflush(rip, XFS_IFLUSH_SYNC);
-
if (error == EFSCORRUPTED)
goto fscorrupt_out2;
if (vn_count(rvp) != 1 && !relocation) {
xfs_iunlock(rip, XFS_ILOCK_EXCL);
- error = XFS_ERROR(EBUSY);
- return (error);
+ return XFS_ERROR(EBUSY);
}
+
/*
* Release dquot that rootinode, rbmino and rsumino might be holding,
* flush and purge the quota inodes.
*/
- error = xfs_qm_unmount_quotas(mp);
+ error = XFS_QM_UNMOUNT(mp);
if (error == EFSCORRUPTED)
goto fscorrupt_out2;
@@ -701,7 +701,7 @@ xfs_unmount_flush(
}
xfs_iunlock(rip, XFS_ILOCK_EXCL);
- return (0);
+ return 0;
fscorrupt_out:
xfs_ifunlock(rip);
@@ -709,8 +709,7 @@ fscorrupt_out:
fscorrupt_out2:
xfs_iunlock(rip, XFS_ILOCK_EXCL);
- error = XFS_ERROR(EFSCORRUPTED);
- return (error);
+ return XFS_ERROR(EFSCORRUPTED);
}
/*
@@ -725,12 +724,11 @@ xfs_root(
bhv_desc_t *bdp,
vnode_t **vpp)
{
- vnode_t *vp;
+ vnode_t *vp;
vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip);
VN_HOLD(vp);
*vpp = vp;
-
return 0;
}
@@ -1411,23 +1409,6 @@ xfs_syncsub(
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
* log activity, so if this isn't vfs_sync() then flush
* the log again. If SYNC_WAIT is set then do it synchronously.
@@ -1581,16 +1562,17 @@ xfs_vget(
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_unmount = xfs_unmount,
.vfs_root = xfs_root,
.vfs_statvfs = xfs_statvfs,
.vfs_sync = xfs_sync,
.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_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
};
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 593384e38a54..1ad2d54f7027 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -254,28 +254,26 @@ xfs_getattr(
*/
STATIC int
xfs_setattr(
- bhv_desc_t *bdp,
- vattr_t *vap,
- int flags,
- cred_t *credp)
+ bhv_desc_t *bdp,
+ vattr_t *vap,
+ int flags,
+ cred_t *credp)
{
- xfs_inode_t *ip;
- xfs_trans_t *tp;
- xfs_mount_t *mp;
- int mask;
- int code;
- uint lock_flags;
- uint commit_flags=0;
- uid_t uid=0, iuid=0;
- gid_t gid=0, igid=0;
- int timeflags = 0;
- vnode_t *vp;
- xfs_prid_t projid=0, iprojid=0;
- int privileged;
- int mandlock_before, mandlock_after;
- uint qflags;
- xfs_dquot_t *udqp, *gdqp, *olddquot1, *olddquot2;
- int file_owner;
+ xfs_inode_t *ip;
+ xfs_trans_t *tp;
+ xfs_mount_t *mp;
+ int mask;
+ int code;
+ uint lock_flags;
+ uint commit_flags=0;
+ uid_t uid=0, iuid=0;
+ gid_t gid=0, igid=0;
+ int timeflags = 0;
+ vnode_t *vp;
+ xfs_prid_t projid=0, iprojid=0;
+ int mandlock_before, mandlock_after;
+ struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
+ int file_owner;
vp = BHV_TO_VNODE(bdp);
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@@ -319,7 +317,8 @@ xfs_setattr(
* because the i_*dquot fields will get updated anyway.
*/
if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) {
- qflags = 0;
+ uint qflags = 0;
+
if (mask & XFS_AT_UID) {
uid = vap->va_uid;
qflags |= XFS_QMOPT_UQUOTA;
@@ -339,8 +338,8 @@ xfs_setattr(
*/
ASSERT(udqp == NULL);
ASSERT(gdqp == NULL);
- if ((code = xfs_qm_vop_dqalloc(mp, ip, uid, gid, qflags,
- &udqp, &gdqp)))
+ code = XFS_QM_DQVOPALLOC(mp, ip, uid,gid, qflags, &udqp, &gdqp);
+ if (code)
return (code);
}
@@ -365,7 +364,7 @@ xfs_setattr(
} else {
if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) &&
!(flags & ATTR_DMI)) {
- code = xfs_dm_send_data_event (DM_EVENT_TRUNCATE, bdp,
+ code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, bdp,
vap->va_size, 0, AT_DELAY_FLAG(flags), NULL);
if (code) {
lock_flags = 0;
@@ -482,15 +481,10 @@ xfs_setattr(
if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
(XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
ASSERT(tp);
- /*
- * XXX:casey - This may result in unnecessary auditing.
- */
- privileged = capable(CAP_FOWNER);
- if ((code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
- privileged ?
- XFS_QMOPT_FORCE_RES :
- 0)))
- /* out of quota */
+ code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
+ capable(CAP_FOWNER) ?
+ XFS_QMOPT_FORCE_RES : 0);
+ if (code) /* out of quota */
goto error_return;
}
}
@@ -520,10 +514,8 @@ xfs_setattr(
/*
* Make sure that the dquots are attached to the inode.
*/
- if (XFS_IS_QUOTA_ON(mp) && XFS_NOT_DQATTACHED(mp, ip)) {
- if ((code = xfs_qm_dqattach(ip, XFS_QMOPT_ILOCKED)))
- goto error_return;
- }
+ if ((code = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED)))
+ goto error_return;
}
/*
@@ -730,13 +722,8 @@ xfs_setattr(
if (XFS_IS_UQUOTA_ON(mp)) {
ASSERT(mask & XFS_AT_UID);
ASSERT(udqp);
- ASSERT(xfs_qm_dqid(udqp) == (xfs_dqid_t)uid);
- olddquot1 = xfs_qm_vop_chown(tp, ip,
- &ip->i_udquot,
- udqp);
- /*
- * We'll dqrele olddquot at the end.
- */
+ olddquot1 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
+ &ip->i_udquot, udqp);
}
ip->i_d.di_uid = uid;
}
@@ -744,10 +731,8 @@ xfs_setattr(
if (XFS_IS_GQUOTA_ON(mp)) {
ASSERT(mask & XFS_AT_GID);
ASSERT(gdqp);
- ASSERT(xfs_qm_dqid(gdqp) == gid);
- olddquot2 = xfs_qm_vop_chown(tp, ip,
- &ip->i_gdquot,
- gdqp);
+ olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
+ &ip->i_gdquot, gdqp);
}
ip->i_d.di_gid = gid;
}
@@ -802,9 +787,6 @@ xfs_setattr(
ip->i_d.di_flags = 0;
if (vap->va_xflags & XFS_XFLAG_REALTIME) {
ip->i_d.di_flags |= XFS_DIFLAG_REALTIME;
- /* This is replicated in the io core for
- * CXFS use
- */
ip->i_iocore.io_flags |= XFS_IOCORE_RT;
}
/* can't set PREALLOC this way, just ignore it */
@@ -866,16 +848,12 @@ xfs_setattr(
xfs_iunlock(ip, lock_flags);
/*
- * release any dquot(s) inode had kept before chown
+ * Release any dquot(s) the inode had kept before chown.
*/
- if (olddquot1)
- xfs_qm_dqrele(olddquot1);
- if (olddquot2)
- xfs_qm_dqrele(olddquot2);
- if (udqp)
- xfs_qm_dqrele(udqp);
- if (gdqp)
- xfs_qm_dqrele(gdqp);
+ XFS_QM_DQRELE(mp, olddquot1);
+ XFS_QM_DQRELE(mp, olddquot2);
+ XFS_QM_DQRELE(mp, udqp);
+ XFS_QM_DQRELE(mp, gdqp);
if (code) {
return code;
@@ -883,9 +861,9 @@ xfs_setattr(
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_ATTRIBUTE) &&
!(flags & ATTR_DMI)) {
- (void) dm_send_namesp_event (DM_EVENT_ATTRIBUTE, bdp, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL, NULL, NULL,
- 0, 0, AT_DELAY_FLAG(flags));
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, bdp, DM_RIGHT_NULL,
+ NULL, DM_RIGHT_NULL, NULL, NULL,
+ 0, 0, AT_DELAY_FLAG(flags));
}
return 0;
@@ -893,10 +871,8 @@ xfs_setattr(
commit_flags |= XFS_TRANS_ABORT;
/* FALLTHROUGH */
error_return:
- if (udqp)
- xfs_qm_dqrele(udqp);
- if (gdqp)
- xfs_qm_dqrele(gdqp);
+ XFS_QM_DQRELE(mp, udqp);
+ XFS_QM_DQRELE(mp, gdqp);
if (tp) {
xfs_trans_cancel(tp, commit_flags);
}
@@ -1286,14 +1262,8 @@ xfs_inactive_free_eofblocks(
/*
* Attach the dquots to the inode up front.
*/
- if (XFS_IS_QUOTA_ON(mp) &&
- ip->i_ino != mp->m_sb.sb_uquotino &&
- ip->i_ino != mp->m_sb.sb_gquotino) {
- if (XFS_NOT_DQATTACHED(mp, ip)) {
- if ((error = xfs_qm_dqattach(ip, 0)))
- return (error);
- }
- }
+ if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
+ return (error);
/*
* There are blocks after the end of file.
@@ -1683,7 +1653,7 @@ xfs_inactive(
if (ip->i_d.di_nlink == 0 &&
DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_DESTROY)) {
- (void) dm_send_destroy_event(bdp, DM_RIGHT_NULL);
+ (void) XFS_SEND_DESTROY(mp, bdp, DM_RIGHT_NULL);
}
error = 0;
@@ -1709,14 +1679,9 @@ xfs_inactive(
ASSERT(ip->i_d.di_nlink == 0);
- if (XFS_IS_QUOTA_ON(mp) &&
- ip->i_ino != mp->m_sb.sb_uquotino &&
- ip->i_ino != mp->m_sb.sb_gquotino) {
- if (XFS_NOT_DQATTACHED(mp, ip)) {
- if ((error = xfs_qm_dqattach(ip, 0)))
- return (VN_INACTIVE_CACHE);
- }
- }
+ if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
+ return (VN_INACTIVE_CACHE);
+
tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
if (truncate) {
/*
@@ -1826,20 +1791,18 @@ xfs_inactive(
* might do that, we need to make sure. Otherwise the
* inode might be lost for a long time or forever.
*/
- if (!XFS_FORCED_SHUTDOWN(tp->t_mountp)) {
+ if (!XFS_FORCED_SHUTDOWN(mp)) {
cmn_err(CE_NOTE,
- "xfs_inactive: xfs_ifree() returned an error = %d on %s",
- error,tp->t_mountp->m_fsname);
- xfs_force_shutdown(tp->t_mountp, XFS_METADATA_IO_ERROR);
+ "xfs_inactive: xfs_ifree() returned an error = %d on %s",
+ error, mp->m_fsname);
+ xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
}
xfs_trans_cancel(tp, commit_flags | XFS_TRANS_ABORT);
} else {
/*
* Credit the quota account(s). The inode is gone.
*/
- if (XFS_IS_QUOTA_ON(tp->t_mountp))
- xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_ICOUNT,
- -1);
+ XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_ICOUNT, -1);
/*
* Just ignore errors at this point. There is
@@ -1850,8 +1813,7 @@ xfs_inactive(
/*
* Release the dquots held by inode, if any.
*/
- if (ip->i_udquot || ip->i_gdquot)
- xfs_qm_dqdettach_inode(ip);
+ XFS_QM_DQDETACH(mp, ip);
xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
@@ -1925,7 +1887,7 @@ xfs_create(
uint cancel_flags;
int committed;
xfs_prid_t prid;
- xfs_dquot_t *udqp, *gdqp;
+ struct xfs_dquot *udqp, *gdqp;
uint resblks;
int dm_di_mode;
int namelen;
@@ -1935,22 +1897,22 @@ xfs_create(
vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
dp = XFS_BHVTOI(dir_bdp);
+ mp = dp->i_mount;
dm_di_mode = vap->va_mode|VTTOIF(vap->va_type);
namelen = VNAMELEN(dentry);
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
- error = dm_send_namesp_event(DM_EVENT_CREATE,
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
dir_bdp, DM_RIGHT_NULL, NULL,
DM_RIGHT_NULL, name, NULL,
dm_di_mode, 0, 0);
+
if (error)
return error;
dm_event_sent = 1;
}
- mp = dp->i_mount;
-
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -1965,14 +1927,10 @@ xfs_create(
/*
* Make sure that we have allocated dquot(s) on disk.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- error = xfs_qm_vop_dqalloc(mp, dp,
- current->fsuid, current->fsgid,
- XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT,
- &udqp, &gdqp);
- if (error)
- goto std_return;
- }
+ error = XFS_QM_DQVOPALLOC(mp, dp, current->fsuid, current->fsgid,
+ XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
+ if (error)
+ goto std_return;
ip = NULL;
dp_joined_to_trans = B_FALSE;
@@ -2008,13 +1966,10 @@ xfs_create(
/*
* Reserve disk quota and the inode.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- if (xfs_trans_reserve_quota(tp, udqp, gdqp, resblks,
- 1, 0)) {
- error = EDQUOT;
- goto error_return;
- }
- }
+ error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
+ if (error)
+ goto error_return;
+
if (resblks == 0 &&
(error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen)))
goto error_return;
@@ -2074,9 +2029,7 @@ xfs_create(
* These ids of the inode couldn't have changed since the new
* inode has been locked ever since it was created.
*/
- if (XFS_IS_QUOTA_ON(mp))
- xfs_qm_vop_dqattach_and_dqmod_newinode(tp, ip, udqp,
- gdqp);
+ XFS_QM_DQVOPCREATE(mp, tp, ip, udqp, gdqp);
/*
* xfs_trans_commit normally decrements the vnode ref count
@@ -2099,10 +2052,8 @@ xfs_create(
goto error_return;
}
- if (udqp)
- xfs_qm_dqrele(udqp);
- if (gdqp)
- xfs_qm_dqrele(gdqp);
+ XFS_QM_DQRELE(mp, udqp);
+ XFS_QM_DQRELE(mp, gdqp);
/*
* Propogate the fact that the vnode changed after the
@@ -2118,7 +2069,7 @@ std_return:
if ( (*vpp || (error != 0 && dm_event_sent != 0)) &&
DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
DM_EVENT_POSTCREATE)) {
- (void) dm_send_namesp_event(DM_EVENT_POSTCREATE,
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
dir_bdp, DM_RIGHT_NULL,
*vpp ? vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops):NULL,
DM_RIGHT_NULL, name, NULL,
@@ -2136,10 +2087,8 @@ std_return:
if (!dp_joined_to_trans && (dp != NULL))
xfs_iunlock(dp, XFS_ILOCK_EXCL);
- if (udqp)
- xfs_qm_dqrele(udqp);
- if (gdqp)
- xfs_qm_dqrele(gdqp);
+ XFS_QM_DQRELE(mp, udqp);
+ XFS_QM_DQRELE(mp, gdqp);
goto std_return;
@@ -2153,10 +2102,8 @@ std_return:
xfs_trans_cancel(tp, cancel_flags);
IRELE(ip);
- if (udqp)
- xfs_qm_dqrele(udqp);
- if (gdqp)
- xfs_qm_dqrele(gdqp);
+ XFS_QM_DQRELE(mp, udqp);
+ XFS_QM_DQRELE(mp, gdqp);
goto std_return;
}
@@ -2437,8 +2384,8 @@ xfs_remove(
namelen = VNAMELEN(dentry);
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
- error = dm_send_namesp_event(DM_EVENT_REMOVE, dir_bdp, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL,
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_bdp,
+ DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
name, NULL, 0, 0, 0);
if (error)
return error;
@@ -2471,17 +2418,13 @@ xfs_remove(
ITRACE(ip);
- if (XFS_IS_QUOTA_ON(mp)) {
- ASSERT(! error);
- if (XFS_NOT_DQATTACHED(mp, dp))
- error = xfs_qm_dqattach(dp, 0);
- if (!error && dp != ip && XFS_NOT_DQATTACHED(mp, ip))
- error = xfs_qm_dqattach(ip, 0);
- if (error) {
- REMOVE_DEBUG_TRACE(__LINE__);
- IRELE(ip);
- goto std_return;
- }
+ error = XFS_QM_DQATTACH(mp, dp, 0);
+ if (!error && dp != ip)
+ error = XFS_QM_DQATTACH(mp, ip, 0);
+ if (error) {
+ REMOVE_DEBUG_TRACE(__LINE__);
+ IRELE(ip);
+ goto std_return;
}
tp = xfs_trans_alloc(mp, XFS_TRANS_REMOVE);
@@ -2606,7 +2549,7 @@ xfs_remove(
std_return:
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp,
DM_EVENT_POSTREMOVE)) {
- (void) dm_send_namesp_event(DM_EVENT_POSTREMOVE,
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
dir_bdp, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL,
name, NULL, dm_di_mode, error, 0);
@@ -2690,7 +2633,7 @@ xfs_link(
return XFS_ERROR(EIO);
if (DM_EVENT_ENABLED(src_vp->v_vfsp, tdp, DM_EVENT_LINK)) {
- error = dm_send_namesp_event(DM_EVENT_LINK,
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK,
target_dir_bdp, DM_RIGHT_NULL,
src_bdp, DM_RIGHT_NULL,
target_name, NULL, 0, 0, 0);
@@ -2700,15 +2643,11 @@ xfs_link(
/* Return through std_return after this point. */
- if (XFS_IS_QUOTA_ON(mp)) {
- error = 0;
- if (XFS_NOT_DQATTACHED(mp, sip))
- error = xfs_qm_dqattach(sip, 0);
- if (!error && sip != tdp && XFS_NOT_DQATTACHED(mp, tdp))
- error = xfs_qm_dqattach(tdp, 0);
- if (error)
- goto std_return;
- }
+ error = XFS_QM_DQATTACH(mp, sip, 0);
+ if (!error && sip != tdp)
+ error = XFS_QM_DQATTACH(mp, tdp, 0);
+ if (error)
+ goto std_return;
tp = xfs_trans_alloc(mp, XFS_TRANS_LINK);
cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
@@ -2798,7 +2737,7 @@ xfs_link(
std_return:
if (DM_EVENT_ENABLED(src_vp->v_vfsp, sip,
DM_EVENT_POSTLINK)) {
- (void) dm_send_namesp_event(DM_EVENT_POSTLINK,
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK,
target_dir_bdp, DM_RIGHT_NULL,
src_bdp, DM_RIGHT_NULL,
target_name, NULL, 0, error, 0);
@@ -2813,8 +2752,6 @@ std_return:
goto std_return;
}
-
-
/*
* xfs_mkdir
*
@@ -2844,7 +2781,7 @@ xfs_mkdir(
boolean_t created = B_FALSE;
int dm_event_sent = 0;
xfs_prid_t prid;
- xfs_dquot_t *udqp, *gdqp;
+ struct xfs_dquot *udqp, *gdqp;
uint resblks;
int dm_di_mode;
int dir_namelen;
@@ -2863,7 +2800,7 @@ xfs_mkdir(
dm_di_mode = vap->va_mode|VTTOIF(vap->va_type);
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
- error = dm_send_namesp_event(DM_EVENT_CREATE,
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
dir_bdp, DM_RIGHT_NULL, NULL,
DM_RIGHT_NULL, dir_name, NULL,
dm_di_mode, 0, 0);
@@ -2886,14 +2823,10 @@ xfs_mkdir(
/*
* Make sure that we have allocated dquot(s) on disk.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- error = xfs_qm_vop_dqalloc(mp, dp,
- current->fsuid, current->fsgid,
- XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT,
- &udqp, &gdqp);
- if (error)
- goto std_return;
- }
+ error = XFS_QM_DQVOPALLOC(mp, dp, current->fsuid, current->fsgid,
+ XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
+ if (error)
+ goto std_return;
tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
@@ -2925,12 +2858,9 @@ xfs_mkdir(
/*
* Reserve disk quota and the inode.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- if (xfs_trans_reserve_quota(tp, udqp, gdqp, resblks, 1, 0)) {
- error = XFS_ERROR(EDQUOT);
- goto error_return;
- }
- }
+ error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
+ if (error)
+ goto error_return;
if (resblks == 0 &&
(error = XFS_DIR_CANENTER(mp, tp, dp, dir_name, dir_namelen)))
@@ -2999,9 +2929,7 @@ xfs_mkdir(
/*
* Attach the dquots to the new inode and modify the icount incore.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- xfs_qm_vop_dqattach_and_dqmod_newinode(tp, cdp, udqp, gdqp);
- }
+ XFS_QM_DQVOPCREATE(mp, tp, cdp, udqp, gdqp);
/*
* If this is a synchronous mount, make sure that the
@@ -3019,11 +2947,8 @@ xfs_mkdir(
}
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- if (udqp)
- xfs_qm_dqrele(udqp);
- if (gdqp)
- xfs_qm_dqrele(gdqp);
-
+ XFS_QM_DQRELE(mp, udqp);
+ XFS_QM_DQRELE(mp, gdqp);
if (error) {
IRELE(cdp);
}
@@ -3035,7 +2960,7 @@ std_return:
if ( (created || (error != 0 && dm_event_sent != 0)) &&
DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
DM_EVENT_POSTCREATE)) {
- (void) dm_send_namesp_event(DM_EVENT_POSTCREATE,
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
dir_bdp, DM_RIGHT_NULL,
created ? XFS_ITOBHV(cdp):NULL,
DM_RIGHT_NULL,
@@ -3051,11 +2976,8 @@ std_return:
cancel_flags |= XFS_TRANS_ABORT;
error_return:
xfs_trans_cancel(tp, cancel_flags);
-
- if (udqp)
- xfs_qm_dqrele(udqp);
- if (gdqp)
- xfs_qm_dqrele(gdqp);
+ XFS_QM_DQRELE(mp, udqp);
+ XFS_QM_DQRELE(mp, gdqp);
if (!dp_joined_to_trans && (dp != NULL)) {
xfs_iunlock(dp, XFS_ILOCK_EXCL);
@@ -3093,6 +3015,7 @@ xfs_rmdir(
dir_vp = BHV_TO_VNODE(dir_bdp);
dp = XFS_BHVTOI(dir_bdp);
+ mp = dp->i_mount;
vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
@@ -3101,7 +3024,7 @@ xfs_rmdir(
namelen = VNAMELEN(dentry);
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
- error = dm_send_namesp_event(DM_EVENT_REMOVE,
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
dir_bdp, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL,
name, NULL, 0, 0, 0);
@@ -3136,17 +3059,13 @@ xfs_rmdir(
/*
* Get the dquots for the inodes.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- ASSERT(! error);
- if (XFS_NOT_DQATTACHED(mp, dp))
- error = xfs_qm_dqattach(dp, 0);
- if (!error && dp != cdp && XFS_NOT_DQATTACHED(mp, cdp))
- error = xfs_qm_dqattach(cdp, 0);
- if (error) {
- IRELE(cdp);
- REMOVE_DEBUG_TRACE(__LINE__);
- goto std_return;
- }
+ error = XFS_QM_DQATTACH(mp, dp, 0);
+ if (!error && dp != cdp)
+ error = XFS_QM_DQATTACH(mp, cdp, 0);
+ if (error) {
+ IRELE(cdp);
+ REMOVE_DEBUG_TRACE(__LINE__);
+ goto std_return;
}
tp = xfs_trans_alloc(mp, XFS_TRANS_RMDIR);
@@ -3298,9 +3217,8 @@ xfs_rmdir(
/* Fall through to std_return with error = 0 or the errno
* from xfs_trans_commit. */
std_return:
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp,
- DM_EVENT_POSTREMOVE)) {
- (void) dm_send_namesp_event(DM_EVENT_POSTREMOVE,
+ if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) {
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
dir_bdp, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL,
name, NULL, dm_di_mode,
@@ -3391,7 +3309,7 @@ xfs_symlink(
int n;
xfs_buf_t *bp;
xfs_prid_t prid;
- xfs_dquot_t *udqp, *gdqp;
+ struct xfs_dquot *udqp, *gdqp;
uint resblks;
char *link_name = VNAME(dentry);
int link_namelen;
@@ -3446,10 +3364,9 @@ xfs_symlink(
}
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_SYMLINK)) {
- error = dm_send_namesp_event(DM_EVENT_SYMLINK, dir_bdp, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL,
- link_name, target_path,
- 0, 0, 0);
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_bdp,
+ DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
+ link_name, target_path, 0, 0, 0);
if (error)
return error;
}
@@ -3465,14 +3382,10 @@ xfs_symlink(
/*
* Make sure that we have allocated dquot(s) on disk.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- error = xfs_qm_vop_dqalloc(mp, dp,
- current->fsuid, current->fsgid,
- XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT,
- &udqp, &gdqp);
- if (error)
- goto std_return;
- }
+ error = XFS_QM_DQVOPALLOC(mp, dp, current->fsuid, current->fsgid,
+ XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
+ if (error)
+ goto std_return;
tp = xfs_trans_alloc(mp, XFS_TRANS_SYMLINK);
cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
@@ -3503,12 +3416,9 @@ xfs_symlink(
/*
* Reserve disk quota : blocks and inode.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- if (xfs_trans_reserve_quota(tp, udqp, gdqp, resblks, 1, 0)) {
- error = XFS_ERROR(EDQUOT);
- goto error_return;
- }
- }
+ error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
+ if (error)
+ goto error_return;
/*
* Check for ability to enter directory entry, if no space reserved.
@@ -3543,9 +3453,7 @@ xfs_symlink(
/*
* Also attach the dquot(s) to it, if applicable.
*/
- if (XFS_IS_QUOTA_ON(mp)) {
- xfs_qm_vop_dqattach_and_dqmod_newinode(tp, ip, udqp, gdqp);
- }
+ XFS_QM_DQVOPCREATE(mp, tp, ip, udqp, gdqp);
if (resblks)
resblks -= XFS_IALLOC_SPACE_RES(mp);
@@ -3641,22 +3549,19 @@ xfs_symlink(
goto error2;
}
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
- if (udqp)
- xfs_qm_dqrele(udqp);
- if (gdqp)
- xfs_qm_dqrele(gdqp);
+ XFS_QM_DQRELE(mp, udqp);
+ XFS_QM_DQRELE(mp, gdqp);
/* Fall through to std_return with error = 0 or errno from
* xfs_trans_commit */
std_return:
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
DM_EVENT_POSTSYMLINK)) {
- (void) dm_send_namesp_event(DM_EVENT_POSTSYMLINK,
- dir_bdp, DM_RIGHT_NULL,
- error? NULL:XFS_ITOBHV(ip),
- DM_RIGHT_NULL,
- link_name, target_path,
- 0, error, 0);
+ (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK,
+ dir_bdp, DM_RIGHT_NULL,
+ error ? NULL : XFS_ITOBHV(ip),
+ DM_RIGHT_NULL, link_name, target_path,
+ 0, error, 0);
}
if (!error) {
@@ -3675,10 +3580,8 @@ std_return:
cancel_flags |= XFS_TRANS_ABORT;
error_return:
xfs_trans_cancel(tp, cancel_flags);
- if (udqp)
- xfs_qm_dqrele(udqp);
- if (gdqp)
- xfs_qm_dqrele(gdqp);
+ XFS_QM_DQRELE(mp, udqp);
+ XFS_QM_DQRELE(mp, gdqp);
if (!dp_joined_to_trans && (dp != NULL)) {
xfs_iunlock(dp, XFS_ILOCK_EXCL);
@@ -4165,7 +4068,7 @@ xfs_alloc_file_space(
/*
* determine if this is a realtime file
*/
- if ((rt = (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) != 0) {
+ if ((rt = XFS_IS_REALTIME_INODE(ip)) != 0) {
if (ip->i_d.di_extsize)
rtextsize = ip->i_d.di_extsize;
else
@@ -4173,12 +4076,8 @@ xfs_alloc_file_space(
} else
rtextsize = 0;
- if (XFS_IS_QUOTA_ON(mp)) {
- if (XFS_NOT_DQATTACHED(mp, ip)) {
- if ((error = xfs_qm_dqattach(ip, 0)))
- return error;
- }
- }
+ if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
+ return error;
if (len <= 0)
return XFS_ERROR(EINVAL);
@@ -4200,7 +4099,7 @@ xfs_alloc_file_space(
end_dmi_offset = offset+len;
if (end_dmi_offset > ip->i_d.di_size)
end_dmi_offset = ip->i_d.di_size;
- error = xfs_dm_send_data_event(DM_EVENT_WRITE, XFS_ITOBHV(ip),
+ error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOBHV(ip),
offset, end_dmi_offset - offset,
0, NULL);
if (error)
@@ -4255,15 +4154,11 @@ retry:
break;
}
xfs_ilock(ip, XFS_ILOCK_EXCL);
- if (XFS_IS_QUOTA_ON(mp)) {
- if (xfs_trans_reserve_quota(tp,
- ip->i_udquot,
- ip->i_gdquot,
- resblks, 0, 0)) {
- error = XFS_ERROR(EDQUOT);
- goto error1;
- }
- }
+ error = XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp,
+ ip->i_udquot, ip->i_gdquot, resblks, 0, rt ?
+ XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
+ if (error)
+ goto error1;
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, ip);
@@ -4308,13 +4203,13 @@ dmapi_enospc_check:
if (error == ENOSPC && (attr_flags&ATTR_DMI) == 0 &&
DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_NOSPACE)) {
- error = dm_send_namesp_event(DM_EVENT_NOSPACE,
+ error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE,
XFS_ITOBHV(ip), DM_RIGHT_NULL,
XFS_ITOBHV(ip), DM_RIGHT_NULL,
NULL, NULL, 0, 0, 0); /* Delay flag intentionally unused */
if (error == 0)
goto retry; /* Maybe DMAPI app. has made space */
- /* else fall through with error from xfs_dm_send_data_event */
+ /* else fall through with error from XFS_SEND_DATA */
}
return error;
@@ -4434,38 +4329,32 @@ xfs_free_file_space(
int nimap;
uint resblks;
int rounding;
- int specrt;
+ int rt;
xfs_fileoff_t startoffset_fsb;
xfs_trans_t *tp;
vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
mp = ip->i_mount;
- if (XFS_IS_QUOTA_ON(mp)) {
- if (XFS_NOT_DQATTACHED(mp, ip)) {
- if ((error = xfs_qm_dqattach(ip, 0)))
- return error;
- }
- }
+ if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
+ return error;
error = 0;
if (len <= 0) /* if nothing being freed */
return error;
- specrt =
- (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) &&
- !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb);
+ rt = (ip->i_d.di_flags & XFS_DIFLAG_REALTIME);
startoffset_fsb = XFS_B_TO_FSB(mp, offset);
end_dmi_offset = offset + len;
endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
if (offset < ip->i_d.di_size &&
- (attr_flags&ATTR_DMI) == 0 &&
+ (attr_flags & ATTR_DMI) == 0 &&
DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
if (end_dmi_offset > ip->i_d.di_size)
end_dmi_offset = ip->i_d.di_size;
- error = xfs_dm_send_data_event(DM_EVENT_WRITE, XFS_ITOBHV(ip),
- offset, end_dmi_offset - offset,
- AT_DELAY_FLAG(attr_flags), NULL);
+ error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOBHV(ip),
+ offset, end_dmi_offset - offset,
+ AT_DELAY_FLAG(attr_flags), NULL);
if (error)
return(error);
}
@@ -4480,11 +4369,11 @@ xfs_free_file_space(
xfs_inval_cached_pages(XFS_ITOV(ip), &(ip->i_iocore), ioffset, 0, 0);
/*
* Need to zero the stuff we're not freeing, on disk.
- * If its specrt (realtime & can't use unwritten extents) then
- * we actually need to zero the extent edges. Otherwise xfs_bunmapi
+ * If its a realtime file & can't use unwritten extents then we
+ * actually need to zero the extent edges. Otherwise xfs_bunmapi
* will take care of it for us.
*/
- if (specrt) {
+ if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
nimap = 1;
error = xfs_bmapi(NULL, ip, startoffset_fsb, 1, 0, NULL, 0,
&imap, &nimap, NULL);
@@ -4561,15 +4450,11 @@ xfs_free_file_space(
break;
}
xfs_ilock(ip, XFS_ILOCK_EXCL);
- if (XFS_IS_QUOTA_ON(mp)) {
- if (xfs_trans_reserve_quota(tp,
- ip->i_udquot,
- ip->i_gdquot,
- resblks, 0, 0)) {
- error = XFS_ERROR(EDQUOT);
- goto error1;
- }
- }
+ error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
+ ip->i_udquot, ip->i_gdquot, resblks, 0, rt ?
+ XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
+ if (error)
+ goto error1;
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, ip);
diff --git a/fs/xfs/xfsidbg.c b/fs/xfs/xfsidbg.c
index 469622afcf09..b519b40626d7 100644
--- a/fs/xfs/xfsidbg.c
+++ b/fs/xfs/xfsidbg.c
@@ -31,8 +31,8 @@
*/
#include <xfs.h>
-#include <xfs_quota_priv.h>
#include <xfs_log_recover.h>
+#include "quota/xfs_qm.h"
#include "pagebuf/page_buf_internal.h"
#include <linux/ctype.h>
@@ -1320,13 +1320,13 @@ char *tab_vflags[] = {
"INVALID0x40000", /* 0x40000 */
"INVALID0x80000", /* 0x80000 */
"VROOT", /* 0x100000 */
- "VNOSWAP", /* 0x200000 */
- "VISSWAP", /* 0x400000 */
- "VREPLICABLE", /* 0x800000 */
- "VNOTREPLICABLE", /* 0x1000000 */
- "VDOCMP", /* 0x2000000 */
+ "INVALID0x200000", /* 0x200000 */
+ "INVALID00x400000", /* 0x400000 */
+ "INVALID0x800000", /* 0x800000 */
+ "INVALID0x1000000", /* 0x1000000 */
+ "INVALID0x2000000", /* 0x2000000 */
"VSHARE", /* 0x4000000 */
- "VFRLOCKS", /* 0x8000000 */
+ "INVALID0x8000000", /* 0x8000000 */
"VENF_LOCKING", /* 0x10000000 */
"VOPLOCK", /* 0x20000000 */
"VPURGE", /* 0x40000000 */
@@ -1373,9 +1373,10 @@ static void printvnode(vnode_t *vp)
kdb_printf("vnode: 0x%p type ", vp);
if ((size_t)vp->v_type >= sizeof(vnode_type)/sizeof(vnode_type[0]))
- kdb_printf("out of range 0x%x\n", vp->v_type);
+ kdb_printf("out of range 0x%x", vp->v_type);
else
- kdb_printf("%s\n", vnode_type[vp->v_type]);
+ kdb_printf("%s", vnode_type[vp->v_type]);
+ kdb_printf(" v_bh %p\n", &vp->v_bh);
if ((bh = vp->v_bh.bh_first)) {
kdb_printf(" v_inode 0x%p v_bh->bh_first 0x%p pobj 0x%p\n",
@@ -1397,6 +1398,9 @@ static void printvnode(vnode_t *vp)
#ifdef CONFIG_XFS_VNODE_TRACING
kdb_printf(" v_trace 0x%p\n", vp->v_trace);
#endif /* CONFIG_XFS_VNODE_TRACING */
+
+ kdb_printf(" v_vfsp 0x%p v_number %Lx\n",
+ vp->v_vfsp, vp->v_number);
}
@@ -4808,13 +4812,8 @@ xfsidbg_xnode(xfs_inode_t *ip)
static void
xfsidbg_xcore(xfs_iocore_t *io)
{
- if (IO_IS_XFS(io)) {
- kdb_printf("io_obj 0x%p (xinode) io_mount 0x%p\n",
- io->io_obj, io->io_mount);
- } else {
- kdb_printf("io_obj 0x%p (dcxvn) io_mount 0x%p\n",
- io->io_obj, io->io_mount);
- }
+ kdb_printf("io_obj 0x%p io_flags 0x%x io_mount 0x%p\n",
+ io->io_obj, io->io_flags, io->io_mount);
kdb_printf("new_size %Lx\n", io->io_new_size);
}