summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Simmons <jsimmons@kozmo.(none)>2003-03-26 00:00:40 -0800
committerJames Simmons <jsimmons@kozmo.(none)>2003-03-26 00:00:40 -0800
commit80d0fb70c7c053db2a9a0dcfdaeb8b56c959a188 (patch)
treed80e5c2dc80bf0a914640dfa713519b6c88e7fe7
parentc84b483af9fa45e631ccfc87a55e9b6edfb44d3c (diff)
parentfff263fed6ff605fdb20bfd3105f4117f30fb24a (diff)
Merge kozmo.(none):/usr/src/linus-2.5
into kozmo.(none):/usr/src/fbdev-2.5
-rw-r--r--CREDITS4
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/char/pcmcia/synclink_cs.c3
-rw-r--r--drivers/isdn/hisax/elsa_cs.c7
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c7
-rw-r--r--drivers/pci/Makefile3
-rw-r--r--drivers/pcmcia/Kconfig4
-rw-r--r--drivers/pcmcia/Makefile69
-rw-r--r--drivers/pcmcia/cardbus.c201
-rw-r--r--drivers/pcmcia/cistpl.c281
-rw-r--r--drivers/pcmcia/cs.c36
-rw-r--r--drivers/pcmcia/cs_internal.h7
-rw-r--r--drivers/pcmcia/hd64465_ss.c32
-rw-r--r--drivers/pcmcia/i82092.c88
-rw-r--r--drivers/pcmcia/i82092aa.h2
-rw-r--r--drivers/pcmcia/i82365.c77
-rw-r--r--drivers/pcmcia/pci_socket.c20
-rw-r--r--drivers/pcmcia/pci_socket.h2
-rw-r--r--drivers/pcmcia/ricoh.h2
-rw-r--r--drivers/pcmcia/rsrc_mgr.c273
-rw-r--r--drivers/pcmcia/sa1100_generic.c54
-rw-r--r--drivers/pcmcia/tcic.c85
-rw-r--r--drivers/pcmcia/ti113x.h6
-rw-r--r--drivers/pcmcia/yenta.c63
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c3
-rw-r--r--drivers/usb/Makefile1
-rw-r--r--drivers/usb/class/audio.c1
-rw-r--r--drivers/usb/class/cdc-acm.c2
-rw-r--r--drivers/usb/core/buffer.c1
-rw-r--r--drivers/usb/core/hcd.c9
-rw-r--r--drivers/usb/core/hub.c56
-rw-r--r--drivers/usb/core/message.c1
-rw-r--r--drivers/usb/core/usb-debug.c1
-rw-r--r--drivers/usb/core/usb.c13
-rw-r--r--drivers/usb/host/ohci-hcd.c1
-rw-r--r--drivers/usb/image/mdc800.c1
-rw-r--r--drivers/usb/media/ov511.c1
-rw-r--r--drivers/usb/media/stv680.c1
-rw-r--r--drivers/usb/misc/emi26.c37
-rw-r--r--drivers/usb/misc/speedtch.c386
-rw-r--r--drivers/usb/misc/usbtest.c7
-rw-r--r--drivers/usb/net/cdc-ether.c19
-rw-r--r--drivers/usb/serial/kobil_sct.c17
-rw-r--r--drivers/usb/storage/isd200.c5
-rw-r--r--drivers/usb/storage/scsiglue.c54
-rw-r--r--drivers/usb/storage/transport.c3
-rw-r--r--drivers/usb/storage/usb.c6
-rw-r--r--drivers/usb/usb-skeleton.c6
-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
-rw-r--r--include/pcmcia/bus_ops.h154
-rw-r--r--include/pcmcia/cs.h1
-rw-r--r--include/pcmcia/ss.h3
118 files changed, 3712 insertions, 4157 deletions
diff --git a/CREDITS b/CREDITS
index 4b9b65953a24..8aef65abf085 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1210,6 +1210,10 @@ S: 25360 Georgia Tech Station
S: Atlanta, Georgia 30332
S: USA
+N: Brad Hards
+E: bradh@frogmouth.net
+D: Various USB bits, other minor patches
+
N: Angelo Haritsis
E: ah@computer.org
D: kernel patches (serial, watchdog)
diff --git a/MAINTAINERS b/MAINTAINERS
index 7b7c9edf37b0..fef4dadcfffb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1869,11 +1869,12 @@ S: Maintained
W: http://www.kroah.com/linux-usb/
USB CDC ETHERNET DRIVER
-P: Brad Hards
-M: bradh@frogmouth.net
+P: Greg Kroah-Hartman
+M: greg@kroah.com
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
+W: http://www.kroah.com/linux-usb/
USB EHCI DRIVER
P: David Brownell
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index a5ff3a48a8fd..e87ca474a11c 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -76,7 +76,6 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <pcmcia/bus_ops.h>
#ifdef CONFIG_SYNCLINK_SYNCPPP_MODULE
#define CONFIG_SYNCLINK_SYNCPPP 1
@@ -241,7 +240,6 @@ typedef struct _mgslpc_info {
dev_link_t link;
dev_node_t node;
int stop;
- struct bus_operations *bus;
/* SPPP/Cisco HDLC device parts */
int netcount;
@@ -826,7 +824,6 @@ static int mgslpc_event(event_t event, int priority,
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- info->bus = args->bus;
mgslpc_config(link);
break;
case CS_EVENT_PM_SUSPEND:
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index b79f67749311..00afdc97de31 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -53,7 +53,6 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <pcmcia/bus_ops.h>
MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards");
MODULE_AUTHOR("Klaus Lichtenwalder");
@@ -163,17 +162,12 @@ static dev_link_t *dev_list = NULL;
"stopped" due to a power management event, or card ejection. The
device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it.
-
- The bus_operations pointer is used on platforms for which we need
- to use special socket-specific versions of normal IO primitives
- (inb, outb, readb, writeb, etc) for card IO.
*/
typedef struct local_info_t {
dev_link_t link;
dev_node_t node;
int busy;
- struct bus_operations *bus;
} local_info_t;
/*====================================================================*/
@@ -522,7 +516,6 @@ static int elsa_cs_event(event_t event, int priority,
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- dev->bus = args->bus;
elsa_cs_config(link);
break;
case CS_EVENT_PM_SUSPEND:
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index a796311f7ae2..3ff07122b9fc 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -53,7 +53,6 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <pcmcia/bus_ops.h>
MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
MODULE_AUTHOR("Marcus Niemann");
@@ -171,17 +170,12 @@ static dev_link_t *dev_list = NULL;
"stopped" due to a power management event, or card ejection. The
device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it.
-
- The bus_operations pointer is used on platforms for which we need
- to use special socket-specific versions of normal IO primitives
- (inb, outb, readb, writeb, etc) for card IO.
*/
typedef struct local_info_t {
dev_link_t link;
dev_node_t node;
int stop;
- struct bus_operations *bus;
} local_info_t;
/*====================================================================*/
@@ -620,7 +614,6 @@ static int sedlbauer_event(event_t event, int priority,
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- dev->bus = args->bus;
sedlbauer_config(link);
break;
case CS_EVENT_PM_SUSPEND:
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 78ca0a2b3843..547939fdd943 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -29,6 +29,9 @@ ifdef CONFIG_HOTPLUG_PCI_CPCI
obj-y += setup-bus.o
endif
+# Hotplug (eg, cardbus) now requires setup-bus
+obj-$(CONFIG_HOTPLUG) += setup-bus.o
+
ifndef CONFIG_X86
obj-y += syscall.o
endif
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index f6ea2466e1a8..357f836ea987 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -87,5 +87,9 @@ config PCMCIA_SA1111
tristate "SA1111 support"
depends on PCMCIA_SA1100 && SA1111
+config PCMCIA_PROBE
+ bool
+ default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X
+
endmenu
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 64145126b7c8..9a593be3f399 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -2,46 +2,43 @@
# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
#
-obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o
+obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o
ifeq ($(CONFIG_CARDBUS),y)
- obj-$(CONFIG_PCMCIA) += yenta_socket.o
+ obj-$(CONFIG_PCMCIA) += yenta_socket.o
endif
-obj-$(CONFIG_I82365) += i82365.o
-obj-$(CONFIG_I82092) += i82092.o
-obj-$(CONFIG_TCIC) += tcic.o
-obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
-obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
-obj-$(CONFIG_PCMCIA_SA1111) += sa1111_cs.o
+obj-$(CONFIG_I82365) += i82365.o
+obj-$(CONFIG_I82092) += i82092.o
+obj-$(CONFIG_TCIC) += tcic.o
+obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
+obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
+obj-$(CONFIG_PCMCIA_SA1111) += sa1111_cs.o
-yenta_socket-objs := pci_socket.o yenta.o
+yenta_socket-y += pci_socket.o yenta.o
-pcmcia_core-objs-y := cistpl.o rsrc_mgr.o bulkmem.o cs.o
-pcmcia_core-objs-$(CONFIG_CARDBUS) += cardbus.o
-pcmcia_core-objs := $(pcmcia_core-objs-y)
+pcmcia_core-y += cistpl.o rsrc_mgr.o bulkmem.o cs.o
+pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
-sa1111_cs-objs-y := sa1111_generic.o
-sa1111_cs-objs-$(CONFIG_SA1100_ADSBITSY) += sa1100_adsbitsy.o
-sa1111_cs-objs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
-sa1111_cs-objs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o
-sa1111_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER) += sa1100_graphicsmaster.o
-sa1111_cs-objs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o
-sa1111_cs-objs-$(CONFIG_SA1100_PFS168) += sa1100_pfs168.o
-sa1111_cs-objs-$(CONFIG_SA1100_PT_SYSTEM3) += sa1100_system3.o
-sa1111_cs-objs-$(CONFIG_SA1100_XP860) += sa1100_xp860.o
-sa1111_cs-objs := $(sa1111_cs-objs-y)
+sa1111_cs-y += sa1111_generic.o
+sa1111_cs-$(CONFIG_SA1100_ADSBITSY) += sa1100_adsbitsy.o
+sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
+sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o
+sa1111_cs-$(CONFIG_SA1100_GRAPHICSMASTER) += sa1100_graphicsmaster.o
+sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o
+sa1111_cs-$(CONFIG_SA1100_PFS168) += sa1100_pfs168.o
+sa1111_cs-$(CONFIG_SA1100_PT_SYSTEM3) += sa1100_system3.o
+sa1111_cs-$(CONFIG_SA1100_XP860) += sa1100_xp860.o
-sa1100_cs-objs-y := sa1100_generic.o
-sa1100_cs-objs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
-sa1100_cs-objs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
-sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET) += sa1100_flexanet.o
-sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD) += sa1100_freebird.o
-sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSCLIENT) += sa1100_graphicsclient.o
-sa1100_cs-objs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
-sa1100_cs-objs-$(CONFIG_SA1100_PANGOLIN) += sa1100_pangolin.o
-sa1100_cs-objs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
-sa1100_cs-objs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
-sa1100_cs-objs-$(CONFIG_SA1100_STORK) += sa1100_stork.o
-sa1100_cs-objs-$(CONFIG_SA1100_TRIZEPS) += sa1100_trizeps.o
-sa1100_cs-objs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o
-sa1100_cs-objs := $(sa1100_cs-objs-y)
+sa1100_cs-y += sa1100_generic.o
+sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
+sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
+sa1100_cs-$(CONFIG_SA1100_FLEXANET) += sa1100_flexanet.o
+sa1100_cs-$(CONFIG_SA1100_FREEBIRD) += sa1100_freebird.o
+sa1100_cs-$(CONFIG_SA1100_GRAPHICSCLIENT) += sa1100_graphicsclient.o
+sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
+sa1100_cs-$(CONFIG_SA1100_PANGOLIN) += sa1100_pangolin.o
+sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
+sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
+sa1100_cs-$(CONFIG_SA1100_STORK) += sa1100_stork.o
+sa1100_cs-$(CONFIG_SA1100_TRIZEPS) += sa1100_trizeps.o
+sa1100_cs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 40c33fc21ba5..00c30ba3ff56 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -87,10 +87,6 @@ static int pc_debug = PCMCIA_DEBUG;
#define PCDATA_CODE_TYPE 0x0014
#define PCDATA_INDICATOR 0x0015
-typedef struct cb_config_t {
- struct pci_dev *dev[8];
-} cb_config_t;
-
/*=====================================================================
Expansion ROM's have a special layout, and pointers specify an
@@ -173,11 +169,10 @@ int read_cb_mem(socket_info_t * s, int space, u_int addr, u_int len, void *ptr)
DEBUG(3, "cs: read_cb_mem(%d, %#x, %u)\n", space, addr, len);
- if (!s->cb_config)
+ dev = pci_find_slot(s->cap.cb_dev->subordinate->number, 0);
+ if (!dev)
goto fail;
- dev = s->cb_config->dev[0];
-
/* Config space? */
if (space == 0) {
if (addr + len > 0x100)
@@ -219,171 +214,61 @@ fail:
=====================================================================*/
-int cb_alloc(socket_info_t * s)
+/*
+ * Since there is only one interrupt available to CardBus
+ * devices, all devices downstream of this device must
+ * be using this IRQ.
+ */
+static void cardbus_assign_irqs(struct pci_bus *bus, int irq)
{
- struct pci_bus *bus;
- u_short vend, v, dev;
- u_char i, hdr, fn;
- cb_config_t *c;
- int irq;
-
- bus = s->cap.cb_dev->subordinate;
-
- pci_bus_read_config_word(bus, 0, PCI_VENDOR_ID, &vend);
- pci_bus_read_config_word(bus, 0, PCI_DEVICE_ID, &dev);
- printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, "
- "device 0x%04x\n", bus->number, vend, dev);
-
- pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr);
- fn = 1;
- if (hdr & 0x80) {
- do {
- if (pci_bus_read_config_word(bus, fn, PCI_VENDOR_ID, &v) ||
- !v || v == 0xffff)
- break;
- fn++;
- } while (fn < 8);
- }
- s->functions = fn;
-
- c = kmalloc(sizeof(struct cb_config_t), GFP_ATOMIC);
- if (!c)
- return CS_OUT_OF_RESOURCE;
- memset(c, 0, sizeof(struct cb_config_t));
-
- for (i = 0; i < fn; i++) {
- c->dev[i] = kmalloc(sizeof(struct pci_dev), GFP_ATOMIC);
- if (!c->dev[i]) {
- for (; i--; )
- kfree(c->dev[i]);
- kfree(c);
- return CS_OUT_OF_RESOURCE;
- }
- memset(c->dev[i], 0, sizeof(struct pci_dev));
- }
+ struct pci_dev *dev;
- irq = s->cap.pci_irq;
- for (i = 0; i < fn; i++) {
- struct pci_dev *dev = c->dev[i];
+ list_for_each_entry(dev, &bus->devices, bus_list) {
u8 irq_pin;
- int r;
-
- dev->bus = bus;
- dev->sysdata = bus->sysdata;
- dev->dev.parent = bus->dev;
- dev->dev.bus = &pci_bus_type;
- dev->devfn = i;
-
- pci_read_config_word(dev, PCI_VENDOR_ID, &dev->vendor);
- pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
- dev->hdr_type = hdr & 0x7f;
- dev->dma_mask = 0xffffffff;
- dev->dev.dma_mask = &dev->dma_mask;
-
- pci_setup_device(dev);
- strcpy(dev->dev.bus_id, dev->slot_name);
-
- /* We need to assign resources for expansion ROM. */
- for (r = 0; r < 7; r++) {
- struct resource *res = dev->resource + r;
- if (res->flags)
- pci_assign_resource(dev, r);
- }
-
- /* Does this function have an interrupt at all? */
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
- if (irq_pin)
+ if (irq_pin) {
dev->irq = irq;
-
- /* pci_enable_device needs to be called after pci_assign_resource */
- /* because it returns an error if (!res->start && res->end). */
- if (pci_enable_device(dev))
- continue;
-
- if (irq_pin)
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-
- device_register(&dev->dev);
- pci_insert_device(dev, bus);
- }
-
- s->cb_config = c;
- s->irq.AssignedIRQ = irq;
- return CS_SUCCESS;
-}
-
-void cb_free(socket_info_t * s)
-{
- cb_config_t *c = s->cb_config;
-
- if (c) {
- s->cb_config = NULL;
- pci_remove_behind_bridge(s->cap.cb_dev);
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+ }
- kfree(c);
- printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
+ if (dev->subordinate)
+ cardbus_assign_irqs(dev->subordinate, irq);
}
}
-/*=====================================================================
-
- cb_enable() has the job of configuring a socket for a Cardbus
- card, and initializing the card's PCI configuration registers.
-
- It first sets up the Cardbus bridge windows, for IO and memory
- accesses. Then, it initializes each card function's base address
- registers, interrupt line register, and command register.
-
- It is called as part of the RequestConfiguration card service.
- It should be called after a previous call to cb_config() (via the
- RequestIO service).
-
-======================================================================*/
-
-void cb_enable(socket_info_t * s)
+int cb_alloc(socket_info_t * s)
{
+ struct pci_bus *bus = s->cap.cb_dev->subordinate;
struct pci_dev *dev;
- u_char i;
-
- DEBUG(0, "cs: cb_enable(bus %d)\n", s->cap.cb_dev->subordinate->number);
-
- /* Configure bridge */
- cb_release_cis_mem(s);
-
- /* Set up PCI interrupt and command registers */
- for (i = 0; i < s->functions; i++) {
- dev = s->cb_config->dev[i];
- pci_write_config_byte(dev, PCI_COMMAND, PCI_COMMAND_MASTER |
- PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
- L1_CACHE_BYTES / 4);
- }
-
- if (s->irq.AssignedIRQ) {
- for (i = 0; i < s->functions; i++) {
- dev = s->cb_config->dev[i];
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
- s->irq.AssignedIRQ);
- }
- s->socket.io_irq = s->irq.AssignedIRQ;
- s->ss_entry->set_socket(s->sock, &s->socket);
- }
+ unsigned int max, pass;
+
+ s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
+// pcibios_fixup_bus(bus);
+
+ max = bus->secondary;
+ for (pass = 0; pass < 2; pass++)
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+ max = pci_scan_bridge(bus, dev, max, pass);
+
+ /*
+ * Size all resources below the CardBus controller.
+ */
+ pci_bus_size_bridges(bus);
+ pci_bus_assign_resources(bus);
+ cardbus_assign_irqs(bus, s->cap.pci_irq);
+ pci_enable_bridges(bus);
+ pci_bus_add_devices(bus);
+
+ s->irq.AssignedIRQ = s->cap.pci_irq;
+ return CS_SUCCESS;
}
-/*======================================================================
-
- cb_disable() unconfigures a Cardbus card previously set up by
- cb_enable().
-
- It is called from the ReleaseConfiguration service.
-
-======================================================================*/
-
-void cb_disable(socket_info_t * s)
+void cb_free(socket_info_t * s)
{
- DEBUG(0, "cs: cb_disable(bus %d)\n", s->cap.cb_dev->subordinate->number);
+ struct pci_dev *bridge = s->cap.cb_dev;
- /* Turn off bridge windows */
- cb_release_cis_mem(s);
+ pci_remove_behind_bridge(bridge);
}
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index e21005d25e45..c34acc53ebe3 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -47,7 +47,6 @@
#include <asm/byteorder.h>
#include <pcmcia/cs_types.h>
-#include <pcmcia/bus_ops.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
@@ -83,6 +82,52 @@ static const u_int exponent[] = {
INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */
+void release_cis_mem(socket_info_t *s)
+{
+ if (s->cis_mem.sys_start != 0) {
+ s->cis_mem.flags &= ~MAP_ACTIVE;
+ s->ss_entry->set_mem_map(s->sock, &s->cis_mem);
+ if (!(s->cap.features & SS_CAP_STATIC_MAP))
+ release_mem_region(s->cis_mem.sys_start, s->cap.map_size);
+ iounmap(s->cis_virt);
+ s->cis_mem.sys_start = 0;
+ s->cis_virt = NULL;
+ }
+}
+
+/*
+ * Map the card memory at "card_offset" into virtual space.
+ * If flags & MAP_ATTRIB, map the attribute space, otherwise
+ * map the memory space.
+ */
+static unsigned char *
+set_cis_map(socket_info_t *s, unsigned int card_offset, unsigned int flags)
+{
+ pccard_mem_map *mem = &s->cis_mem;
+ if (!(s->cap.features & SS_CAP_STATIC_MAP) &&
+ mem->sys_start == 0) {
+ int low = !(s->cap.features & SS_CAP_PAGE_REGS);
+ validate_mem(s);
+ mem->sys_start = 0;
+ if (find_mem_region(&mem->sys_start, s->cap.map_size,
+ s->cap.map_size, low, "card services", s)) {
+ printk(KERN_NOTICE "cs: unable to map card memory!\n");
+ return NULL;
+ }
+ mem->sys_stop = mem->sys_start+s->cap.map_size-1;
+ s->cis_virt = ioremap(mem->sys_start, s->cap.map_size);
+ }
+ mem->card_start = card_offset;
+ mem->flags = flags;
+ s->ss_entry->set_mem_map(s->sock, mem);
+ if (s->cap.features & SS_CAP_STATIC_MAP) {
+ if (s->cis_virt)
+ iounmap(s->cis_virt);
+ s->cis_virt = ioremap(mem->sys_start, s->cap.map_size);
+ }
+ return s->cis_virt;
+}
+
/*======================================================================
Low-level functions to read and write CIS memory. I think the
@@ -94,60 +139,60 @@ INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */
#define IS_ATTR 1
#define IS_INDIRECT 8
-static int setup_cis_mem(socket_info_t *s);
-
-static void set_cis_map(socket_info_t *s, pccard_mem_map *mem)
-{
- s->ss_entry->set_mem_map(s->sock, mem);
- if (s->cap.features & SS_CAP_STATIC_MAP) {
- if (s->cis_virt)
- bus_iounmap(s->cap.bus, s->cis_virt);
- s->cis_virt = bus_ioremap(s->cap.bus, mem->sys_start,
- s->cap.map_size);
- }
-}
-
int read_cis_mem(socket_info_t *s, int attr, u_int addr,
u_int len, void *ptr)
{
- pccard_mem_map *mem = &s->cis_mem;
- u_char *sys, *buf = ptr;
+ u_char *sys, *end, *buf = ptr;
DEBUG(3, "cs: read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
- if (setup_cis_mem(s) != 0) {
- memset(ptr, 0xff, len);
- return -1;
- }
- mem->flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed
locations in common memory */
u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
- if (attr & IS_ATTR) { addr *= 2; flags = ICTRL0_AUTOINC; }
- mem->card_start = 0; mem->flags = MAP_ACTIVE;
- set_cis_map(s, mem);
- sys = s->cis_virt;
- bus_writeb(s->cap.bus, flags, sys+CISREG_ICTRL0);
- bus_writeb(s->cap.bus, addr & 0xff, sys+CISREG_IADDR0);
- bus_writeb(s->cap.bus, (addr>>8) & 0xff, sys+CISREG_IADDR1);
- bus_writeb(s->cap.bus, (addr>>16) & 0xff, sys+CISREG_IADDR2);
- bus_writeb(s->cap.bus, (addr>>24) & 0xff, sys+CISREG_IADDR3);
+ if (attr & IS_ATTR) {
+ addr *= 2;
+ flags = ICTRL0_AUTOINC;
+ }
+
+ sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
+ if (!sys) {
+ memset(ptr, 0xff, len);
+ return -1;
+ }
+
+ writeb(flags, sys+CISREG_ICTRL0);
+ writeb(addr & 0xff, sys+CISREG_IADDR0);
+ writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
+ writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
+ writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
for ( ; len > 0; len--, buf++)
- *buf = bus_readb(s->cap.bus, sys+CISREG_IDATA0);
+ *buf = readb(sys+CISREG_IDATA0);
} else {
- u_int inc = 1;
- if (attr) { mem->flags |= MAP_ATTRIB; inc++; addr *= 2; }
- sys += (addr & (s->cap.map_size-1));
- mem->card_start = addr & ~(s->cap.map_size-1);
+ u_int inc = 1, card_offset, flags;
+
+ flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
+ if (attr) {
+ flags |= MAP_ATTRIB;
+ inc++;
+ addr *= 2;
+ }
+
+ card_offset = addr & ~(s->cap.map_size-1);
while (len) {
- set_cis_map(s, mem);
- sys = s->cis_virt + (addr & (s->cap.map_size-1));
+ sys = set_cis_map(s, card_offset, flags);
+ if (!sys) {
+ memset(ptr, 0xff, len);
+ return -1;
+ }
+ end = sys + s->cap.map_size;
+ sys = sys + (addr & (s->cap.map_size-1));
for ( ; len > 0; len--, buf++, sys += inc) {
- if (sys == s->cis_virt+s->cap.map_size) break;
- *buf = bus_readb(s->cap.bus, sys);
+ if (sys == end)
+ break;
+ *buf = readb(sys);
}
- mem->card_start += s->cap.map_size;
+ card_offset += s->cap.map_size;
addr = 0;
}
}
@@ -160,134 +205,56 @@ int read_cis_mem(socket_info_t *s, int attr, u_int addr,
void write_cis_mem(socket_info_t *s, int attr, u_int addr,
u_int len, void *ptr)
{
- pccard_mem_map *mem = &s->cis_mem;
- u_char *sys, *buf = ptr;
+ u_char *sys, *end, *buf = ptr;
DEBUG(3, "cs: write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
- if (setup_cis_mem(s) != 0) return;
- mem->flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed
locations in common memory */
u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
- if (attr & IS_ATTR) { addr *= 2; flags = ICTRL0_AUTOINC; }
- mem->card_start = 0; mem->flags = MAP_ACTIVE;
- set_cis_map(s, mem);
- sys = s->cis_virt;
- bus_writeb(s->cap.bus, flags, sys+CISREG_ICTRL0);
- bus_writeb(s->cap.bus, addr & 0xff, sys+CISREG_IADDR0);
- bus_writeb(s->cap.bus, (addr>>8) & 0xff, sys+CISREG_IADDR1);
- bus_writeb(s->cap.bus, (addr>>16) & 0xff, sys+CISREG_IADDR2);
- bus_writeb(s->cap.bus, (addr>>24) & 0xff, sys+CISREG_IADDR3);
- for ( ; len > 0; len--, buf++)
- bus_writeb(s->cap.bus, *buf, sys+CISREG_IDATA0);
- } else {
- int inc = 1;
- if (attr & IS_ATTR) { mem->flags |= MAP_ATTRIB; inc++; addr *= 2; }
- mem->card_start = addr & ~(s->cap.map_size-1);
- while (len) {
- set_cis_map(s, mem);
- sys = s->cis_virt + (addr & (s->cap.map_size-1));
- for ( ; len > 0; len--, buf++, sys += inc) {
- if (sys == s->cis_virt+s->cap.map_size) break;
- bus_writeb(s->cap.bus, *buf, sys);
- }
- mem->card_start += s->cap.map_size;
- addr = 0;
+ if (attr & IS_ATTR) {
+ addr *= 2;
+ flags = ICTRL0_AUTOINC;
}
- }
-}
-
-/*======================================================================
-
- This is tricky... when we set up CIS memory, we try to validate
- the memory window space allocations.
-
-======================================================================*/
-/* Scratch pointer to the socket we use for validation */
-static socket_info_t *vs = NULL;
+ sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
+ if (!sys)
+ return; /* FIXME: Error */
-/* Validation function for cards with a valid CIS */
-static int cis_readable(u_long base)
-{
- cisinfo_t info1, info2;
- int ret;
- vs->cis_mem.sys_start = base;
- vs->cis_mem.sys_stop = base+vs->cap.map_size-1;
- vs->cis_virt = bus_ioremap(vs->cap.bus, base, vs->cap.map_size);
- ret = pcmcia_validate_cis(vs->clients, &info1);
- /* invalidate mapping and CIS cache */
- bus_iounmap(vs->cap.bus, vs->cis_virt); vs->cis_used = 0;
- if ((ret != 0) || (info1.Chains == 0))
- return 0;
- vs->cis_mem.sys_start = base+vs->cap.map_size;
- vs->cis_mem.sys_stop = base+2*vs->cap.map_size-1;
- vs->cis_virt = bus_ioremap(vs->cap.bus, base+vs->cap.map_size,
- vs->cap.map_size);
- ret = pcmcia_validate_cis(vs->clients, &info2);
- bus_iounmap(vs->cap.bus, vs->cis_virt); vs->cis_used = 0;
- return ((ret == 0) && (info1.Chains == info2.Chains));
-}
+ writeb(flags, sys+CISREG_ICTRL0);
+ writeb(addr & 0xff, sys+CISREG_IADDR0);
+ writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
+ writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
+ writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
+ for ( ; len > 0; len--, buf++)
+ writeb(*buf, sys+CISREG_IDATA0);
+ } else {
+ u_int inc = 1, card_offset, flags;
-/* Validation function for simple memory cards */
-static int checksum(u_long base)
-{
- int i, a, b, d;
- vs->cis_mem.sys_start = base;
- vs->cis_mem.sys_stop = base+vs->cap.map_size-1;
- vs->cis_virt = bus_ioremap(vs->cap.bus, base, vs->cap.map_size);
- vs->cis_mem.card_start = 0;
- vs->cis_mem.flags = MAP_ACTIVE;
- vs->ss_entry->set_mem_map(vs->sock, &vs->cis_mem);
- /* Don't bother checking every word... */
- a = 0; b = -1;
- for (i = 0; i < vs->cap.map_size; i += 44) {
- d = bus_readl(vs->cap.bus, vs->cis_virt+i);
- a += d; b &= d;
- }
- bus_iounmap(vs->cap.bus, vs->cis_virt);
- return (b == -1) ? -1 : (a>>1);
-}
+ flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
+ if (attr & IS_ATTR) {
+ flags |= MAP_ATTRIB;
+ inc++;
+ addr *= 2;
+ }
-static int checksum_match(u_long base)
-{
- int a = checksum(base), b = checksum(base+vs->cap.map_size);
- return ((a == b) && (a >= 0));
-}
+ card_offset = addr & ~(s->cap.map_size-1);
+ while (len) {
+ sys = set_cis_map(s, card_offset, flags);
+ if (!sys)
+ return; /* FIXME: error */
-static int setup_cis_mem(socket_info_t *s)
-{
- if (!(s->cap.features & SS_CAP_STATIC_MAP) &&
- (s->cis_mem.sys_start == 0)) {
- int low = !(s->cap.features & SS_CAP_PAGE_REGS);
- vs = s;
- validate_mem(cis_readable, checksum_match, low, s);
- s->cis_mem.sys_start = 0;
- vs = NULL;
- if (find_mem_region(&s->cis_mem.sys_start, s->cap.map_size,
- s->cap.map_size, low, "card services", s)) {
- printk(KERN_NOTICE "cs: unable to map card memory!\n");
- return -1;
+ end = sys + s->cap.map_size;
+ sys = sys + (addr & (s->cap.map_size-1));
+ for ( ; len > 0; len--, buf++, sys += inc) {
+ if (sys == end)
+ break;
+ writeb(*buf, sys);
+ }
+ card_offset += s->cap.map_size;
+ addr = 0;
}
- s->cis_mem.sys_stop = s->cis_mem.sys_start+s->cap.map_size-1;
- s->cis_virt = bus_ioremap(s->cap.bus, s->cis_mem.sys_start,
- s->cap.map_size);
- }
- return 0;
-}
-
-void release_cis_mem(socket_info_t *s)
-{
- if (s->cis_mem.sys_start != 0) {
- s->cis_mem.flags &= ~MAP_ACTIVE;
- s->ss_entry->set_mem_map(s->sock, &s->cis_mem);
- if (!(s->cap.features & SS_CAP_STATIC_MAP))
- release_mem_region(s->cis_mem.sys_start, s->cap.map_size);
- bus_iounmap(s->cap.bus, s->cis_virt);
- s->cis_mem.sys_start = 0;
- s->cis_virt = NULL;
}
}
@@ -427,11 +394,9 @@ int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
tuple->TupleLink = tuple->Flags = 0;
#ifdef CONFIG_CARDBUS
if (s->state & SOCKET_CARDBUS) {
+ struct pci_dev *dev = s->cap.cb_dev;
u_int ptr;
- struct pci_dev *dev = pci_find_slot (s->cap.cb_dev->subordinate->number, 0);
- if (!dev)
- return CS_BAD_HANDLE;
- pci_read_config_dword(dev, 0x28, &ptr);
+ pci_bus_read_config_dword(dev->subordinate, 0, PCI_CARDBUS_CIS, &ptr);
tuple->CISOffset = ptr & ~7;
SPACE(tuple->Flags) = (ptr & 7);
} else
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index f235eb1fda73..31d8b5b451a3 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -59,7 +59,6 @@
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
-#include <pcmcia/bus_ops.h>
#include "cs_internal.h"
#ifdef CONFIG_PCI
@@ -622,8 +621,10 @@ static void unreset_socket(socket_info_t *s)
send_event(s, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
} else if (s->state & SOCKET_SETUP_PENDING) {
#ifdef CONFIG_CARDBUS
- if (s->state & SOCKET_CARDBUS)
+ if (s->state & SOCKET_CARDBUS) {
cb_alloc(s);
+ s->state |= SOCKET_CARDBUS_CONFIG;
+ }
#endif
send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
s->state &= ~SOCKET_SETUP_PENDING;
@@ -1077,7 +1078,7 @@ int pcmcia_get_configuration_info(client_handle_t handle,
config->Vcc = s->socket.Vcc;
config->Vpp1 = config->Vpp2 = s->socket.Vpp;
config->Option = s->cap.cb_dev->subordinate->number;
- if (s->cb_config) {
+ if (s->state & SOCKET_CARDBUS_CONFIG) {
config->Attributes = CONF_VALID_CLIENT;
config->IntType = INT_CARDBUS;
config->AssignedIRQ = s->irq.AssignedIRQ;
@@ -1473,7 +1474,6 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
client->event_handler = req->event_handler;
client->event_callback_args = req->event_callback_args;
client->event_callback_args.client_handle = client;
- client->event_callback_args.bus = s->cap.bus;
if (s->state & SOCKET_CARDBUS)
client->state |= CLIENT_CARDBUS;
@@ -1522,11 +1522,8 @@ int pcmcia_release_configuration(client_handle_t handle)
s = SOCKET(handle);
#ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS) {
- cb_disable(s);
- s->lock_count = 0;
+ if (handle->state & CLIENT_CARDBUS)
return CS_SUCCESS;
- }
#endif
if (!(handle->state & CLIENT_STALE)) {
@@ -1573,9 +1570,8 @@ int pcmcia_release_io(client_handle_t handle, io_req_t *req)
s = SOCKET(handle);
#ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS) {
+ if (handle->state & CLIENT_CARDBUS)
return CS_SUCCESS;
- }
#endif
if (!(handle->state & CLIENT_STALE)) {
@@ -1622,10 +1618,10 @@ int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
}
if (req->Attributes & IRQ_HANDLE_PRESENT) {
- bus_free_irq(s->cap.bus, req->AssignedIRQ, req->Instance);
+ free_irq(req->AssignedIRQ, req->Instance);
}
-#ifdef CONFIG_ISA
+#ifdef CONFIG_PCMCIA_PROBE
if (req->AssignedIRQ != s->cap.pci_irq)
undo_irq(req->Attributes, req->AssignedIRQ);
#endif
@@ -1678,16 +1674,8 @@ int pcmcia_request_configuration(client_handle_t handle,
return CS_NO_CARD;
#ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS) {
- if (!(req->IntType & INT_CARDBUS))
- return CS_UNSUPPORTED_MODE;
- if (s->lock_count != 0)
- return CS_CONFIGURATION_LOCKED;
- cb_enable(s);
- handle->state |= CLIENT_CONFIG_LOCKED;
- s->lock_count++;
- return CS_SUCCESS;
- }
+ if (handle->state & CLIENT_CARDBUS)
+ return CS_UNSUPPORTED_MODE;
#endif
if (req->IntType & INT_CARDBUS)
@@ -1887,7 +1875,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
if (!s->cap.irq_mask) {
irq = s->cap.pci_irq;
ret = (irq) ? 0 : CS_IN_USE;
-#ifdef CONFIG_ISA
+#ifdef CONFIG_PCMCIA_PROBE
} else if (s->irq.AssignedIRQ != 0) {
/* If the interrupt is already assigned, it must match */
irq = s->irq.AssignedIRQ;
@@ -1917,7 +1905,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
if (ret != 0) return ret;
if (req->Attributes & IRQ_HANDLE_PRESENT) {
- if (bus_request_irq(s->cap.bus, irq, req->Handler,
+ if (request_irq(irq, req->Handler,
((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
(s->functions > 1) ||
(irq == s->cap.pci_irq)) ? SA_SHIRQ : 0,
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index a0c8bf9196c8..963ca8abaca0 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -136,7 +136,6 @@ typedef struct socket_info_t {
#ifdef CONFIG_CARDBUS
struct resource * cb_cis_res;
u_char *cb_cis_virt;
- struct cb_config_t *cb_config;
#endif
struct {
u_int AssignedIRQ;
@@ -176,6 +175,7 @@ typedef struct socket_info_t {
#define SOCKET_IO_REQ(i) (0x1000<<(i))
#define SOCKET_REGION_INFO 0x4000
#define SOCKET_CARDBUS 0x8000
+#define SOCKET_CARDBUS_CONFIG 0x10000
#define CHECK_HANDLE(h) \
(((h) == NULL) || ((h)->client_magic != CLIENT_MAGIC))
@@ -198,8 +198,6 @@ typedef struct socket_info_t {
/* In cardbus.c */
int cb_alloc(socket_info_t *s);
void cb_free(socket_info_t *s);
-void cb_enable(socket_info_t *s);
-void cb_disable(socket_info_t *s);
int read_cb_mem(socket_info_t *s, int space, u_int addr, u_int len, void *ptr);
void cb_release_cis_mem(socket_info_t *s);
@@ -234,8 +232,7 @@ int write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf);
int copy_memory(memory_handle_t handle, copy_op_t *req);
/* In rsrc_mgr */
-void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
- int force_low, socket_info_t *s);
+void validate_mem(socket_info_t *s);
int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
char *name, socket_info_t *s);
int find_mem_region(u_long *base, u_long num, u_long align,
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index 37b8a95a4421..580d63f59298 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -599,21 +599,6 @@ static int hs_set_socket(unsigned int sock, socket_state_t *state)
/*============================================================*/
-static int hs_get_io_map(unsigned int sock, struct pccard_io_map *io)
-{
- hs_socket_t *sp = &hs_sockets[sock];
- int map = io->map;
-
- DPRINTK("hs_get_io_map(%d, %d)\n", sock, map);
- if (map >= MAX_IO_WIN)
- return -EINVAL;
-
- *io = sp->io_maps[map];
- return 0;
-}
-
-/*============================================================*/
-
static int hs_set_io_map(unsigned int sock, struct pccard_io_map *io)
{
hs_socket_t *sp = &hs_sockets[sock];
@@ -696,21 +681,6 @@ static int hs_set_io_map(unsigned int sock, struct pccard_io_map *io)
/*============================================================*/
-static int hs_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
-{
- hs_socket_t *sp = &hs_sockets[sock];
- int map = mem->map;
-
- DPRINTK("hs_get_mem_map(%d, %d)\n", sock, map);
- if (map >= MAX_WIN)
- return -EINVAL;
-
- *mem = sp->mem_maps[map];
- return 0;
-}
-
-/*============================================================*/
-
static int hs_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{
hs_socket_t *sp = &hs_sockets[sock];
@@ -894,9 +864,7 @@ static struct pccard_operations hs_operations = {
.get_status = hs_get_status,
.get_socket = hs_get_socket,
.set_socket = hs_set_socket,
- .get_io_map = hs_get_io_map,
.set_io_map = hs_set_io_map,
- .get_mem_map = hs_get_mem_map,
.set_mem_map = hs_set_mem_map,
.proc_setup = hs_proc_setup,
};
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index 9292bc1222ff..81afb84aa89d 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -63,9 +63,7 @@ static struct pccard_operations i82092aa_operations = {
.get_status = i82092aa_get_status,
.get_socket = i82092aa_get_socket,
.set_socket = i82092aa_set_socket,
- .get_io_map = i82092aa_get_io_map,
.set_io_map = i82092aa_set_io_map,
- .get_mem_map = i82092aa_get_mem_map,
.set_mem_map = i82092aa_set_mem_map,
.proc_setup = i82092aa_proc_setup,
};
@@ -688,34 +686,6 @@ static int i82092aa_set_socket(unsigned int sock, socket_state_t *state)
return 0;
}
-static int i82092aa_get_io_map(unsigned int sock, struct pccard_io_map *io)
-{
- unsigned char map, ioctl, addr;
-
- enter("i82092aa_get_io_map");
- map = io->map;
- if (map > 1) {
- leave("i82092aa_get_io_map with -EINVAL");
- return -EINVAL;
- }
-
- /* FIXME: How does this fit in with the PCI resource (re)allocation */
- io->start = indirect_read16(sock, I365_IO(map)+I365_W_START);
- io->stop = indirect_read16(sock, I365_IO(map)+I365_W_START);
-
- ioctl = indirect_read(sock,I365_IOCTL); /* IOCREG: I/O Control Register */
- addr = indirect_read(sock,I365_ADDRWIN); /* */
-
- io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0; /* check this out later */
- io->flags = 0;
-
- if (addr & I365_IOCTL_16BIT(map))
- io->flags |= MAP_AUTOSZ;
-
- leave("i82092aa_get_io_map");
- return 0;
-}
-
static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io)
{
unsigned char map, ioctl;
@@ -759,64 +729,6 @@ static int i82092aa_set_io_map(unsigned sock, struct pccard_io_map *io)
return 0;
}
-static int i82092aa_get_mem_map(unsigned sock, struct pccard_mem_map *mem)
-{
- unsigned short base, i;
- unsigned char map, addr;
-
- enter("i82092aa_get_mem_map");
-
- mem->flags = 0;
- mem->speed = 0;
- map = mem->map;
- if (map > 4) {
- leave("i82092aa_get_mem_map: -EINVAL");
- return -EINVAL;
- }
-
- addr = indirect_read(sock, I365_ADDRWIN);
-
- if (addr & I365_ENA_MEM(map))
- mem->flags |= MAP_ACTIVE; /* yes this mapping is active */
-
- base = I365_MEM(map);
-
- /* Find the start address - this register also has mapping info */
-
- i = indirect_read16(sock,base+I365_W_START);
- if (i & I365_MEM_16BIT)
- mem->flags |= MAP_16BIT;
- if (i & I365_MEM_0WS)
- mem->flags |= MAP_0WS;
-
- mem->sys_start = ((unsigned long)(i & 0x0fff) << 12);
-
- /* Find the end address - this register also has speed info */
- i = indirect_read16(sock,base+I365_W_STOP);
- if (i & I365_MEM_WS0)
- mem->speed = 1;
- if (i & I365_MEM_WS1)
- mem->speed += 2;
- mem->speed = to_ns(mem->speed);
- mem->sys_stop = ( (unsigned long)(i & 0x0fff) << 12) + 0x0fff;
-
- /* Find the card start address, also some more MAP attributes */
-
- i = indirect_read16(sock, base+I365_W_OFF);
- if (i & I365_MEM_WRPROT)
- mem->flags |= MAP_WRPROT;
- if (i & I365_MEM_REG)
- mem->flags |= MAP_ATTRIB;
- mem->card_start = ( (unsigned long)(i & 0x3fff)<12) + mem->sys_start;
- mem->card_start &= 0x3ffffff;
-
- printk("Card %i is from %lx to %lx \n",sock,mem->sys_start,mem->sys_stop);
-
- leave("i82092aa_get_mem_map");
- return 0;
-
-}
-
static int i82092aa_set_mem_map(unsigned sock, struct pccard_mem_map *mem)
{
unsigned short base, i;
diff --git a/drivers/pcmcia/i82092aa.h b/drivers/pcmcia/i82092aa.h
index 4e857688ec78..dc56daec6bb9 100644
--- a/drivers/pcmcia/i82092aa.h
+++ b/drivers/pcmcia/i82092aa.h
@@ -29,9 +29,7 @@ static void i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs);
static int i82092aa_get_status(unsigned int sock, u_int *value);
static int i82092aa_get_socket(unsigned int sock, socket_state_t *state);
static int i82092aa_set_socket(unsigned int sock, socket_state_t *state);
-static int i82092aa_get_io_map(unsigned int sock, struct pccard_io_map *io);
static int i82092aa_set_io_map(unsigned int sock, struct pccard_io_map *io);
-static int i82092aa_get_mem_map(unsigned int sock, struct pccard_mem_map *mem);
static int i82092aa_set_mem_map(unsigned int sock, struct pccard_mem_map *mem);
static int i82092aa_init(unsigned int s);
static int i82092aa_suspend(unsigned int sock);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index afc8e7380f5a..257c3503941c 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1250,29 +1250,6 @@ static int i365_set_socket(u_short sock, socket_state_t *state)
/*====================================================================*/
-static int i365_get_io_map(u_short sock, struct pccard_io_map *io)
-{
- u_char map, ioctl, addr;
-
- map = io->map;
- if (map > 1) return -EINVAL;
- io->start = i365_get_pair(sock, I365_IO(map)+I365_W_START);
- io->stop = i365_get_pair(sock, I365_IO(map)+I365_W_STOP);
- ioctl = i365_get(sock, I365_IOCTL);
- addr = i365_get(sock, I365_ADDRWIN);
- io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0;
- io->flags = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0;
- io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;
- io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;
- io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;
- DEBUG(1, "i82365: GetIOMap(%d, %d) = %#2.2x, %d ns, "
- "%#4.4x-%#4.4x\n", sock, map, io->flags, io->speed,
- io->start, io->stop);
- return 0;
-} /* i365_get_io_map */
-
-/*====================================================================*/
-
static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
{
u_char map, ioctl;
@@ -1302,42 +1279,6 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
/*====================================================================*/
-static int i365_get_mem_map(u_short sock, struct pccard_mem_map *mem)
-{
- u_short base, i;
- u_char map, addr;
-
- map = mem->map;
- if (map > 4) return -EINVAL;
- addr = i365_get(sock, I365_ADDRWIN);
- mem->flags = (addr & I365_ENA_MEM(map)) ? MAP_ACTIVE : 0;
- base = I365_MEM(map);
-
- i = i365_get_pair(sock, base+I365_W_START);
- mem->flags |= (i & I365_MEM_16BIT) ? MAP_16BIT : 0;
- mem->flags |= (i & I365_MEM_0WS) ? MAP_0WS : 0;
- mem->sys_start = ((u_long)(i & 0x0fff) << 12);
-
- i = i365_get_pair(sock, base+I365_W_STOP);
- mem->speed = (i & I365_MEM_WS0) ? 1 : 0;
- mem->speed += (i & I365_MEM_WS1) ? 2 : 0;
- mem->speed = to_ns(mem->speed);
- mem->sys_stop = ((u_long)(i & 0x0fff) << 12) + 0x0fff;
-
- i = i365_get_pair(sock, base+I365_W_OFF);
- mem->flags |= (i & I365_MEM_WRPROT) ? MAP_WRPROT : 0;
- mem->flags |= (i & I365_MEM_REG) ? MAP_ATTRIB : 0;
- mem->card_start = ((u_int)(i & 0x3fff) << 12) + mem->sys_start;
- mem->card_start &= 0x3ffffff;
-
- DEBUG(1, "i82365: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5."
- "5lx, %#5.5x\n", sock, mem->map, mem->flags, mem->speed,
- mem->sys_start, mem->sys_stop, mem->card_start);
- return 0;
-} /* i365_get_mem_map */
-
-/*====================================================================*/
-
static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
{
u_short base, i;
@@ -1506,14 +1447,6 @@ static int pcic_set_socket(unsigned int sock, socket_state_t *state)
LOCKED(i365_set_socket(sock, state));
}
-static int pcic_get_io_map(unsigned int sock, struct pccard_io_map *io)
-{
- if (socket[sock].flags & IS_ALIVE)
- return -EINVAL;
-
- LOCKED(i365_get_io_map(sock, io));
-}
-
static int pcic_set_io_map(unsigned int sock, struct pccard_io_map *io)
{
if (socket[sock].flags & IS_ALIVE)
@@ -1522,14 +1455,6 @@ static int pcic_set_io_map(unsigned int sock, struct pccard_io_map *io)
LOCKED(i365_set_io_map(sock, io));
}
-static int pcic_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
-{
- if (socket[sock].flags & IS_ALIVE)
- return -EINVAL;
-
- LOCKED(i365_get_mem_map(sock, mem));
-}
-
static int pcic_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{
if (socket[sock].flags & IS_ALIVE)
@@ -1571,9 +1496,7 @@ static struct pccard_operations pcic_operations = {
.get_status = pcic_get_status,
.get_socket = pcic_get_socket,
.set_socket = pcic_set_socket,
- .get_io_map = pcic_get_io_map,
.set_io_map = pcic_set_io_map,
- .get_mem_map = pcic_get_mem_map,
.set_mem_map = pcic_set_mem_map,
.proc_setup = pcic_proc_setup,
};
diff --git a/drivers/pcmcia/pci_socket.c b/drivers/pcmcia/pci_socket.c
index da0e6ae74b4c..147167f787c6 100644
--- a/drivers/pcmcia/pci_socket.c
+++ b/drivers/pcmcia/pci_socket.c
@@ -105,15 +105,6 @@ static int pci_set_socket(unsigned int sock, socket_state_t *state)
return -EINVAL;
}
-static int pci_get_io_map(unsigned int sock, struct pccard_io_map *io)
-{
- pci_socket_t *socket = pci_socket_array + sock;
-
- if (socket->op && socket->op->get_io_map)
- return socket->op->get_io_map(socket, io);
- return -EINVAL;
-}
-
static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io)
{
pci_socket_t *socket = pci_socket_array + sock;
@@ -123,15 +114,6 @@ static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io)
return -EINVAL;
}
-static int pci_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
-{
- pci_socket_t *socket = pci_socket_array + sock;
-
- if (socket->op && socket->op->get_mem_map)
- return socket->op->get_mem_map(socket, mem);
- return -EINVAL;
-}
-
static int pci_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
{
pci_socket_t *socket = pci_socket_array + sock;
@@ -158,9 +140,7 @@ static struct pccard_operations pci_socket_operations = {
.get_status = pci_get_status,
.get_socket = pci_get_socket,
.set_socket = pci_set_socket,
- .get_io_map = pci_get_io_map,
.set_io_map = pci_set_io_map,
- .get_mem_map = pci_get_mem_map,
.set_mem_map = pci_set_mem_map,
.proc_setup = pci_proc_setup,
};
diff --git a/drivers/pcmcia/pci_socket.h b/drivers/pcmcia/pci_socket.h
index c5daacaec7c9..206eddd05c11 100644
--- a/drivers/pcmcia/pci_socket.h
+++ b/drivers/pcmcia/pci_socket.h
@@ -37,9 +37,7 @@ struct pci_socket_ops {
int (*get_status)(struct pci_socket *, unsigned int *);
int (*get_socket)(struct pci_socket *, socket_state_t *);
int (*set_socket)(struct pci_socket *, socket_state_t *);
- int (*get_io_map)(struct pci_socket *, struct pccard_io_map *);
int (*set_io_map)(struct pci_socket *, struct pccard_io_map *);
- int (*get_mem_map)(struct pci_socket *, struct pccard_mem_map *);
int (*set_mem_map)(struct pci_socket *, struct pccard_mem_map *);
void (*proc_setup)(struct pci_socket *, struct proc_dir_entry *base);
};
diff --git a/drivers/pcmcia/ricoh.h b/drivers/pcmcia/ricoh.h
index aaf679f1ac70..14573f8d3646 100644
--- a/drivers/pcmcia/ricoh.h
+++ b/drivers/pcmcia/ricoh.h
@@ -170,9 +170,7 @@ static struct pci_socket_ops ricoh_ops = {
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
- yenta_get_io_map,
yenta_set_io_map,
- yenta_get_mem_map,
yenta_set_mem_map,
yenta_proc_setup
};
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index a5736fee388e..01727ab93359 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -60,7 +60,7 @@
#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
INT_MODULE_PARM(probe_mem, 1); /* memory probe? */
-#ifdef CONFIG_ISA
+#ifdef CONFIG_PCMCIA_PROBE
INT_MODULE_PARM(probe_io, 1); /* IO port probe? */
INT_MODULE_PARM(mem_limit, 0x10000);
#endif
@@ -83,7 +83,9 @@ static resource_map_t mem_db = { 0, 0, &mem_db };
/* IO port resource database */
static resource_map_t io_db = { 0, 0, &io_db };
-#ifdef CONFIG_ISA
+static DECLARE_MUTEX(rsrc_sem);
+
+#ifdef CONFIG_PCMCIA_PROBE
typedef struct irq_info_t {
u_int Attributes;
@@ -269,7 +271,7 @@ static int sub_interval(resource_map_t *map, u_long base, u_long num)
======================================================================*/
-#ifdef CONFIG_ISA
+#ifdef CONFIG_PCMCIA_PROBE
static void do_io_probe(ioaddr_t base, ioaddr_t num)
{
@@ -333,15 +335,69 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num)
/*======================================================================
+ This is tricky... when we set up CIS memory, we try to validate
+ the memory window space allocations.
+
+======================================================================*/
+
+/* Validation function for cards with a valid CIS */
+static int cis_readable(socket_info_t *s, u_long base)
+{
+ cisinfo_t info1, info2;
+ int ret;
+ s->cis_mem.sys_start = base;
+ s->cis_mem.sys_stop = base+s->cap.map_size-1;
+ s->cis_virt = ioremap(base, s->cap.map_size);
+ ret = pcmcia_validate_cis(s->clients, &info1);
+ /* invalidate mapping and CIS cache */
+ iounmap(s->cis_virt);
+ s->cis_used = 0;
+ if ((ret != 0) || (info1.Chains == 0))
+ return 0;
+ s->cis_mem.sys_start = base+s->cap.map_size;
+ s->cis_mem.sys_stop = base+2*s->cap.map_size-1;
+ s->cis_virt = ioremap(base+s->cap.map_size, s->cap.map_size);
+ ret = pcmcia_validate_cis(s->clients, &info2);
+ iounmap(s->cis_virt);
+ s->cis_used = 0;
+ return ((ret == 0) && (info1.Chains == info2.Chains));
+}
+
+/* Validation function for simple memory cards */
+static int checksum(socket_info_t *s, u_long base)
+{
+ int i, a, b, d;
+ s->cis_mem.sys_start = base;
+ s->cis_mem.sys_stop = base+s->cap.map_size-1;
+ s->cis_virt = ioremap(base, s->cap.map_size);
+ s->cis_mem.card_start = 0;
+ s->cis_mem.flags = MAP_ACTIVE;
+ s->ss_entry->set_mem_map(s->sock, &s->cis_mem);
+ /* Don't bother checking every word... */
+ a = 0; b = -1;
+ for (i = 0; i < s->cap.map_size; i += 44) {
+ d = readl(s->cis_virt+i);
+ a += d; b &= d;
+ }
+ iounmap(s->cis_virt);
+ return (b == -1) ? -1 : (a>>1);
+}
+
+static int checksum_match(socket_info_t *s, u_long base)
+{
+ int a = checksum(s, base), b = checksum(s, base+s->cap.map_size);
+ return ((a == b) && (a >= 0));
+}
+
+/*======================================================================
+
The memory probe. If the memory list includes a 64K-aligned block
below 1MB, we probe in 64K chunks, and as soon as we accumulate at
least mem_limit free space, we quit.
======================================================================*/
-static int do_mem_probe(u_long base, u_long num,
- int (*is_valid)(u_long), int (*do_cksum)(u_long),
- socket_info_t *s)
+static int do_mem_probe(u_long base, u_long num, socket_info_t *s)
{
u_long i, j, bad, fail, step;
@@ -349,18 +405,21 @@ static int do_mem_probe(u_long base, u_long num,
base, base+num-1);
bad = fail = 0;
step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
+ /* cis_readable wants to map 2x map_size */
+ if (step < 2 * s->cap.map_size)
+ step = 2 * s->cap.map_size;
for (i = j = base; i < base+num; i = j + step) {
if (!fail) {
for (j = i; j < base+num; j += step)
if ((check_mem_resource(j, step, s->cap.cb_dev) == 0) &&
- is_valid(j))
+ cis_readable(s, j))
break;
fail = ((i == base) && (j == base+num));
}
if (fail) {
for (j = i; j < base+num; j += 2*step)
if ((check_mem_resource(j, 2*step, s->cap.cb_dev) == 0) &&
- do_cksum(j) && do_cksum(j+step))
+ checksum_match(s, j) && checksum_match(s, j + step))
break;
}
if (i != j) {
@@ -374,16 +433,14 @@ static int do_mem_probe(u_long base, u_long num,
return (num - bad);
}
-#ifdef CONFIG_ISA
+#ifdef CONFIG_PCMCIA_PROBE
-static u_long inv_probe(int (*is_valid)(u_long),
- int (*do_cksum)(u_long),
- resource_map_t *m, socket_info_t *s)
+static u_long inv_probe(resource_map_t *m, socket_info_t *s)
{
u_long ok;
if (m == &mem_db)
return 0;
- ok = inv_probe(is_valid, do_cksum, m->next, s);
+ ok = inv_probe(m->next, s);
if (ok) {
if (m->base >= 0x100000)
sub_interval(&mem_db, m->base, m->num);
@@ -391,32 +448,36 @@ static u_long inv_probe(int (*is_valid)(u_long),
}
if (m->base < 0x100000)
return 0;
- return do_mem_probe(m->base, m->num, is_valid, do_cksum, s);
+ return do_mem_probe(m->base, m->num, s);
}
-void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
- int force_low, socket_info_t *s)
+void validate_mem(socket_info_t *s)
{
resource_map_t *m, *n;
static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
static int hi = 0, lo = 0;
u_long b, i, ok = 0;
-
- if (!probe_mem) return;
+ int force_low = !(s->cap.features & SS_CAP_PAGE_REGS);
+
+ if (!probe_mem)
+ return;
+
+ down(&rsrc_sem);
/* We do up to four passes through the list */
if (!force_low) {
- if (hi++ || (inv_probe(is_valid, do_cksum, mem_db.next, s) > 0))
- return;
+ if (hi++ || (inv_probe(mem_db.next, s) > 0))
+ goto out;
printk(KERN_NOTICE "cs: warning: no high memory space "
"available!\n");
}
- if (lo++) return;
+ if (lo++)
+ goto out;
for (m = mem_db.next; m != &mem_db; m = n) {
n = m->next;
/* Only probe < 1 MB */
if (m->base >= 0x100000) continue;
if ((m->base | m->num) & 0xffff) {
- ok += do_mem_probe(m->base, m->num, is_valid, do_cksum, s);
+ ok += do_mem_probe(m->base, m->num, s);
continue;
}
/* Special probe for 64K-aligned block */
@@ -426,28 +487,31 @@ void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
if (ok >= mem_limit)
sub_interval(&mem_db, b, 0x10000);
else
- ok += do_mem_probe(b, 0x10000, is_valid, do_cksum, s);
+ ok += do_mem_probe(b, 0x10000, s);
}
}
}
+ out:
+ up(&rsrc_sem);
}
-#else /* CONFIG_ISA */
+#else /* CONFIG_PCMCIA_PROBE */
-void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
- int force_low, socket_info_t *s)
+void validate_mem(socket_info_t *s)
{
resource_map_t *m;
static int done = 0;
- if (!probe_mem || done++)
- return;
- for (m = mem_db.next; m != &mem_db; m = m->next)
- if (do_mem_probe(m->base, m->num, is_valid, do_cksum, s))
- return;
+ if (probe_mem && done++ == 0) {
+ down(&rsrc_sem);
+ for (m = mem_db.next; m != &mem_db; m = m->next)
+ if (do_mem_probe(m->base, m->num, s))
+ break;
+ up(&rsrc_sem);
+ }
}
-#endif /* CONFIG_ISA */
+#endif /* CONFIG_PCMCIA_PROBE */
/*======================================================================
@@ -467,7 +531,9 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
{
ioaddr_t try;
resource_map_t *m;
-
+ int ret = -1;
+
+ down(&rsrc_sem);
for (m = io_db.next; m != &io_db; m = m->next) {
try = (m->base & ~(align-1)) + *base;
for (try = (try >= m->base) ? try : try+align;
@@ -475,12 +541,16 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
try += align) {
if (request_io_resource(try, num, name, s->cap.cb_dev) == 0) {
*base = try;
- return 0;
+ ret = 0;
+ goto out;
}
- if (!align) break;
+ if (!align)
+ break;
}
}
- return -1;
+ out:
+ up(&rsrc_sem);
+ return ret;
}
int find_mem_region(u_long *base, u_long num, u_long align,
@@ -488,26 +558,35 @@ int find_mem_region(u_long *base, u_long num, u_long align,
{
u_long try;
resource_map_t *m;
+ int ret = -1;
+ down(&rsrc_sem);
while (1) {
for (m = mem_db.next; m != &mem_db; m = m->next) {
/* first pass >1MB, second pass <1MB */
- if ((force_low != 0) ^ (m->base < 0x100000)) continue;
+ if ((force_low != 0) ^ (m->base < 0x100000))
+ continue;
+
try = (m->base & ~(align-1)) + *base;
for (try = (try >= m->base) ? try : try+align;
(try >= m->base) && (try+num <= m->base+m->num);
try += align) {
if (request_mem_resource(try, num, name, s->cap.cb_dev) == 0) {
*base = try;
- return 0;
+ ret = 0;
+ goto out;
}
- if (!align) break;
+ if (!align)
+ break;
}
}
- if (force_low) break;
+ if (force_low)
+ break;
force_low++;
}
- return -1;
+ out:
+ up(&rsrc_sem);
+ return ret;
}
/*======================================================================
@@ -518,7 +597,7 @@ int find_mem_region(u_long *base, u_long num, u_long align,
======================================================================*/
-#ifdef CONFIG_ISA
+#ifdef CONFIG_PCMCIA_PROBE
static void fake_irq(int i, void *d, struct pt_regs *r) { }
static inline int check_irq(int irq)
@@ -532,66 +611,89 @@ static inline int check_irq(int irq)
int try_irq(u_int Attributes, int irq, int specific)
{
irq_info_t *info = &irq_table[irq];
+ int ret = 0;
+
+ down(&rsrc_sem);
if (info->Attributes & RES_ALLOCATED) {
switch (Attributes & IRQ_TYPE) {
case IRQ_TYPE_EXCLUSIVE:
- return CS_IN_USE;
+ ret = CS_IN_USE;
+ break;
case IRQ_TYPE_TIME:
if ((info->Attributes & RES_IRQ_TYPE)
- != RES_IRQ_TYPE_TIME)
- return CS_IN_USE;
- if (Attributes & IRQ_FIRST_SHARED)
- return CS_BAD_ATTRIBUTE;
+ != RES_IRQ_TYPE_TIME) {
+ ret = CS_IN_USE;
+ break;
+ }
+ if (Attributes & IRQ_FIRST_SHARED) {
+ ret = CS_BAD_ATTRIBUTE;
+ break;
+ }
info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED;
info->time_share++;
break;
case IRQ_TYPE_DYNAMIC_SHARING:
if ((info->Attributes & RES_IRQ_TYPE)
- != RES_IRQ_TYPE_DYNAMIC)
- return CS_IN_USE;
- if (Attributes & IRQ_FIRST_SHARED)
- return CS_BAD_ATTRIBUTE;
+ != RES_IRQ_TYPE_DYNAMIC) {
+ ret = CS_IN_USE;
+ break;
+ }
+ if (Attributes & IRQ_FIRST_SHARED) {
+ ret = CS_BAD_ATTRIBUTE;
+ break;
+ }
info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED;
info->dyn_share++;
break;
}
} else {
- if ((info->Attributes & RES_RESERVED) && !specific)
- return CS_IN_USE;
- if (check_irq(irq) != 0)
- return CS_IN_USE;
+ if ((info->Attributes & RES_RESERVED) && !specific) {
+ ret = CS_IN_USE;
+ goto out;
+ }
+ if (check_irq(irq) != 0) {
+ ret = CS_IN_USE;
+ goto out;
+ }
switch (Attributes & IRQ_TYPE) {
case IRQ_TYPE_EXCLUSIVE:
info->Attributes |= RES_ALLOCATED;
break;
case IRQ_TYPE_TIME:
- if (!(Attributes & IRQ_FIRST_SHARED))
- return CS_BAD_ATTRIBUTE;
+ if (!(Attributes & IRQ_FIRST_SHARED)) {
+ ret = CS_BAD_ATTRIBUTE;
+ break;
+ }
info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED;
info->time_share = 1;
break;
case IRQ_TYPE_DYNAMIC_SHARING:
- if (!(Attributes & IRQ_FIRST_SHARED))
- return CS_BAD_ATTRIBUTE;
+ if (!(Attributes & IRQ_FIRST_SHARED)) {
+ ret = CS_BAD_ATTRIBUTE;
+ break;
+ }
info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED;
info->dyn_share = 1;
break;
}
}
- return 0;
+ out:
+ up(&rsrc_sem);
+ return ret;
}
#endif
/*====================================================================*/
-#ifdef CONFIG_ISA
+#ifdef CONFIG_PCMCIA_PROBE
void undo_irq(u_int Attributes, int irq)
{
irq_info_t *info;
info = &irq_table[irq];
+ down(&rsrc_sem);
switch (Attributes & IRQ_TYPE) {
case IRQ_TYPE_EXCLUSIVE:
info->Attributes &= RES_RESERVED;
@@ -607,6 +709,7 @@ void undo_irq(u_int Attributes, int irq)
info->Attributes &= RES_RESERVED;
break;
}
+ up(&rsrc_sem);
}
#endif
@@ -629,6 +732,8 @@ static int adjust_memory(adjust_t *adj)
return CS_BAD_SIZE;
ret = CS_SUCCESS;
+
+ down(&rsrc_sem);
switch (adj->Action) {
case ADD_MANAGED_RESOURCE:
ret = add_interval(&mem_db, base, num);
@@ -647,6 +752,7 @@ static int adjust_memory(adjust_t *adj)
default:
ret = CS_UNSUPPORTED_FUNCTION;
}
+ up(&rsrc_sem);
return ret;
}
@@ -655,7 +761,7 @@ static int adjust_memory(adjust_t *adj)
static int adjust_io(adjust_t *adj)
{
- int base, num;
+ int base, num, ret = CS_SUCCESS;
base = adj->resource.io.BasePort;
num = adj->resource.io.NumPorts;
@@ -664,11 +770,14 @@ static int adjust_io(adjust_t *adj)
if ((num <= 0) || (base+num > 0x10000) || (base+num <= base))
return CS_BAD_SIZE;
+ down(&rsrc_sem);
switch (adj->Action) {
case ADD_MANAGED_RESOURCE:
- if (add_interval(&io_db, base, num) != 0)
- return CS_IN_USE;
-#ifdef CONFIG_ISA
+ if (add_interval(&io_db, base, num) != 0) {
+ ret = CS_IN_USE;
+ break;
+ }
+#ifdef CONFIG_PCMCIA_PROBE
if (probe_io)
do_io_probe(base, num);
#endif
@@ -677,18 +786,20 @@ static int adjust_io(adjust_t *adj)
sub_interval(&io_db, base, num);
break;
default:
- return CS_UNSUPPORTED_FUNCTION;
+ ret = CS_UNSUPPORTED_FUNCTION;
break;
}
+ up(&rsrc_sem);
- return CS_SUCCESS;
+ return ret;
}
/*====================================================================*/
static int adjust_irq(adjust_t *adj)
{
-#ifdef CONFIG_ISA
+ int ret = CS_SUCCESS;
+#ifdef CONFIG_PCMCIA_PROBE
int irq;
irq_info_t *info;
@@ -696,33 +807,41 @@ static int adjust_irq(adjust_t *adj)
if ((irq < 0) || (irq > 15))
return CS_BAD_IRQ;
info = &irq_table[irq];
-
+
+ down(&rsrc_sem);
switch (adj->Action) {
case ADD_MANAGED_RESOURCE:
if (info->Attributes & RES_REMOVED)
info->Attributes &= ~(RES_REMOVED|RES_ALLOCATED);
else
- if (adj->Attributes & RES_ALLOCATED)
- return CS_IN_USE;
+ if (adj->Attributes & RES_ALLOCATED) {
+ ret = CS_IN_USE;
+ break;
+ }
if (adj->Attributes & RES_RESERVED)
info->Attributes |= RES_RESERVED;
else
info->Attributes &= ~RES_RESERVED;
break;
case REMOVE_MANAGED_RESOURCE:
- if (info->Attributes & RES_REMOVED)
- return 0;
- if (info->Attributes & RES_ALLOCATED)
- return CS_IN_USE;
+ if (info->Attributes & RES_REMOVED) {
+ ret = 0;
+ break;
+ }
+ if (info->Attributes & RES_ALLOCATED) {
+ ret = CS_IN_USE;
+ break;
+ }
info->Attributes |= RES_ALLOCATED|RES_REMOVED;
info->Attributes &= ~RES_RESERVED;
break;
default:
- return CS_UNSUPPORTED_FUNCTION;
+ ret = CS_UNSUPPORTED_FUNCTION;
break;
}
+ up(&rsrc_sem);
#endif
- return CS_SUCCESS;
+ return ret;
}
/*====================================================================*/
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 3b7bd42aca97..19e23eca7ca6 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -52,7 +52,6 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
-#include <pcmcia/bus_ops.h>
#include <asm/hardware.h>
#include <asm/io.h>
@@ -567,31 +566,6 @@ sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
} /* sa1100_pcmcia_set_socket() */
-/* sa1100_pcmcia_get_io_map()
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^
- * Implements the get_io_map() operation for the in-kernel PCMCIA
- * service (formerly SS_GetIOMap in Card Services). Just returns an
- * I/O map descriptor which was assigned earlier by a set_io_map().
- *
- * Returns: 0 on success, -1 if the map index was out of range
- */
-static int
-sa1100_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
-{
- struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
- int ret = -1;
-
- DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
-
- if (map->map < MAX_IO_WIN) {
- *map = skt->io_map[map->map];
- ret = 0;
- }
-
- return ret;
-}
-
-
/* sa1100_pcmcia_set_io_map()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the set_io_map() operation for the in-kernel PCMCIA
@@ -646,32 +620,6 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
} /* sa1100_pcmcia_set_io_map() */
-/* sa1100_pcmcia_get_mem_map()
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * Implements the get_mem_map() operation for the in-kernel PCMCIA
- * service (formerly SS_GetMemMap in Card Services). Just returns a
- * memory map descriptor which was assigned earlier by a
- * set_mem_map() request.
- *
- * Returns: 0 on success, -1 if the map index was out of range
- */
-static int
-sa1100_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
-{
- struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
- int ret = -1;
-
- DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
-
- if (map->map < MAX_WIN) {
- *map = skt->pc_mem_map[map->map];
- ret = 0;
- }
-
- return ret;
-}
-
-
/* sa1100_pcmcia_set_mem_map()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Implements the set_mem_map() operation for the in-kernel PCMCIA
@@ -841,9 +789,7 @@ static struct pccard_operations sa1100_pcmcia_operations = {
.get_status = sa1100_pcmcia_get_status,
.get_socket = sa1100_pcmcia_get_socket,
.set_socket = sa1100_pcmcia_set_socket,
- .get_io_map = sa1100_pcmcia_get_io_map,
.set_io_map = sa1100_pcmcia_set_io_map,
- .get_mem_map = sa1100_pcmcia_get_mem_map,
.set_mem_map = sa1100_pcmcia_set_mem_map,
#ifdef CONFIG_PROC_FS
.proc_setup = sa1100_pcmcia_proc_setup
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index d537519e4cce..6d701f9710ac 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -806,44 +806,6 @@ static int tcic_set_socket(unsigned int lsock, socket_state_t *state)
/*====================================================================*/
-static int tcic_get_io_map(unsigned int lsock, struct pccard_io_map *io)
-{
- u_short psock = socket_table[lsock].psock;
- u_short base, ioctl;
- u_int addr;
-
- if (io->map > 1) return -EINVAL;
- tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
- addr = TCIC_IWIN(psock, io->map);
- tcic_setw(TCIC_ADDR, addr + TCIC_IBASE_X);
- base = tcic_getw(TCIC_DATA);
- tcic_setw(TCIC_ADDR, addr + TCIC_ICTL_X);
- ioctl = tcic_getw(TCIC_DATA);
-
- if (ioctl & TCIC_ICTL_TINY)
- io->start = io->stop = base;
- else {
- io->start = base & (base-1);
- io->stop = io->start + (base ^ (base-1));
- }
- io->speed = to_ns(ioctl & TCIC_ICTL_WSCNT_MASK);
- io->flags = (ioctl & TCIC_ICTL_ENA) ? MAP_ACTIVE : 0;
- switch (ioctl & TCIC_ICTL_BW_MASK) {
- case TCIC_ICTL_BW_DYN:
- io->flags |= MAP_AUTOSZ; break;
- case TCIC_ICTL_BW_16:
- io->flags |= MAP_16BIT; break;
- default:
- break;
- }
- DEBUG(1, "tcic: GetIOMap(%d, %d) = %#2.2x, %d ns, "
- "%#4.4x-%#4.4x\n", lsock, io->map, io->flags,
- io->speed, io->start, io->stop);
- return 0;
-} /* tcic_get_io_map */
-
-/*====================================================================*/
-
static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io)
{
u_short psock = socket_table[lsock].psock;
@@ -881,51 +843,6 @@ static int tcic_set_io_map(unsigned int lsock, struct pccard_io_map *io)
/*====================================================================*/
-static int tcic_get_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
-{
- u_short psock = socket_table[lsock].psock;
- u_short addr, ctl;
- u_long base, mmap;
-
- if (mem->map > 3) return -EINVAL;
- tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
- addr = TCIC_MWIN(psock, mem->map);
-
- tcic_setw(TCIC_ADDR, addr + TCIC_MBASE_X);
- base = tcic_getw(TCIC_DATA);
- if (base & TCIC_MBASE_4K_BIT) {
- mem->sys_start = base & TCIC_MBASE_HA_MASK;
- mem->sys_stop = mem->sys_start;
- } else {
- base &= TCIC_MBASE_HA_MASK;
- mem->sys_start = (base & (base-1));
- mem->sys_stop = mem->sys_start + (base ^ (base-1));
- }
- mem->sys_start = mem->sys_start << TCIC_MBASE_HA_SHFT;
- mem->sys_stop = (mem->sys_stop << TCIC_MBASE_HA_SHFT) + 0x0fff;
-
- tcic_setw(TCIC_ADDR, addr + TCIC_MMAP_X);
- mmap = tcic_getw(TCIC_DATA);
- mem->flags = (mmap & TCIC_MMAP_REG) ? MAP_ATTRIB : 0;
- mmap &= TCIC_MMAP_CA_MASK;
- mem->card_start = mem->sys_start + (mmap << TCIC_MMAP_CA_SHFT);
- mem->card_start &= 0x3ffffff;
-
- tcic_setw(TCIC_ADDR, addr + TCIC_MCTL_X);
- ctl = tcic_getw(TCIC_DATA);
- mem->flags |= (ctl & TCIC_MCTL_ENA) ? MAP_ACTIVE : 0;
- mem->flags |= (ctl & TCIC_MCTL_B8) ? 0 : MAP_16BIT;
- mem->flags |= (ctl & TCIC_MCTL_WP) ? MAP_WRPROT : 0;
- mem->speed = to_ns(ctl & TCIC_MCTL_WSCNT_MASK);
-
- DEBUG(1, "tcic: GetMemMap(%d, %d) = %#2.2x, %d ns, "
- "%#5.5lx-%#5.5lx, %#5.5x\n", lsock, mem->map, mem->flags,
- mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
- return 0;
-} /* tcic_get_mem_map */
-
-/*====================================================================*/
-
static int tcic_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
{
u_short psock = socket_table[lsock].psock;
@@ -1007,9 +924,7 @@ static struct pccard_operations tcic_operations = {
.get_status = tcic_get_status,
.get_socket = tcic_get_socket,
.set_socket = tcic_set_socket,
- .get_io_map = tcic_get_io_map,
.set_io_map = tcic_set_io_map,
- .get_mem_map = tcic_get_mem_map,
.set_mem_map = tcic_set_mem_map,
.proc_setup = tcic_proc_setup,
};
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index 8b1f6a02ef2d..353cc02b8181 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -185,9 +185,7 @@ static struct pci_socket_ops ti_ops = {
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
- yenta_get_io_map,
yenta_set_io_map,
- yenta_get_mem_map,
yenta_set_mem_map,
yenta_proc_setup
};
@@ -230,9 +228,7 @@ static struct pci_socket_ops ti113x_ops = {
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
- yenta_get_io_map,
yenta_set_io_map,
- yenta_get_mem_map,
yenta_set_mem_map,
yenta_proc_setup
};
@@ -272,9 +268,7 @@ static struct pci_socket_ops ti1250_ops = {
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
- yenta_get_io_map,
yenta_set_io_map,
- yenta_get_mem_map,
yenta_set_mem_map,
yenta_proc_setup
};
diff --git a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c
index bf6c913752d0..4bb9cc7257ba 100644
--- a/drivers/pcmcia/yenta.c
+++ b/drivers/pcmcia/yenta.c
@@ -27,7 +27,7 @@
#include "i82365.h"
#if 0
-#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args)
+#define DEBUG(x,args...) printk("%s: " x, __FUNCTION__, ##args)
#else
#define DEBUG(x,args...)
#endif
@@ -300,29 +300,6 @@ static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state)
return 0;
}
-static int yenta_get_io_map(pci_socket_t *socket, struct pccard_io_map *io)
-{
- int map;
- unsigned char ioctl, addr;
-
- map = io->map;
- if (map > 1)
- return -EINVAL;
-
- io->start = exca_readw(socket, I365_IO(map)+I365_W_START);
- io->stop = exca_readw(socket, I365_IO(map)+I365_W_STOP);
-
- ioctl = exca_readb(socket, I365_IOCTL);
- addr = exca_readb(socket, I365_ADDRWIN);
- io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0;
- io->flags = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0;
- io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;
- io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;
- io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;
-
- return 0;
-}
-
static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io)
{
int map;
@@ -356,41 +333,6 @@ static int yenta_set_io_map(pci_socket_t *socket, struct pccard_io_map *io)
return 0;
}
-static int yenta_get_mem_map(pci_socket_t *socket, struct pccard_mem_map *mem)
-{
- int map;
- unsigned char addr;
- unsigned int start, stop, page, offset;
-
- map = mem->map;
- if (map > 4)
- return -EINVAL;
-
- addr = exca_readb(socket, I365_ADDRWIN);
- mem->flags = (addr & I365_ENA_MEM(map)) ? MAP_ACTIVE : 0;
-
- start = exca_readw(socket, I365_MEM(map) + I365_W_START);
- mem->flags |= (start & I365_MEM_16BIT) ? MAP_16BIT : 0;
- mem->flags |= (start & I365_MEM_0WS) ? MAP_0WS : 0;
- start = (start & 0x0fff) << 12;
-
- stop = exca_readw(socket, I365_MEM(map) + I365_W_STOP);
- mem->speed = to_ns(stop >> 14);
- stop = ((stop & 0x0fff) << 12) + 0x0fff;
-
- offset = exca_readw(socket, I365_MEM(map) + I365_W_OFF);
- mem->flags |= (offset & I365_MEM_WRPROT) ? MAP_WRPROT : 0;
- mem->flags |= (offset & I365_MEM_REG) ? MAP_ATTRIB : 0;
- offset = ((offset & 0x3fff) << 12) + start;
- mem->card_start = offset & 0x3ffffff;
-
- page = exca_readb(socket, CB_MEM_PAGE(map)) << 24;
- mem->sys_start = start + page;
- mem->sys_stop = start + page;
-
- return 0;
-}
-
static int yenta_set_mem_map(pci_socket_t *socket, struct pccard_mem_map *mem)
{
int map;
@@ -572,7 +514,6 @@ static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask
socket->cap.pci_irq = socket->cb_irq;
socket->cap.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
socket->cap.cb_dev = socket->dev;
- socket->cap.bus = NULL;
printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq);
}
@@ -935,9 +876,7 @@ struct pci_socket_ops yenta_operations = {
yenta_get_status,
yenta_get_socket,
yenta_set_socket,
- yenta_get_io_map,
yenta_set_io_map,
- yenta_get_mem_map,
yenta_set_mem_map,
yenta_proc_setup
};
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 50e9a2f24389..523a0b54769e 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -62,7 +62,6 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <pcmcia/bus_ops.h>
#include "nsp_cs.h"
@@ -93,7 +92,6 @@ typedef struct scsi_info_t {
int ndev;
dev_node_t node[8];
int stop;
- struct bus_operations *bus;
} scsi_info_t;
@@ -1948,7 +1946,6 @@ static int nsp_cs_event(event_t event,
case CS_EVENT_CARD_INSERTION:
DEBUG(0, " event: insert\n");
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- info->bus = args->bus;
nsp_cs_config(link);
break;
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 0231b65954e3..5d2c2121535e 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_SL811HS) += host/
obj-$(CONFIG_USB_ACM) += class/
obj-$(CONFIG_USB_AUDIO) += class/
obj-$(CONFIG_USB_BLUETOOTH_TTY) += class/
+obj-$(CONFIG_USB_MIDI) += class/
obj-$(CONFIG_USB_PRINTER) += class/
obj-$(CONFIG_USB_STORAGE) += storage/
diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
index b8803ce7301f..7e21997bf9bf 100644
--- a/drivers/usb/class/audio.c
+++ b/drivers/usb/class/audio.c
@@ -172,7 +172,6 @@
/*****************************************************************************/
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 7a6b3d0204e8..99233f6f06ef 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -538,7 +538,7 @@ static int acm_probe (struct usb_interface *intf,
cfacm = dev->config + i;
- dbg("probing config %d", cfacm->bConfigurationValue);
+ dbg("probing config %d", cfacm->desc.bConfigurationValue);
if (cfacm->desc.bNumInterfaces != 2 ||
usb_interface_claimed(cfacm->interface + 0) ||
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 6e4392596750..e88cda590a31 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -7,7 +7,6 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pci.h>
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index ef25a85a939a..8ad8c112c1c0 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1024,9 +1024,7 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
*/
urb->transfer_flags |= URB_NO_DMA_MAP;
status = rh_urb_enqueue (hcd, urb);
- if (status)
- urb_unlink (urb);
- return status;
+ goto done;
}
/* lower level hcd code should use *_dma exclusively,
@@ -1051,8 +1049,11 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
}
status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
- if (status)
+done:
+ if (status) {
+ usb_put_urb (urb);
urb_unlink (urb);
+ }
return status;
}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 03696016c495..fc8c00c3b432 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -135,8 +135,7 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
default: /* presumably an error */
/* Cause a hub reset after 10 consecutive errors */
- dbg("hub '%s' status %d for interrupt transfer",
- urb->dev->devpath, urb->status);
+ dev_dbg (&hub->intf->dev, "transfer --> %d\n", urb->status);
if ((++hub->nerrors < 10) || hub->error)
goto resubmit;
hub->error = urb->status;
@@ -158,10 +157,10 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
spin_unlock_irqrestore(&hub_event_lock, flags);
resubmit:
- if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0)
- err ("hub '%s-%s' status %d for interrupt resubmit",
- urb->dev->bus->bus_name, urb->dev->devpath,
- status);
+ if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0
+ /* ENODEV means we raced disconnect() */
+ && status != -ENODEV)
+ dev_err (&hub->intf->dev, "resubmit --> %d\n", urb->status);
}
/* USB 2.0 spec Section 11.24.2.3 */
@@ -648,12 +647,13 @@ static int usb_hub_port_status(struct usb_device *hub, int port,
struct usb_port_status *portsts;
int ret = -ENOMEM;
- portsts = kmalloc(sizeof(*portsts), GFP_KERNEL);
+ portsts = kmalloc(sizeof(*portsts), GFP_NOIO);
if (portsts) {
ret = usb_get_port_status(hub, port + 1, portsts);
if (ret < 0)
- err("%s(%s-%s) failed (err = %d)", __FUNCTION__,
- hub->bus->bus_name, hub->devpath, ret);
+ dev_err (hubdev (hub),
+ "%s failed (err = %d)\n", __FUNCTION__,
+ ret);
else {
*status = le16_to_cpu(portsts->wPortStatus);
*change = le16_to_cpu(portsts->wPortChange);
@@ -759,8 +759,8 @@ void usb_hub_port_disable(struct usb_device *hub, int port)
ret = usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_ENABLE);
if (ret)
- err("cannot disable port %d of hub %s (err = %d)",
- port + 1, hub->devpath, ret);
+ dev_err(hubdev(hub), "cannot disable port %d (err = %d)\n",
+ port + 1, ret);
}
/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
@@ -983,12 +983,12 @@ static void usb_hub_events(void)
spin_unlock_irqrestore(&hub_event_lock, flags);
if (hub->error) {
- dbg("resetting hub %s for error %d",
- dev->devpath, hub->error);
+ dev_dbg (&hub->intf->dev, "resetting for error %d\n",
+ hub->error);
if (usb_hub_reset(hub)) {
- err("error resetting hub %s - disconnecting",
- dev->devpath);
+ dev_dbg (&hub->intf->dev,
+ "can't reset; disconnecting\n");
up(&hub->khubd_sem);
usb_hub_disconnect(dev);
continue;
@@ -1022,33 +1022,37 @@ static void usb_hub_events(void)
if (!(portstatus & USB_PORT_STAT_ENABLE)
&& (portstatus & USB_PORT_STAT_CONNECTION)
&& (dev->children[i])) {
- err("already running hub %s port %i "
+ dev_err (&hub->intf->dev,
+ "port %i "
"disabled by hub (EMI?), "
"re-enabling...",
- dev->devpath, i + 1);
+ i + 1);
usb_hub_port_connect_change(hub,
i, portstatus, portchange);
}
}
if (portchange & USB_PORT_STAT_C_SUSPEND) {
- dbg("hub %s port %d suspend change",
- dev->devpath, i + 1);
+ dev_dbg (&hub->intf->dev,
+ "suspend change on port %d\n",
+ i + 1);
usb_clear_port_feature(dev,
i + 1, USB_PORT_FEAT_C_SUSPEND);
}
if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
- err("hub %s port %d over-current change",
- dev->devpath, i + 1);
+ dev_err (&hub->intf->dev,
+ "over-current change on port %d\n",
+ i + 1);
usb_clear_port_feature(dev,
i + 1, USB_PORT_FEAT_C_OVER_CURRENT);
usb_hub_power_on(hub);
}
if (portchange & USB_PORT_STAT_C_RESET) {
- dbg("hub %s port %d reset change",
- dev->devpath, i + 1);
+ dev_dbg (&hub->intf->dev,
+ "reset change on port %d\n",
+ i + 1);
usb_clear_port_feature(dev,
i + 1, USB_PORT_FEAT_C_RESET);
}
@@ -1056,16 +1060,16 @@ static void usb_hub_events(void)
/* deal with hub status changes */
if (usb_get_hub_status(dev, &hubsts) < 0)
- err("get_hub_status %s failed", dev->devpath);
+ dev_err (&hub->intf->dev, "get_hub_status failed\n");
else {
hubstatus = le16_to_cpup(&hubsts.wHubStatus);
hubchange = le16_to_cpup(&hubsts.wHubChange);
if (hubchange & HUB_CHANGE_LOCAL_POWER) {
- dbg("hub %s power change", dev->devpath);
+ dev_dbg (&hub->intf->dev, "power change\n");
usb_clear_hub_feature(dev, C_HUB_LOCAL_POWER);
}
if (hubchange & HUB_CHANGE_OVERCURRENT) {
- dbg("hub %s overcurrent change", dev->devpath);
+ dev_dbg (&hub->intf->dev, "overcurrent change\n");
wait_ms(500); /* Cool down */
usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
usb_hub_power_on(hub);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 793a82b23ac2..f0d1fdad80c0 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
+#include <linux/mm.h>
#include <asm/byteorder.h>
#include "hcd.h" /* for usbcore internals */
diff --git a/drivers/usb/core/usb-debug.c b/drivers/usb/core/usb-debug.c
index ea5d4f766bb6..91bea396940f 100644
--- a/drivers/usb/core/usb-debug.c
+++ b/drivers/usb/core/usb-debug.c
@@ -5,7 +5,6 @@
* face, but so that you can still use them..
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index b87e7aaaf14d..a3b3c32b3a6a 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -866,14 +866,11 @@ void usb_disconnect(struct usb_device **pdev)
}
/**
- * usb_connect - connects a new device during enumeration (usbcore-internal)
- * @dev: partially enumerated device
- *
- * Connect a new USB device. This basically just initializes
- * the USB device information and sets up the topology - it's
- * up to the low-level driver to reset the port and actually
- * do the setup (the upper levels don't know how to do that).
+ * usb_connect - pick device address (usbcore-internal)
+ * @dev: newly detected device (in DEFAULT state)
*
+ * Picks a device address. It's up to the hub (or root hub) driver
+ * to handle and manage enumeration, starting from the DEFAULT state.
* Only hub drivers (including virtual root hub drivers for host
* controllers) should ever call this.
*/
@@ -983,7 +980,7 @@ static void set_device_description (struct usb_device *dev)
}
/*
- * By the time we get here, the device has gotten a new device ID
+ * By the time we get here, we chose a new device address
* and is in the default state. We need to identify the thing and
* get the ball rolling..
*
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5c148c778e9c..798d2e0e1c50 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -94,7 +94,6 @@
#include <linux/list.h>
#include <linux/interrupt.h> /* for in_interrupt () */
#include <linux/usb.h>
-#include <linux/version.h>
#include "../core/hcd.h"
#include <asm/io.h>
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index 602b597cedab..faf9c3b51b70 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -85,7 +85,6 @@
* (20/10/1999)
*/
-#include <linux/version.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/spinlock.h>
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
index 3f2305bf964b..7f456725a6b4 100644
--- a/drivers/usb/media/ov511.c
+++ b/drivers/usb/media/ov511.c
@@ -36,7 +36,6 @@
*/
#include <linux/config.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
index 1b5df6990a4c..f8113626df13 100644
--- a/drivers/usb/media/stv680.c
+++ b/drivers/usb/media/stv680.c
@@ -60,7 +60,6 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c
index 02e22f53b45b..93a3b241c908 100644
--- a/drivers/usb/misc/emi26.c
+++ b/drivers/usb/misc/emi26.c
@@ -78,19 +78,28 @@ static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit)
return response;
}
+#define FW_LOAD_SIZE 1023
+
static int emi26_load_firmware (struct usb_device *dev)
{
int err;
int i;
int pos = 0; /* Position in hex record */
__u32 addr; /* Address to write */
- __u8 buf[1023];
+ __u8 *buf;
+
+ buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
+ if (!buf) {
+ err( "%s - error loading firmware: error = %d", __FUNCTION__, -ENOMEM);
+ err = -ENOMEM;
+ goto wraperr;
+ }
/* Assert reset (stop the CPU in the EMI) */
err = emi26_set_reset(dev,1);
if (err < 0) {
err( "%s - error loading firmware: error = %d", __FUNCTION__, err);
- return err;
+ goto wraperr;
}
/* 1. We need to put the loader for the FPGA into the EZ-USB */
@@ -98,7 +107,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
- return err;
+ goto wraperr;
}
}
@@ -113,7 +122,7 @@ static int emi26_load_firmware (struct usb_device *dev)
addr = g_bitstream[pos].address;
/* intel hex records are terminated with type 0 element */
- while ((g_bitstream[pos].type == 0) && (i + g_bitstream[pos].length < sizeof(buf))) {
+ while ((g_bitstream[pos].type == 0) && (i + g_bitstream[pos].length < FW_LOAD_SIZE)) {
memcpy(buf + i, g_bitstream[pos].data, g_bitstream[pos].length);
i += g_bitstream[pos].length;
pos++;
@@ -121,7 +130,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
- return err;
+ goto wraperr;
}
} while (i > 0);
@@ -129,7 +138,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_set_reset(dev,1);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
- return err;
+ goto wraperr;
}
/* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
@@ -137,7 +146,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
- return err;
+ goto wraperr;
}
}
@@ -145,7 +154,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
- return err;
+ goto wraperr;
}
/* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
@@ -154,7 +163,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_EXTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
- return err;
+ goto wraperr;
}
}
}
@@ -163,7 +172,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_set_reset(dev,1);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
- return err;
+ goto wraperr;
}
for (i=0; g_Firmware[i].type == 0; i++) {
@@ -171,7 +180,7 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_INTERNAL);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
- return err;
+ goto wraperr;
}
}
}
@@ -180,12 +189,16 @@ static int emi26_load_firmware (struct usb_device *dev)
err = emi26_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
- return err;
+ goto wraperr;
}
/* return 1 to fail the driver inialization
* and give real driver change to load */
return 1;
+
+wraperr:
+ kfree(buf);
+ return err;
}
static __devinitdata struct usb_device_id id_table [] = {
diff --git a/drivers/usb/misc/speedtch.c b/drivers/usb/misc/speedtch.c
index d2006a09c36e..7ee2a0168392 100644
--- a/drivers/usb/misc/speedtch.c
+++ b/drivers/usb/misc/speedtch.c
@@ -148,27 +148,15 @@ struct udsl_control {
#define UDSL_SKB(x) ((struct udsl_control *)(x)->cb)
-struct atmsar_vcc_data {
- struct atmsar_vcc_data *next;
-
- /* general atmsar flags, per connection */
- int flags;
- int type;
-
- /* connection specific non-atmsar data */
+struct udsl_vcc_data {
+ /* vpi/vci lookup */
+ struct list_head list;
+ short vpi;
+ int vci;
struct atm_vcc *vcc;
- struct k_atm_aal_stats *stats;
- unsigned short mtu; /* max is actually 65k for AAL5... */
-
- /* cell data */
- unsigned int vp;
- unsigned int vc;
- unsigned char gfc;
- unsigned char pti;
- unsigned int headerFlags;
- unsigned long atmHeader;
/* raw cell reassembly */
+ unsigned short mtu;
struct sk_buff *reasBuffer;
};
@@ -186,7 +174,7 @@ struct udsl_instance_data {
/* atm device part */
struct atm_dev *atm_dev;
- struct atmsar_vcc_data *atmsar_vcc_list;
+ struct list_head vcc_list;
/* receiving */
struct udsl_receiver all_receivers [UDSL_NUMBER_RCV_URBS];
@@ -258,73 +246,46 @@ static struct usb_driver udsl_usb_driver = {
** decode **
*************/
-#define ATM_HDR_VPVC_MASK (ATM_HDR_VPI_MASK | ATM_HDR_VCI_MASK)
-#define ATMSAR_USE_53BYTE_CELL 0x1L
+static inline struct udsl_vcc_data *udsl_find_vcc (struct udsl_instance_data *instance, short vpi, int vci)
+{
+ struct udsl_vcc_data *vcc;
+
+ list_for_each_entry (vcc, &instance->vcc_list, list)
+ if ((vcc->vpi == vpi) && (vcc->vci == vci))
+ return vcc;
+ return NULL;
+}
-struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_buff *skb,
- struct atmsar_vcc_data **ctx)
+static struct sk_buff *udsl_decode_rawcell (struct udsl_instance_data *instance, struct sk_buff *skb, struct udsl_vcc_data **ctx)
{
+ if (!instance || !skb || !ctx)
+ return NULL;
+ if (!skb->data || !skb->tail)
+ return NULL;
+
while (skb->len) {
unsigned char *cell = skb->data;
unsigned char *cell_payload;
- struct atmsar_vcc_data *vcc = list;
- unsigned long atmHeader =
- ((unsigned long) (cell[0]) << 24) | ((unsigned long) (cell[1]) << 16) |
- ((unsigned long) (cell[2]) << 8) | (cell[3] & 0xff);
+ struct udsl_vcc_data *vcc;
+ short vpi;
+ int vci;
- dbg ("atmsar_decode_rawcell (0x%p, 0x%p, 0x%p) called", list, skb, ctx);
- dbg ("atmsar_decode_rawcell skb->data %p, skb->tail %p", skb->data, skb->tail);
+ vpi = ((cell[0] & 0x0f) << 4) | (cell[1] >> 4);
+ vci = ((cell[1] & 0x0f) << 12) | (cell[2] << 4) | (cell[3] >> 4);
- if (!list || !skb || !ctx)
- return NULL;
- if (!skb->data || !skb->tail)
- return NULL;
+ dbg ("udsl_decode_rawcell (0x%p, 0x%p, 0x%p) called", instance, skb, ctx);
+ dbg ("udsl_decode_rawcell skb->data %p, skb->tail %p", skb->data, skb->tail);
/* here should the header CRC check be... */
- /* look up correct vcc */
- for (;
- vcc
- && ((vcc->atmHeader & ATM_HDR_VPVC_MASK) != (atmHeader & ATM_HDR_VPVC_MASK));
- vcc = vcc->next);
-
- dbg ("atmsar_decode_rawcell found vcc %p for packet on vp %d, vc %d", vcc,
- (int) ((atmHeader & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT),
- (int) ((atmHeader & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT));
+ if (!(vcc = udsl_find_vcc (instance, vpi, vci)))
+ dbg ("udsl_decode_rawcell: no vcc found for packet on vpi %d, vci %d", vpi, vci);
+ else {
+ dbg ("udsl_decode_rawcell found vcc %p for packet on vpi %d, vci %d", vcc, vpi, vci);
- if (vcc && (skb->len >= (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52))) {
- cell_payload = cell + (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 5 : 4);
+ if (skb->len >= 53) {
+ cell_payload = cell + 5;
- switch (vcc->type) {
- case ATM_AAL0:
- /* case ATM_AAL1: when we have a decode AAL1 function... */
- {
- struct sk_buff *tmp = dev_alloc_skb (vcc->mtu);
-
- if (tmp) {
- memcpy (tmp->tail, cell_payload, 48);
- skb_put (tmp, 48);
-
- if (vcc->stats)
- atomic_inc (&vcc->stats->rx);
-
- skb_pull (skb,
- (vcc->
- flags & ATMSAR_USE_53BYTE_CELL ? 53 :
- 52));
- dbg
- ("atmsar_decode_rawcell returns ATM_AAL0 pdu 0x%p with length %d",
- tmp, tmp->len);
- return tmp;
- };
- }
- break;
- case ATM_AAL1:
- case ATM_AAL2:
- case ATM_AAL34:
- /* not supported */
- break;
- case ATM_AAL5:
if (!vcc->reasBuffer)
vcc->reasBuffer = dev_alloc_skb (vcc->mtu);
@@ -347,43 +308,36 @@ struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_b
/* the aal5 buffer ends here, cut the buffer. */
/* buffer will always have at least one whole cell, so */
/* don't need to check return from skb_pull */
- skb_pull (skb,
- (vcc->
- flags & ATMSAR_USE_53BYTE_CELL ? 53 :
- 52));
+ skb_pull (skb, 53);
*ctx = vcc;
tmp = vcc->reasBuffer;
vcc->reasBuffer = NULL;
- dbg
- ("atmsar_decode_rawcell returns ATM_AAL5 pdu 0x%p with length %d",
- tmp, tmp->len);
+ dbg ("udsl_decode_rawcell returns ATM_AAL5 pdu 0x%p with length %d", tmp, tmp->len);
return tmp;
}
}
- break;
- };
- /* flush the cell */
- /* buffer will always contain at least one whole cell, so don't */
- /* need to check return value from skb_pull */
- skb_pull (skb, (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52));
- } else {
- /* If data is corrupt and skb doesn't hold a whole cell, flush the lot */
- if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) ==
- NULL)
- return NULL;
+ /* flush the cell */
+ /* buffer will always contain at least one whole cell, so don't */
+ /* need to check return value from skb_pull */
+ skb_pull (skb, 53);
+ } else {
+ /* If data is corrupt and skb doesn't hold a whole cell, flush the lot */
+ if (skb_pull (skb, 53) == NULL)
+ return NULL;
+ }
}
}
return NULL;
-};
+}
-struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb)
+static struct sk_buff *udsl_decode_aal5 (struct udsl_vcc_data *ctx, struct sk_buff *skb)
{
uint crc = 0xffffffff;
uint length, pdu_crc, pdu_length;
- dbg ("atmsar_decode_aal5 (0x%p, 0x%p) called", ctx, skb);
+ dbg ("udsl_decode_aal5 (0x%p, 0x%p) called", ctx, skb);
if (skb->len && (skb->len % 48))
return NULL;
@@ -393,20 +347,18 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff
(skb->tail[-4] << 24) + (skb->tail[-3] << 16) + (skb->tail[-2] << 8) + skb->tail[-1];
pdu_length = ((length + 47 + 8) / 48) * 48;
- dbg ("atmsar_decode_aal5: skb->len = %d, length = %d, pdu_crc = 0x%x, pdu_length = %d",
- skb->len, length, pdu_crc, pdu_length);
+ dbg ("udsl_decode_aal5: skb->len = %d, length = %d, pdu_crc = 0x%x, pdu_length = %d", skb->len, length, pdu_crc, pdu_length);
/* is skb long enough ? */
if (skb->len < pdu_length) {
- if (ctx->stats)
- atomic_inc (&ctx->stats->rx_err);
+ if (ctx->vcc->stats)
+ atomic_inc (&ctx->vcc->stats->rx_err);
return NULL;
}
/* is skb too long ? */
if (skb->len > pdu_length) {
- dbg ("atmsar_decode_aal5: Warning: readjusting illeagl size %d -> %d",
- skb->len, pdu_length);
+ dbg ("udsl_decode_aal5: Warning: readjusting illegal size %d -> %d", skb->len, pdu_length);
/* buffer is too long. we can try to recover
* if we discard the first part of the skb.
* the crc will decide whether this was ok
@@ -418,9 +370,9 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff
/* check crc */
if (pdu_crc != crc) {
- dbg ("atmsar_decode_aal5: crc check failed!");
- if (ctx->stats)
- atomic_inc (&ctx->stats->rx_err);
+ dbg ("udsl_decode_aal5: crc check failed!");
+ if (ctx->vcc->stats)
+ atomic_inc (&ctx->vcc->stats->rx_err);
return NULL;
}
@@ -428,19 +380,20 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff
skb_trim (skb, length);
/* update stats */
- if (ctx->stats)
- atomic_inc (&ctx->stats->rx);
+ if (ctx->vcc->stats)
+ atomic_inc (&ctx->vcc->stats->rx);
- dbg ("atmsar_decode_aal5 returns pdu 0x%p with length %d", skb, skb->len);
+ dbg ("udsl_decode_aal5 returns pdu 0x%p with length %d", skb, skb->len);
return skb;
-};
+}
/*************
** encode **
*************/
-static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb) {
+static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb)
+{
struct udsl_control *ctrl = UDSL_SKB (skb);
unsigned int i, zero_padding;
unsigned char zero = 0;
@@ -480,7 +433,8 @@ static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb) {
ctrl->aal5_trailer [7] = crc;
}
-unsigned int udsl_write_cells (unsigned int howmany, struct sk_buff *skb, unsigned char **target_p) {
+static unsigned int udsl_write_cells (unsigned int howmany, struct sk_buff *skb, unsigned char **target_p)
+{
struct udsl_control *ctrl = UDSL_SKB (skb);
unsigned char *target = *target_p;
unsigned int nc, ne, i;
@@ -569,7 +523,7 @@ static void udsl_process_receive (unsigned long data)
unsigned char *data_start;
struct sk_buff *skb;
struct urb *urb;
- struct atmsar_vcc_data *atmsar_vcc = NULL;
+ struct udsl_vcc_data *atmsar_vcc = NULL;
struct sk_buff *new = NULL, *tmp = NULL;
int err;
@@ -597,40 +551,28 @@ static void udsl_process_receive (unsigned long data)
dbg ("skb->len = %d", skb->len);
PACKETDEBUG (skb->data, skb->len);
- while ((new =
- atmsar_decode_rawcell (instance->atmsar_vcc_list, skb,
- &atmsar_vcc)) != NULL) {
+ while ((new = udsl_decode_rawcell (instance, skb, &atmsar_vcc))) {
dbg ("(after cell processing)skb->len = %d", new->len);
- switch (atmsar_vcc->type) {
- case ATM_AAL5:
- tmp = new;
- new = atmsar_decode_aal5 (atmsar_vcc, new);
-
- /* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */
- if (new) {
- dbg ("(after aal5 decap) skb->len = %d", new->len);
- if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) {
- PACKETDEBUG (new->data, new->len);
- atmsar_vcc->vcc->push (atmsar_vcc->vcc, new);
- } else {
- dbg
- ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d",
- atomic_read (&atmsar_vcc->vcc->rx_inuse),
- atmsar_vcc->vcc->sk->rcvbuf, new->truesize);
- dev_kfree_skb (new);
- }
+ tmp = new;
+ new = udsl_decode_aal5 (atmsar_vcc, new);
+
+ /* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */
+ if (new) {
+ dbg ("(after aal5 decap) skb->len = %d", new->len);
+ if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) {
+ PACKETDEBUG (new->data, new->len);
+ atmsar_vcc->vcc->push (atmsar_vcc->vcc, new);
} else {
- dbg ("atmsar_decode_aal5 returned NULL!");
- dev_kfree_skb (tmp);
+ dbg
+ ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d",
+ atomic_read (&atmsar_vcc->vcc->rx_inuse),
+ atmsar_vcc->vcc->sk->rcvbuf, new->truesize);
+ dev_kfree_skb (new);
}
- break;
- default:
- /* not supported. we delete the skb. */
- printk (KERN_INFO
- "SpeedTouch USB: illegal vcc type. Dropping packet.\n");
- dev_kfree_skb (new);
- break;
+ } else {
+ dbg ("udsl_decode_aal5 returned NULL!");
+ dev_kfree_skb (tmp);
}
}
@@ -901,95 +843,6 @@ static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
** ATM **
**********/
-#define ATMSAR_DEF_MTU_AAL0 48
-#define ATMSAR_DEF_MTU_AAL1 47
-#define ATMSAR_DEF_MTU_AAL2 0 /* not supported */
-#define ATMSAR_DEF_MTU_AAL34 0 /* not supported */
-#define ATMSAR_DEF_MTU_AAL5 65535 /* max mtu .. */
-
-struct atmsar_vcc_data *atmsar_open (struct atmsar_vcc_data **list, struct atm_vcc *vcc, uint type,
- ushort vpi, ushort vci, unchar pti, unchar gfc, uint flags)
-{
- struct atmsar_vcc_data *new;
-
- if (!vcc)
- return NULL;
-
- new = kmalloc (sizeof (struct atmsar_vcc_data), GFP_KERNEL);
-
- if (!new)
- return NULL;
-
- memset (new, 0, sizeof (struct atmsar_vcc_data));
- new->vcc = vcc;
- new->stats = vcc->stats;
- new->type = type;
- new->next = NULL;
- new->gfc = gfc;
- new->vp = vpi;
- new->vc = vci;
- new->pti = pti;
-
- switch (type) {
- case ATM_AAL0:
- new->mtu = ATMSAR_DEF_MTU_AAL0;
- break;
- case ATM_AAL1:
- new->mtu = ATMSAR_DEF_MTU_AAL1;
- break;
- case ATM_AAL2:
- new->mtu = ATMSAR_DEF_MTU_AAL2;
- break;
- case ATM_AAL34:
- /* not supported */
- new->mtu = ATMSAR_DEF_MTU_AAL34;
- break;
- case ATM_AAL5:
- new->mtu = ATMSAR_DEF_MTU_AAL5;
- break;
- }
-
- new->atmHeader = ((unsigned long) gfc << ATM_HDR_GFC_SHIFT)
- | ((unsigned long) vpi << ATM_HDR_VPI_SHIFT)
- | ((unsigned long) vci << ATM_HDR_VCI_SHIFT)
- | ((unsigned long) pti << ATM_HDR_PTI_SHIFT);
- new->flags = flags;
- new->next = NULL;
- new->reasBuffer = NULL;
-
- new->next = *list;
- *list = new;
-
- dbg ("Allocated new SARLib vcc 0x%p with vp %d vc %d", new, vpi, vci);
-
- return new;
-}
-
-void atmsar_close (struct atmsar_vcc_data **list, struct atmsar_vcc_data *vcc)
-{
- struct atmsar_vcc_data *work;
-
- if (*list == vcc) {
- *list = (*list)->next;
- } else {
- for (work = *list; work && work->next && (work->next != vcc); work = work->next);
-
- /* return if not found */
- if (work->next != vcc)
- return;
-
- work->next = work->next->next;
- }
-
- if (vcc->reasBuffer) {
- dev_kfree_skb (vcc->reasBuffer);
- }
-
- dbg ("Allocated SARLib vcc 0x%p with vp %d vc %d", vcc, vcc->vp, vcc->vc);
-
- kfree (vcc);
-}
-
static void udsl_atm_dev_close (struct atm_dev *dev)
{
struct udsl_instance_data *instance = dev->dev_data;
@@ -1061,11 +914,10 @@ static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page)
return 0;
}
-#define ATMSAR_SET_PTI 0x2L
-
static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
{
struct udsl_instance_data *instance = vcc->dev->dev_data;
+ struct udsl_vcc_data *new;
dbg ("udsl_atm_open called");
@@ -1074,63 +926,97 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
return -ENODEV;
}
- /* at the moment only AAL5 support */
+ if ((vpi == ATM_VPI_ANY) || (vci == ATM_VCI_ANY))
+ return -EINVAL;
+
+ /* only support AAL5 */
if (vcc->qos.aal != ATM_AAL5)
return -EINVAL;
- MOD_INC_USE_COUNT;
+ down (&instance->serialize); /* vs self, udsl_atm_close */
- vcc->dev_data =
- atmsar_open (&(instance->atmsar_vcc_list), vcc, ATM_AAL5, vpi, vci, 0, 0,
- ATMSAR_USE_53BYTE_CELL | ATMSAR_SET_PTI);
- if (!vcc->dev_data) {
- MOD_DEC_USE_COUNT;
- return -ENOMEM; /* this is the only reason atmsar_open can fail... */
+ if (udsl_find_vcc (instance, vpi, vci)) {
+ up (&instance->serialize);
+ return -EADDRINUSE;
}
+ if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) {
+ up (&instance->serialize);
+ return -ENOMEM;
+ }
+
+ memset (new, 0, sizeof (struct udsl_vcc_data));
+ new->vcc = vcc;
+ new->vpi = vpi;
+ new->vci = vci;
+ new->mtu = UDSL_MAX_AAL5_MRU;
+
+ vcc->dev_data = new;
vcc->vpi = vpi;
vcc->vci = vci;
+
+ tasklet_disable (&instance->receive_tasklet);
+ list_add (&new->list, &instance->vcc_list);
+ tasklet_enable (&instance->receive_tasklet);
+
set_bit (ATM_VF_ADDR, &vcc->flags);
set_bit (ATM_VF_PARTIAL, &vcc->flags);
set_bit (ATM_VF_READY, &vcc->flags);
- ((struct atmsar_vcc_data *)vcc->dev_data)->mtu = UDSL_MAX_AAL5_MRU;
+ up (&instance->serialize);
+
+ dbg ("Allocated new SARLib vcc 0x%p with vpi %d vci %d", new, vpi, vci);
+
+ MOD_INC_USE_COUNT;
if (instance->firmware_loaded)
udsl_fire_receivers (instance);
dbg ("udsl_atm_open successful");
+
return 0;
}
static void udsl_atm_close (struct atm_vcc *vcc)
{
struct udsl_instance_data *instance = vcc->dev->dev_data;
+ struct udsl_vcc_data *vcc_data = vcc->dev_data;
dbg ("udsl_atm_close called");
- if (!instance) {
- dbg ("NULL instance!");
+ if (!instance || !vcc_data) {
+ dbg ("NULL data!");
return;
}
- /* freeing resources */
- /* cancel all sends on this vcc */
+ dbg ("Deallocating SARLib vcc 0x%p with vpi %d vci %d", vcc_data, vcc_data->vpi, vcc_data->vci);
+
udsl_cancel_send (instance, vcc);
- atmsar_close (&(instance->atmsar_vcc_list), vcc->dev_data);
+ down (&instance->serialize); /* vs self, udsl_atm_open */
+
+ tasklet_disable (&instance->receive_tasklet);
+ list_del (&vcc_data->list);
+ tasklet_enable (&instance->receive_tasklet);
+
+ if (vcc_data->reasBuffer)
+ kfree_skb (vcc_data->reasBuffer);
+ vcc_data->reasBuffer = NULL;
+
+ kfree (vcc_data);
vcc->dev_data = NULL;
- clear_bit (ATM_VF_PARTIAL, &vcc->flags);
- /* freeing address */
vcc->vpi = ATM_VPI_UNSPEC;
vcc->vci = ATM_VCI_UNSPEC;
+ clear_bit (ATM_VF_READY, &vcc->flags);
+ clear_bit (ATM_VF_PARTIAL, &vcc->flags);
clear_bit (ATM_VF_ADDR, &vcc->flags);
+ up (&instance->serialize);
+
MOD_DEC_USE_COUNT;
dbg ("udsl_atm_close successful");
- return;
}
static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
@@ -1209,6 +1095,8 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
instance->usb_dev = dev;
+ INIT_LIST_HEAD (&instance->vcc_list);
+
spin_lock_init (&instance->spare_receivers_lock);
INIT_LIST_HEAD (&instance->spare_receivers);
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index cc0ecaaeee70..a0b1c423c832 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -881,6 +881,8 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async)
init_completion (&completion);
urb = simple_alloc_urb (testdev_to_usbdev (dev), pipe, size);
+ if (!urb)
+ return -ENOMEM;
if (async)
urb->transfer_flags |= URB_ASYNC_UNLINK;
urb->context = &completion;
@@ -1407,6 +1409,11 @@ static struct usb_device_id id_table [] = {
.driver_info = (unsigned long) &fw_info,
},
+ /* "Gadget Zero" firmware runs under Linux */
+ { USB_DEVICE (0x0525, 0xa4a0),
+ .driver_info = (unsigned long) &fw_info,
+ },
+
#ifdef KEYSPAN_19Qi
/* Keyspan 19qi uses an21xx (original EZ-USB) */
// this does not coexist with the real Keyspan 19qi driver!
diff --git a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c
index e6b530720209..0d2cad6d33e7 100644
--- a/drivers/usb/net/cdc-ether.c
+++ b/drivers/usb/net/cdc-ether.c
@@ -269,22 +269,8 @@ static void CDCEther_tx_timeout( struct net_device *net )
static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net )
{
ether_dev_t *ether_dev = net->priv;
- int count;
int res;
- // If we are told to transmit an ethernet frame that fits EXACTLY
- // into an integer number of USB packets, we force it to send one
- // more byte so the device will get a runt USB packet signalling the
- // end of the ethernet frame
- if ( (skb->len) ^ (ether_dev->data_ep_out_size) ) {
- // It was not an exact multiple
- // no need to add anything extra
- count = skb->len;
- } else {
- // Add one to make it NOT an exact multiple
- count = skb->len + 1;
- }
-
// Tell the kernel, "No more frames 'til we are done
// with this one.'
netif_stop_queue( net );
@@ -299,7 +285,10 @@ static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net )
write_bulk_callback, ether_dev );
// Tell the URB how much it will be transporting today
- ether_dev->tx_urb->transfer_buffer_length = count;
+ ether_dev->tx_urb->transfer_buffer_length = skb->len;
+
+ /* Deal with the zero length problem, I hope */
+ ether_dev->tx_urb->transfer_flags |= URB_ZERO_PACKET;
// Send the URB on its merry way.
if ((res = usb_submit_urb(ether_dev->tx_urb, GFP_ATOMIC))) {
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 99c634017192..e15f060772f4 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -406,8 +406,6 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
int result = 0;
int todo = 0;
struct kobil_private * priv;
- int i;
- char *data;
if (count == 0) {
dbg("%s - port %d write request of 0 bytes", __FUNCTION__, port->number);
@@ -421,19 +419,6 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
return -ENOMEM;
}
- // BEGIN DEBUG
- data = (unsigned char *) kmalloc((3 * count + 10) * sizeof(char), GFP_KERNEL);
- if (! data) {
- return (-1);
- }
- memset(data, 0, (3 * count + 10));
- for (i = 0; i < count; i++) {
- sprintf(data +3*i, "%02X ", buf[i]);
- }
- dbg(" %d --> %s", port->number, data );
- kfree(data);
- // END DEBUG
-
// Copy data to buffer
if (from_user) {
if (copy_from_user(priv->buf + priv->filled, buf, count)) {
@@ -443,6 +428,8 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
memcpy (priv->buf + priv->filled, buf, count);
}
+ usb_serial_debug_data (__FILE__, __FUNCTION__, count, priv->buf + priv->filled);
+
priv->filled = priv->filled + count;
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 1f56f63bb8e5..9ac69a72555c 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -405,11 +405,14 @@ static int isd200_action( struct us_data *us, int action,
{
union ata_cdb ata;
struct scsi_cmnd srb;
+ struct scsi_device srb_dev;
struct isd200_info *info = (struct isd200_info *)us->extra;
int status;
memset(&ata, 0, sizeof(ata));
memset(&srb, 0, sizeof(srb));
+ memset(&srb_dev, 0, sizeof(srb_dev));
+ srb.device = &srb_dev;
ata.generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
ata.generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
@@ -479,6 +482,7 @@ static int isd200_action( struct us_data *us, int action,
}
memcpy(srb.cmnd, &ata, sizeof(ata.generic));
+ srb.cmd_len = sizeof(ata.generic);
status = usb_stor_Bulk_transport(&srb, us);
if (status == USB_STOR_TRANSPORT_GOOD)
status = ISD200_GOOD;
@@ -538,6 +542,7 @@ void isd200_invoke_transport( struct us_data *us,
/* send the command to the transport layer */
srb->resid = 0;
memcpy(srb->cmnd, ataCdb, sizeof(ataCdb->generic));
+ srb->cmd_len = sizeof(ataCdb->generic);
transferStatus = usb_stor_Bulk_transport(srb, us);
/* if the command gets aborted by the higher layers, we need to
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index f30d8c162db9..f57afebe8df6 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -209,21 +209,14 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb )
return result;
}
-/* This resets the device port, and simulates the device
- * disconnect/reconnect for all drivers which have claimed
- * interfaces, including ourself. */
+/* This resets the device port */
+/* It refuses to work if there's more than one interface in
+ this device, so that other users are not affected. */
/* This is always called with scsi_lock(srb->host) held */
-/* FIXME: This needs to be re-examined in the face of the new
- * hotplug system -- this will implicitly cause a detach/reattach of
- * usb-storage, which is not what we want now.
- *
- * Can we just skip over usb-storage in the while loop?
- */
static int usb_storage_bus_reset( Scsi_Cmnd *srb )
{
struct us_data *us;
- int i;
int result;
/* we use the usb_reset_device() function to handle this for us */
@@ -231,36 +224,25 @@ static int usb_storage_bus_reset( Scsi_Cmnd *srb )
scsi_unlock(srb->device->host);
us = (struct us_data *)srb->device->host->hostdata[0];
- /* attempt to reset the port */
- result = usb_reset_device(us->pusb_dev);
- US_DEBUGP("usb_reset_device returns %d\n", result);
- if (result < 0) {
- scsi_lock(srb->device->host);
- return FAILED;
+ /* The USB subsystem doesn't handle synchronisation between
+ a device's several drivers. Therefore we reset only devices
+ with one interface which we of course own.
+ */
+
+ //FIXME: needs locking against config changes
+
+ if ( us->pusb_dev->actconfig->desc.bNumInterfaces == 1) {
+ /* attempt to reset the port */
+ result = usb_reset_device(us->pusb_dev);
+ US_DEBUGP("usb_reset_device returns %d\n", result);
+ } else {
+ result = -EBUSY;
+ US_DEBUGP("cannot reset a multiinterface device. failing to reset.\n");
}
- /* FIXME: This needs to lock out driver probing while it's working
- * or we can have race conditions */
- /* This functionality really should be provided by the khubd thread */
- for (i = 0; i < us->pusb_dev->actconfig->desc.bNumInterfaces; i++) {
- struct usb_interface *intf =
- &us->pusb_dev->actconfig->interface[i];
-
- /* if this is an unclaimed interface, skip it */
- if (!intf->driver) {
- continue;
- }
-
- US_DEBUGP("Examining driver %s...", intf->driver->name);
-
- /* simulate a disconnect and reconnect for all interfaces */
- US_DEBUGPX("simulating disconnect/reconnect.\n");
- usb_device_remove (&intf->dev);
- usb_device_probe (&intf->dev);
- }
US_DEBUGP("bus_reset() complete\n");
scsi_lock(srb->device->host);
- return SUCCESS;
+ return result < 0 ? FAILED : SUCCESS;
}
/***********************************************************************
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index b0371f74e40a..0c59028691d0 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -126,6 +126,7 @@ static int usb_stor_msg_common(struct us_data *us)
us->current_urb->actual_length = 0;
us->current_urb->error_count = 0;
us->current_urb->transfer_flags = URB_ASYNC_UNLINK;
+ us->current_urb->status = 0;
/* submit the URB */
status = usb_submit_urb(us->current_urb, GFP_NOIO);
@@ -900,7 +901,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
bcb.DataTransferLength = cpu_to_le32(transfer_length);
bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
bcb.Tag = srb->serial_number;
- bcb.Lun = srb->cmnd[1] >> 5;
+ bcb.Lun = srb->device->lun;
if (us->flags & US_FL_SCM_MULT_TARG)
bcb.Lun |= srb->device->id << 4;
bcb.Length = srb->cmd_len;
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 4c2b6de50c91..aa0b5ec968bc 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -360,7 +360,7 @@ static int usb_stor_control_thread(void * __us)
}
else if (us->srb->device->lun > us->max_lun) {
- US_DEBUGP("Bad LUN (%d/%d)\n",
+ US_DEBUGP("Bad LUN (%d:%d)\n",
us->srb->device->id, us->srb->device->lun);
us->srb->result = DID_BAD_TARGET << 16;
}
@@ -475,8 +475,6 @@ static int usb_stor_allocate_urbs(struct us_data *ss)
*/
static void usb_stor_deallocate_urbs(struct us_data *ss)
{
- int result;
-
/* free the scatter-gather request block */
if (ss->current_sg) {
kfree(ss->current_sg);
@@ -486,8 +484,6 @@ static void usb_stor_deallocate_urbs(struct us_data *ss)
/* free up the main URB for this device */
if (ss->current_urb) {
US_DEBUGP("-- releasing main URB\n");
- result = usb_unlink_urb(ss->current_urb);
- US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);
usb_free_urb(ss->current_urb);
ss->current_urb = NULL;
}
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 447382eca091..0c833fdeee42 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -72,13 +72,15 @@ MODULE_PARM(debug, "i");
MODULE_PARM_DESC(debug, "Debug enabled or not");
-/* Define these values to match your device */
+/* Define these values to match your devices */
#define USB_SKEL_VENDOR_ID 0xfff0
#define USB_SKEL_PRODUCT_ID 0xfff0
/* table of devices that work with this driver */
static struct usb_device_id skel_table [] = {
{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
+ /* "Gadget Zero" firmware runs under Linux */
+ { USB_DEVICE(0x0525, 0xa4a0) },
{ } /* Terminating entry */
};
@@ -707,7 +709,7 @@ static int __init usb_skel_init(void)
/* register this driver with the USB subsystem */
result = usb_register(&skel_driver);
if (result < 0) {
- err("usb_register failed for the "__FILE__" driver. Error number %d",
+ err("usb_register failed. Error number %d",
result);
return -1;
}
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);
}
diff --git a/include/pcmcia/bus_ops.h b/include/pcmcia/bus_ops.h
index d99634af16f3..eb094dd03fca 100644
--- a/include/pcmcia/bus_ops.h
+++ b/include/pcmcia/bus_ops.h
@@ -1,152 +1,2 @@
-/*
- * bus_ops.h 1.10 2000/06/12 21:55:41
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
- * above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use
- * your version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- */
-
-#ifndef _LINUX_BUS_OPS_H
-#define _LINUX_BUS_OPS_H
-
-#include <linux/config.h>
-
-#ifdef CONFIG_VIRTUAL_BUS
-
-typedef struct bus_operations {
- void *priv;
- u32 (*b_in)(void *bus, u32 port, s32 sz);
- void (*b_ins)(void *bus, u32 port, void *buf,
- u32 count, s32 sz);
- void (*b_out)(void *bus, u32 val, u32 port, s32 sz);
- void (*b_outs)(void *bus, u32 port, void *buf,
- u32 count, s32 sz);
- void *(*b_ioremap)(void *bus, u_long ofs, u_long sz);
- void (*b_iounmap)(void *bus, void *addr);
- u32 (*b_read)(void *bus, void *addr, s32 sz);
- void (*b_write)(void *bus, u32 val, void *addr, s32 sz);
- void (*b_copy_from)(void *bus, void *d, void *s, u32 count);
- void (*b_copy_to)(void *bus, void *d, void *s, u32 count);
- int (*b_request_irq)(void *bus, u_int irq,
- void (*handler)(int, void *,
- struct pt_regs *),
- u_long flags, const char *device,
- void *dev_id);
- void (*b_free_irq)(void *bus, u_int irq, void *dev_id);
-} bus_operations;
-
-#define bus_inb(b,p) (b)->b_in((b),(p),0)
-#define bus_inw(b,p) (b)->b_in((b),(p),1)
-#define bus_inl(b,p) (b)->b_in((b),(p),2)
-#define bus_inw_ns(b,p) (b)->b_in((b),(p),-1)
-#define bus_inl_ns(b,p) (b)->b_in((b),(p),-2)
-
-#define bus_insb(b,p,a,c) (b)->b_ins((b),(p),(a),(c),0)
-#define bus_insw(b,p,a,c) (b)->b_ins((b),(p),(a),(c),1)
-#define bus_insl(b,p,a,c) (b)->b_ins((b),(p),(a),(c),2)
-#define bus_insw_ns(b,p,a,c) (b)->b_ins((b),(p),(a),(c),-1)
-#define bus_insl_ns(b,p,a,c) (b)->b_ins((b),(p),(a),(c),-2)
-
-#define bus_outb(b,v,p) (b)->b_out((b),(v),(p),0)
-#define bus_outw(b,v,p) (b)->b_out((b),(v),(p),1)
-#define bus_outl(b,v,p) (b)->b_out((b),(v),(p),2)
-#define bus_outw_ns(b,v,p) (b)->b_out((b),(v),(p),-1)
-#define bus_outl_ns(b,v,p) (b)->b_out((b),(v),(p),-2)
-
-#define bus_outsb(b,p,a,c) (b)->b_outs((b),(p),(a),(c),0)
-#define bus_outsw(b,p,a,c) (b)->b_outs((b),(p),(a),(c),1)
-#define bus_outsl(b,p,a,c) (b)->b_outs((b),(p),(a),(c),2)
-#define bus_outsw_ns(b,p,a,c) (b)->b_outs((b),(p),(a),(c),-1)
-#define bus_outsl_ns(b,p,a,c) (b)->b_outs((b),(p),(a),(c),-2)
-
-#define bus_readb(b,a) (b)->b_read((b),(a),0)
-#define bus_readw(b,a) (b)->b_read((b),(a),1)
-#define bus_readl(b,a) (b)->b_read((b),(a),2)
-#define bus_readw_ns(b,a) (b)->b_read((b),(a),-1)
-#define bus_readl_ns(b,a) (b)->b_read((b),(a),-2)
-
-#define bus_writeb(b,v,a) (b)->b_write((b),(v),(a),0)
-#define bus_writew(b,v,a) (b)->b_write((b),(v),(a),1)
-#define bus_writel(b,v,a) (b)->b_write((b),(v),(a),2)
-#define bus_writew_ns(b,v,a) (b)->b_write((b),(v),(a),-1)
-#define bus_writel_ns(b,v,a) (b)->b_write((b),(v),(a),-2)
-
-#define bus_ioremap(b,s,n) (b)->b_ioremap((b),(s),(n))
-#define bus_iounmap(b,a) (b)->b_iounmap((b),(a))
-#define bus_memcpy_fromio(b,d,s,n) (b)->b_copy_from((b),(d),(s),(n))
-#define bus_memcpy_toio(b,d,s,n) (b)->b_copy_to((b),(d),(s),(n))
-
-#define bus_request_irq(b,i,h,f,n,d) \
- (b)->b_request_irq((b),(i),(h),(f),(n),(d))
-#define bus_free_irq(b,i,d) (b)->b_free_irq((b),(i),(d))
-
-#else
-
-#define bus_inb(b,p) inb(p)
-#define bus_inw(b,p) inw(p)
-#define bus_inl(b,p) inl(p)
-#define bus_inw_ns(b,p) inw_ns(p)
-#define bus_inl_ns(b,p) inl_ns(p)
-
-#define bus_insb(b,p,a,c) insb(p,a,c)
-#define bus_insw(b,p,a,c) insw(p,a,c)
-#define bus_insl(b,p,a,c) insl(p,a,c)
-#define bus_insw_ns(b,p,a,c) insw_ns(p,a,c)
-#define bus_insl_ns(b,p,a,c) insl_ns(p,a,c)
-
-#define bus_outb(b,v,p) outb(b,v,p)
-#define bus_outw(b,v,p) outw(b,v,p)
-#define bus_outl(b,v,p) outl(b,v,p)
-#define bus_outw_ns(b,v,p) outw_ns(b,v,p)
-#define bus_outl_ns(b,v,p) outl_ns(b,v,p)
-
-#define bus_outsb(b,p,a,c) outsb(p,a,c)
-#define bus_outsw(b,p,a,c) outsw(p,a,c)
-#define bus_outsl(b,p,a,c) outsl(p,a,c)
-#define bus_outsw_ns(b,p,a,c) outsw_ns(p,a,c)
-#define bus_outsl_ns(b,p,a,c) outsl_ns(p,a,c)
-
-#define bus_readb(b,a) readb(a)
-#define bus_readw(b,a) readw(a)
-#define bus_readl(b,a) readl(a)
-#define bus_readw_ns(b,a) readw_ns(a)
-#define bus_readl_ns(b,a) readl_ns(a)
-
-#define bus_writeb(b,v,a) writeb(v,a)
-#define bus_writew(b,v,a) writew(v,a)
-#define bus_writel(b,v,a) writel(v,a)
-#define bus_writew_ns(b,v,a) writew_ns(v,a)
-#define bus_writel_ns(b,v,a) writel_ns(v,a)
-
-#define bus_ioremap(b,s,n) ioremap(s,n)
-#define bus_iounmap(b,a) iounmap(a)
-#define bus_memcpy_fromio(b,d,s,n) memcpy_fromio(d,s,n)
-#define bus_memcpy_toio(b,d,s,n) memcpy_toio(d,s,n)
-
-#define bus_request_irq(b,i,h,f,n,d) request_irq((i),(h),(f),(n),(d))
-#define bus_free_irq(b,i,d) free_irq((i),(d))
-
-#endif /* CONFIG_VIRTUAL_BUS */
-
-#endif /* _LINUX_BUS_OPS_H */
+/* now empty */
+#warning please remove the reference to this file
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h
index 2bd505c969dc..e29dfbb82a99 100644
--- a/include/pcmcia/cs.h
+++ b/include/pcmcia/cs.h
@@ -98,7 +98,6 @@ typedef struct event_callback_args_t {
void *buffer;
void *misc;
void *client_data;
- struct bus_operations *bus;
} event_callback_args_t;
/* for GetConfigurationInfo */
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 2d8fee9e7733..fcc6515cc2e1 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -58,7 +58,6 @@ typedef struct socket_cap_t {
ioaddr_t io_offset;
u_char pci_irq;
struct pci_dev *cb_dev;
- struct bus_operations *bus;
} socket_cap_t;
/* InquireSocket capabilities */
@@ -134,9 +133,7 @@ struct pccard_operations {
int (*get_status)(unsigned int sock, u_int *value);
int (*get_socket)(unsigned int sock, socket_state_t *state);
int (*set_socket)(unsigned int sock, socket_state_t *state);
- int (*get_io_map)(unsigned int sock, struct pccard_io_map *io);
int (*set_io_map)(unsigned int sock, struct pccard_io_map *io);
- int (*get_mem_map)(unsigned int sock, struct pccard_mem_map *mem);
int (*set_mem_map)(unsigned int sock, struct pccard_mem_map *mem);
void (*proc_setup)(unsigned int sock, struct proc_dir_entry *base);
};