summaryrefslogtreecommitdiffstats
path: root/fs/xfs/support
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/support')
-rw-r--r--fs/xfs/support/debug.c127
-rw-r--r--fs/xfs/support/debug.h72
-rw-r--r--fs/xfs/support/ktrace.c346
-rw-r--r--fs/xfs/support/ktrace.h101
-rw-r--r--fs/xfs/support/move.c66
-rw-r--r--fs/xfs/support/move.h84
-rw-r--r--fs/xfs/support/qsort.c155
-rw-r--r--fs/xfs/support/qsort.h41
-rw-r--r--fs/xfs/support/uuid.c151
-rw-r--r--fs/xfs/support/uuid.h48
10 files changed, 1191 insertions, 0 deletions
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
new file mode 100644
index 00000000000..7d6e1f37df1
--- /dev/null
+++ b/fs/xfs/support/debug.c
@@ -0,0 +1,127 @@
+/*
+ * 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 "debug.h"
+
+#include <asm/page.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+
+int doass = 1;
+static char message[256]; /* keep it off the stack */
+static DEFINE_SPINLOCK(xfs_err_lock);
+
+/* Translate from CE_FOO to KERN_FOO, err_level(CE_FOO) == KERN_FOO */
+#define XFS_MAX_ERR_LEVEL 7
+#define XFS_ERR_MASK ((1 << 3) - 1)
+static char *err_level[XFS_MAX_ERR_LEVEL+1] =
+ {KERN_EMERG, KERN_ALERT, KERN_CRIT,
+ KERN_ERR, KERN_WARNING, KERN_NOTICE,
+ KERN_INFO, KERN_DEBUG};
+
+void
+assfail(char *a, char *f, int l)
+{
+ printk("XFS assertion failed: %s, file: %s, line: %d\n", a, f, l);
+ BUG();
+}
+
+#if ((defined(DEBUG) || defined(INDUCE_IO_ERRROR)) && !defined(NO_WANT_RANDOM))
+
+unsigned long
+random(void)
+{
+ static unsigned long RandomValue = 1;
+ /* cycles pseudo-randomly through all values between 1 and 2^31 - 2 */
+ register long rv = RandomValue;
+ register long lo;
+ register long hi;
+
+ hi = rv / 127773;
+ lo = rv % 127773;
+ rv = 16807 * lo - 2836 * hi;
+ if( rv <= 0 ) rv += 2147483647;
+ return( RandomValue = rv );
+}
+
+int
+get_thread_id(void)
+{
+ return current->pid;
+}
+
+#endif /* DEBUG || INDUCE_IO_ERRROR || !NO_WANT_RANDOM */
+
+void
+cmn_err(register int level, char *fmt, ...)
+{
+ char *fp = fmt;
+ int len;
+ ulong flags;
+ va_list ap;
+
+ level &= XFS_ERR_MASK;
+ if (level > XFS_MAX_ERR_LEVEL)
+ level = XFS_MAX_ERR_LEVEL;
+ spin_lock_irqsave(&xfs_err_lock,flags);
+ va_start(ap, fmt);
+ if (*fmt == '!') fp++;
+ len = vsprintf(message, fp, ap);
+ if (message[len-1] != '\n')
+ strcat(message, "\n");
+ printk("%s%s", err_level[level], message);
+ va_end(ap);
+ spin_unlock_irqrestore(&xfs_err_lock,flags);
+
+ if (level == CE_PANIC)
+ BUG();
+}
+
+
+void
+icmn_err(register int level, char *fmt, va_list ap)
+{
+ ulong flags;
+ int len;
+
+ level &= XFS_ERR_MASK;
+ if(level > XFS_MAX_ERR_LEVEL)
+ level = XFS_MAX_ERR_LEVEL;
+ spin_lock_irqsave(&xfs_err_lock,flags);
+ len = vsprintf(message, fmt, ap);
+ if (message[len-1] != '\n')
+ strcat(message, "\n");
+ spin_unlock_irqrestore(&xfs_err_lock,flags);
+ printk("%s%s", err_level[level], message);
+ if (level == CE_PANIC)
+ BUG();
+}
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
new file mode 100644
index 00000000000..40b0f4c54d9
--- /dev/null
+++ b/fs/xfs/support/debug.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2000-2004 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_SUPPORT_DEBUG_H__
+#define __XFS_SUPPORT_DEBUG_H__
+
+#include <stdarg.h>
+
+#define CE_DEBUG 7 /* debug */
+#define CE_CONT 6 /* continuation */
+#define CE_NOTE 5 /* notice */
+#define CE_WARN 4 /* warning */
+#define CE_ALERT 1 /* alert */
+#define CE_PANIC 0 /* panic */
+
+extern void icmn_err(int, char *, va_list);
+/* PRINTFLIKE2 */
+extern void cmn_err(int, char *, ...);
+
+#ifndef STATIC
+# define STATIC static
+#endif
+
+#ifdef DEBUG
+# ifdef lint
+# define ASSERT(EX) ((void)0) /* avoid "constant in conditional" babble */
+# else
+# define ASSERT(EX) ((!doass||(EX))?((void)0):assfail(#EX, __FILE__, __LINE__))
+# endif /* lint */
+#else
+# define ASSERT(x) ((void)0)
+#endif
+
+extern int doass; /* dynamically turn off asserts */
+extern void assfail(char *, char *, int);
+#ifdef DEBUG
+extern unsigned long random(void);
+extern int get_thread_id(void);
+#endif
+
+#define ASSERT_ALWAYS(EX) ((EX)?((void)0):assfail(#EX, __FILE__, __LINE__))
+#define debug_stop_all_cpus(param) /* param is "cpumask_t *" */
+
+#endif /* __XFS_SUPPORT_DEBUG_H__ */
diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c
new file mode 100644
index 00000000000..3dae14c8c55
--- /dev/null
+++ b/fs/xfs/support/ktrace.c
@@ -0,0 +1,346 @@
+/*
+ * 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>
+
+static kmem_zone_t *ktrace_hdr_zone;
+static kmem_zone_t *ktrace_ent_zone;
+static int ktrace_zentries;
+
+void
+ktrace_init(int zentries)
+{
+ ktrace_zentries = zentries;
+
+ ktrace_hdr_zone = kmem_zone_init(sizeof(ktrace_t),
+ "ktrace_hdr");
+ ASSERT(ktrace_hdr_zone);
+
+ ktrace_ent_zone = kmem_zone_init(ktrace_zentries
+ * sizeof(ktrace_entry_t),
+ "ktrace_ent");
+ ASSERT(ktrace_ent_zone);
+}
+
+void
+ktrace_uninit(void)
+{
+ kmem_cache_destroy(ktrace_hdr_zone);
+ kmem_cache_destroy(ktrace_ent_zone);
+}
+
+/*
+ * ktrace_alloc()
+ *
+ * Allocate a ktrace header and enough buffering for the given
+ * number of entries.
+ */
+ktrace_t *
+ktrace_alloc(int nentries, int sleep)
+{
+ ktrace_t *ktp;
+ ktrace_entry_t *ktep;
+
+ ktp = (ktrace_t*)kmem_zone_alloc(ktrace_hdr_zone, sleep);
+
+ if (ktp == (ktrace_t*)NULL) {
+ /*
+ * KM_SLEEP callers don't expect failure.
+ */
+ if (sleep & KM_SLEEP)
+ panic("ktrace_alloc: NULL memory on KM_SLEEP request!");
+
+ return NULL;
+ }
+
+ /*
+ * Special treatment for buffers with the ktrace_zentries entries
+ */
+ if (nentries == ktrace_zentries) {
+ ktep = (ktrace_entry_t*)kmem_zone_zalloc(ktrace_ent_zone,
+ sleep);
+ } else {
+ ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)),
+ sleep);
+ }
+
+ if (ktep == NULL) {
+ /*
+ * KM_SLEEP callers don't expect failure.
+ */
+ if (sleep & KM_SLEEP)
+ panic("ktrace_alloc: NULL memory on KM_SLEEP request!");
+
+ kmem_free(ktp, sizeof(*ktp));
+
+ return NULL;
+ }
+
+ spinlock_init(&(ktp->kt_lock), "kt_lock");
+
+ ktp->kt_entries = ktep;
+ ktp->kt_nentries = nentries;
+ ktp->kt_index = 0;
+ ktp->kt_rollover = 0;
+ return ktp;
+}
+
+
+/*
+ * ktrace_free()
+ *
+ * Free up the ktrace header and buffer. It is up to the caller
+ * to ensure that no-one is referencing it.
+ */
+void
+ktrace_free(ktrace_t *ktp)
+{
+ int entries_size;
+
+ if (ktp == (ktrace_t *)NULL)
+ return;
+
+ spinlock_destroy(&ktp->kt_lock);
+
+ /*
+ * Special treatment for the Vnode trace buffer.
+ */
+ if (ktp->kt_nentries == ktrace_zentries) {
+ kmem_zone_free(ktrace_ent_zone, ktp->kt_entries);
+ } else {
+ entries_size = (int)(ktp->kt_nentries * sizeof(ktrace_entry_t));
+
+ kmem_free(ktp->kt_entries, entries_size);
+ }
+
+ kmem_zone_free(ktrace_hdr_zone, ktp);
+}
+
+
+/*
+ * Enter the given values into the "next" entry in the trace buffer.
+ * kt_index is always the index of the next entry to be filled.
+ */
+void
+ktrace_enter(
+ ktrace_t *ktp,
+ void *val0,
+ void *val1,
+ void *val2,
+ void *val3,
+ void *val4,
+ void *val5,
+ void *val6,
+ void *val7,
+ void *val8,
+ void *val9,
+ void *val10,
+ void *val11,
+ void *val12,
+ void *val13,
+ void *val14,
+ void *val15)
+{
+ static lock_t wrap_lock = SPIN_LOCK_UNLOCKED;
+ unsigned long flags;
+ int index;
+ ktrace_entry_t *ktep;
+
+ ASSERT(ktp != NULL);
+
+ /*
+ * Grab an entry by pushing the index up to the next one.
+ */
+ spin_lock_irqsave(&wrap_lock, flags);
+ index = ktp->kt_index;
+ if (++ktp->kt_index == ktp->kt_nentries)
+ ktp->kt_index = 0;
+ spin_unlock_irqrestore(&wrap_lock, flags);
+
+ if (!ktp->kt_rollover && index == ktp->kt_nentries - 1)
+ ktp->kt_rollover = 1;
+
+ ASSERT((index >= 0) && (index < ktp->kt_nentries));
+
+ ktep = &(ktp->kt_entries[index]);
+
+ ktep->val[0] = val0;
+ ktep->val[1] = val1;
+ ktep->val[2] = val2;
+ ktep->val[3] = val3;
+ ktep->val[4] = val4;
+ ktep->val[5] = val5;
+ ktep->val[6] = val6;
+ ktep->val[7] = val7;
+ ktep->val[8] = val8;
+ ktep->val[9] = val9;
+ ktep->val[10] = val10;
+ ktep->val[11] = val11;
+ ktep->val[12] = val12;
+ ktep->val[13] = val13;
+ ktep->val[14] = val14;
+ ktep->val[15] = val15;
+}
+
+/*
+ * Return the number of entries in the trace buffer.
+ */
+int
+ktrace_nentries(
+ ktrace_t *ktp)
+{
+ if (ktp == NULL) {
+ return 0;
+ }
+
+ return (ktp->kt_rollover ? ktp->kt_nentries : ktp->kt_index);
+}
+
+/*
+ * ktrace_first()
+ *
+ * This is used to find the start of the trace buffer.
+ * In conjunction with ktrace_next() it can be used to
+ * iterate through the entire trace buffer. This code does
+ * not do any locking because it is assumed that it is called
+ * from the debugger.
+ *
+ * The caller must pass in a pointer to a ktrace_snap
+ * structure in which we will keep some state used to
+ * iterate through the buffer. This state must not touched
+ * by any code outside of this module.
+ */
+ktrace_entry_t *
+ktrace_first(ktrace_t *ktp, ktrace_snap_t *ktsp)
+{
+ ktrace_entry_t *ktep;
+ int index;
+ int nentries;
+
+ if (ktp->kt_rollover)
+ index = ktp->kt_index;
+ else
+ index = 0;
+
+ ktsp->ks_start = index;
+ ktep = &(ktp->kt_entries[index]);
+
+ nentries = ktrace_nentries(ktp);
+ index++;
+ if (index < nentries) {
+ ktsp->ks_index = index;
+ } else {
+ ktsp->ks_index = 0;
+ if (index > nentries)
+ ktep = NULL;
+ }
+ return ktep;
+}
+
+/*
+ * ktrace_next()
+ *
+ * This is used to iterate through the entries of the given
+ * trace buffer. The caller must pass in the ktrace_snap_t
+ * structure initialized by ktrace_first(). The return value
+ * will be either a pointer to the next ktrace_entry or NULL
+ * if all of the entries have been traversed.
+ */
+ktrace_entry_t *
+ktrace_next(
+ ktrace_t *ktp,
+ ktrace_snap_t *ktsp)
+{
+ int index;
+ ktrace_entry_t *ktep;
+
+ index = ktsp->ks_index;
+ if (index == ktsp->ks_start) {
+ ktep = NULL;
+ } else {
+ ktep = &ktp->kt_entries[index];
+ }
+
+ index++;
+ if (index == ktrace_nentries(ktp)) {
+ ktsp->ks_index = 0;
+ } else {
+ ktsp->ks_index = index;
+ }
+
+ return ktep;
+}
+
+/*
+ * ktrace_skip()
+ *
+ * Skip the next "count" entries and return the entry after that.
+ * Return NULL if this causes us to iterate past the beginning again.
+ */
+ktrace_entry_t *
+ktrace_skip(
+ ktrace_t *ktp,
+ int count,
+ ktrace_snap_t *ktsp)
+{
+ int index;
+ int new_index;
+ ktrace_entry_t *ktep;
+ int nentries = ktrace_nentries(ktp);
+
+ index = ktsp->ks_index;
+ new_index = index + count;
+ while (new_index >= nentries) {
+ new_index -= nentries;
+ }
+ if (index == ktsp->ks_start) {
+ /*
+ * We've iterated around to the start, so we're done.
+ */
+ ktep = NULL;
+ } else if ((new_index < index) && (index < ktsp->ks_index)) {
+ /*
+ * We've skipped past the start again, so we're done.
+ */
+ ktep = NULL;
+ ktsp->ks_index = ktsp->ks_start;
+ } else {
+ ktep = &(ktp->kt_entries[new_index]);
+ new_index++;
+ if (new_index == nentries) {
+ ktsp->ks_index = 0;
+ } else {
+ ktsp->ks_index = new_index;
+ }
+ }
+ return ktep;
+}
diff --git a/fs/xfs/support/ktrace.h b/fs/xfs/support/ktrace.h
new file mode 100644
index 00000000000..92d1a1a5d04
--- /dev/null
+++ b/fs/xfs/support/ktrace.h
@@ -0,0 +1,101 @@
+/*
+ * 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/
+ */
+#ifndef __XFS_SUPPORT_KTRACE_H__
+#define __XFS_SUPPORT_KTRACE_H__
+
+#include <spin.h>
+
+/*
+ * Trace buffer entry structure.
+ */
+typedef struct ktrace_entry {
+ void *val[16];
+} ktrace_entry_t;
+
+/*
+ * Trace buffer header structure.
+ */
+typedef struct ktrace {
+ lock_t kt_lock; /* mutex to guard counters */
+ int kt_nentries; /* number of entries in trace buf */
+ int kt_index; /* current index in entries */
+ int kt_rollover;
+ ktrace_entry_t *kt_entries; /* buffer of entries */
+} ktrace_t;
+
+/*
+ * Trace buffer snapshot structure.
+ */
+typedef struct ktrace_snap {
+ int ks_start; /* kt_index at time of snap */
+ int ks_index; /* current index */
+} ktrace_snap_t;
+
+
+#ifdef CONFIG_XFS_TRACE
+
+extern void ktrace_init(int zentries);
+extern void ktrace_uninit(void);
+
+extern ktrace_t *ktrace_alloc(int, int);
+extern void ktrace_free(ktrace_t *);
+
+extern void ktrace_enter(
+ ktrace_t *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void *);
+
+extern ktrace_entry_t *ktrace_first(ktrace_t *, ktrace_snap_t *);
+extern int ktrace_nentries(ktrace_t *);
+extern ktrace_entry_t *ktrace_next(ktrace_t *, ktrace_snap_t *);
+extern ktrace_entry_t *ktrace_skip(ktrace_t *, int, ktrace_snap_t *);
+
+#else
+#define ktrace_init(x) do { } while (0)
+#define ktrace_uninit() do { } while (0)
+#endif /* CONFIG_XFS_TRACE */
+
+#endif /* __XFS_SUPPORT_KTRACE_H__ */
diff --git a/fs/xfs/support/move.c b/fs/xfs/support/move.c
new file mode 100644
index 00000000000..15b5194f16b
--- /dev/null
+++ b/fs/xfs/support/move.c
@@ -0,0 +1,66 @@
+/*
+ * 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>
+
+/* Read from kernel buffer at src to user/kernel buffer defined
+ * by the uio structure. Advance the pointer in the uio struct
+ * as we go.
+ */
+int
+uio_read(caddr_t src, size_t len, struct uio *uio)
+{
+ size_t count;
+
+ if (!len || !uio->uio_resid)
+ return 0;
+
+ count = uio->uio_iov->iov_len;
+ if (!count)
+ return 0;
+ if (count > len)
+ count = len;
+
+ if (uio->uio_segflg == UIO_USERSPACE) {
+ if (copy_to_user(uio->uio_iov->iov_base, src, count))
+ return EFAULT;
+ } else {
+ ASSERT(uio->uio_segflg == UIO_SYSSPACE);
+ memcpy(uio->uio_iov->iov_base, src, count);
+ }
+
+ uio->uio_iov->iov_base = (void*)((char*)uio->uio_iov->iov_base + count);
+ uio->uio_iov->iov_len -= count;
+ uio->uio_offset += count;
+ uio->uio_resid -= count;
+ return 0;
+}
diff --git a/fs/xfs/support/move.h b/fs/xfs/support/move.h
new file mode 100644
index 00000000000..3d406dc1c89
--- /dev/null
+++ b/fs/xfs/support/move.h
@@ -0,0 +1,84 @@
+/*
+ * 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/
+ *
+ * Portions Copyright (c) 1982, 1986, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef __XFS_SUPPORT_MOVE_H__
+#define __XFS_SUPPORT_MOVE_H__
+
+#include <linux/uio.h>
+#include <asm/uaccess.h>
+
+/* Segment flag values. */
+enum uio_seg {
+ UIO_USERSPACE, /* from user data space */
+ UIO_SYSSPACE, /* from system space */
+};
+
+struct uio {
+ struct iovec *uio_iov; /* pointer to array of iovecs */
+ int uio_iovcnt; /* number of iovecs in array */
+ xfs_off_t uio_offset; /* offset in file this uio corresponds to */
+ int uio_resid; /* residual i/o count */
+ enum uio_seg uio_segflg; /* see above */
+};
+
+typedef struct uio uio_t;
+typedef struct iovec iovec_t;
+
+extern int uio_read (caddr_t, size_t, uio_t *);
+
+#endif /* __XFS_SUPPORT_MOVE_H__ */
diff --git a/fs/xfs/support/qsort.c b/fs/xfs/support/qsort.c
new file mode 100644
index 00000000000..1ec824140cf
--- /dev/null
+++ b/fs/xfs/support/qsort.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+/*
+ * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
+ */
+#define swapcode(TYPE, parmi, parmj, n) { \
+ long i = (n) / sizeof (TYPE); \
+ register TYPE *pi = (TYPE *) (parmi); \
+ register TYPE *pj = (TYPE *) (parmj); \
+ do { \
+ register TYPE t = *pi; \
+ *pi++ = *pj; \
+ *pj++ = t; \
+ } while (--i > 0); \
+}
+
+#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
+ es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
+
+static __inline void
+swapfunc(char *a, char *b, int n, int swaptype)
+{
+ if (swaptype <= 1)
+ swapcode(long, a, b, n)
+ else
+ swapcode(char, a, b, n)
+}
+
+#define swap(a, b) \
+ if (swaptype == 0) { \
+ long t = *(long *)(a); \
+ *(long *)(a) = *(long *)(b); \
+ *(long *)(b) = t; \
+ } else \
+ swapfunc(a, b, es, swaptype)
+
+#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
+
+static __inline char *
+med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
+{
+ return cmp(a, b) < 0 ?
+ (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
+ :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
+}
+
+void
+qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *))
+{
+ char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
+ int d, r, swaptype, swap_cnt;
+ register char *a = aa;
+
+loop: SWAPINIT(a, es);
+ swap_cnt = 0;
+ if (n < 7) {
+ for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
+ for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
+ pl -= es)
+ swap(pl, pl - es);
+ return;
+ }
+ pm = (char *)a + (n / 2) * es;
+ if (n > 7) {
+ pl = (char *)a;
+ pn = (char *)a + (n - 1) * es;
+ if (n > 40) {
+ d = (n / 8) * es;
+ pl = med3(pl, pl + d, pl + 2 * d, cmp);
+ pm = med3(pm - d, pm, pm + d, cmp);
+ pn = med3(pn - 2 * d, pn - d, pn, cmp);
+ }
+ pm = med3(pl, pm, pn, cmp);
+ }
+ swap(a, pm);
+ pa = pb = (char *)a + es;
+
+ pc = pd = (char *)a + (n - 1) * es;
+ for (;;) {
+ while (pb <= pc && (r = cmp(pb, a)) <= 0) {
+ if (r == 0) {
+ swap_cnt = 1;
+ swap(pa, pb);
+ pa += es;
+ }
+ pb += es;
+ }
+ while (pb <= pc && (r = cmp(pc, a)) >= 0) {
+ if (r == 0) {
+ swap_cnt = 1;
+ swap(pc, pd);
+ pd -= es;
+ }
+ pc -= es;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc);
+ swap_cnt = 1;
+ pb += es;
+ pc -= es;
+ }
+ if (swap_cnt == 0) { /* Switch to insertion sort */
+ for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
+ for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
+ pl -= es)
+ swap(pl, pl - es);
+ return;
+ }
+
+ pn = (char *)a + n * es;
+ r = min(pa - (char *)a, pb - pa);
+ vecswap(a, pb - r, r);
+ r = min((long)(pd - pc), (long)(pn - pd - es));
+ vecswap(pb, pn - r, r);
+ if ((r = pb - pa) > es)
+ qsort(a, r / es, es, cmp);
+ if ((r = pd - pc) > es) {
+ /* Iterate rather than recurse to save stack space */
+ a = pn - r;
+ n = r / es;
+ goto loop;
+ }
+/* qsort(pn - r, r / es, es, cmp);*/
+}
diff --git a/fs/xfs/support/qsort.h b/fs/xfs/support/qsort.h
new file mode 100644
index 00000000000..94263106d71
--- /dev/null
+++ b/fs/xfs/support/qsort.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2000-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 QSORT_H
+#define QSORT_H
+
+extern void qsort (void *const pbase,
+ size_t total_elems,
+ size_t size,
+ int (*cmp)(const void *, const void *));
+
+#endif
diff --git a/fs/xfs/support/uuid.c b/fs/xfs/support/uuid.c
new file mode 100644
index 00000000000..81f40cfcb26
--- /dev/null
+++ b/fs/xfs/support/uuid.c
@@ -0,0 +1,151 @@
+/*
+ * 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>
+
+static mutex_t uuid_monitor;
+static int uuid_table_size;
+static uuid_t *uuid_table;
+
+void
+uuid_init(void)
+{
+ mutex_init(&uuid_monitor, MUTEX_DEFAULT, "uuid_monitor");
+}
+
+/*
+ * uuid_getnodeuniq - obtain the node unique fields of a UUID.
+ *
+ * This is not in any way a standard or condoned UUID function;
+ * it just something that's needed for user-level file handles.
+ */
+void
+uuid_getnodeuniq(uuid_t *uuid, int fsid [2])
+{
+ char *uu = (char *)uuid;
+
+ /* on IRIX, this function assumes big-endian fields within
+ * the uuid, so we use INT_GET to get the same result on
+ * little-endian systems
+ */
+
+ fsid[0] = (INT_GET(*(u_int16_t*)(uu+8), ARCH_CONVERT) << 16) +
+ INT_GET(*(u_int16_t*)(uu+4), ARCH_CONVERT);
+ fsid[1] = INT_GET(*(u_int32_t*)(uu ), ARCH_CONVERT);
+}
+
+void
+uuid_create_nil(uuid_t *uuid)
+{
+ memset(uuid, 0, sizeof(*uuid));
+}
+
+int
+uuid_is_nil(uuid_t *uuid)
+{
+ int i;
+ char *cp = (char *)uuid;
+
+ if (uuid == NULL)
+ return 0;
+ /* implied check of version number here... */
+ for (i = 0; i < sizeof *uuid; i++)
+ if (*cp++) return 0; /* not nil */
+ return 1; /* is nil */
+}
+
+int
+uuid_equal(uuid_t *uuid1, uuid_t *uuid2)
+{
+ return memcmp(uuid1, uuid2, sizeof(uuid_t)) ? 0 : 1;
+}
+
+/*
+ * Given a 128-bit uuid, return a 64-bit value by adding the top and bottom
+ * 64-bit words. NOTE: This function can not be changed EVER. Although
+ * brain-dead, some applications depend on this 64-bit value remaining
+ * persistent. Specifically, DMI vendors store the value as a persistent
+ * filehandle.
+ */
+__uint64_t
+uuid_hash64(uuid_t *uuid)
+{
+ __uint64_t *sp = (__uint64_t *)uuid;
+
+ return sp[0] + sp[1];
+}
+
+int
+uuid_table_insert(uuid_t *uuid)
+{
+ int i, hole;
+
+ mutex_lock(&uuid_monitor, PVFS);
+ for (i = 0, hole = -1; i < uuid_table_size; i++) {
+ if (uuid_is_nil(&uuid_table[i])) {
+ hole = i;
+ continue;
+ }
+ if (uuid_equal(uuid, &uuid_table[i])) {
+ mutex_unlock(&uuid_monitor);
+ return 0;
+ }
+ }
+ if (hole < 0) {
+ uuid_table = kmem_realloc(uuid_table,
+ (uuid_table_size + 1) * sizeof(*uuid_table),
+ uuid_table_size * sizeof(*uuid_table),
+ KM_SLEEP);
+ hole = uuid_table_size++;
+ }
+ uuid_table[hole] = *uuid;
+ mutex_unlock(&uuid_monitor);
+ return 1;
+}
+
+void
+uuid_table_remove(uuid_t *uuid)
+{
+ int i;
+
+ mutex_lock(&uuid_monitor, PVFS);
+ for (i = 0; i < uuid_table_size; i++) {
+ if (uuid_is_nil(&uuid_table[i]))
+ continue;
+ if (!uuid_equal(uuid, &uuid_table[i]))
+ continue;
+ uuid_create_nil(&uuid_table[i]);
+ break;
+ }
+ ASSERT(i < uuid_table_size);
+ mutex_unlock(&uuid_monitor);
+}
diff --git a/fs/xfs/support/uuid.h b/fs/xfs/support/uuid.h
new file mode 100644
index 00000000000..5220ea58ba2
--- /dev/null
+++ b/fs/xfs/support/uuid.h
@@ -0,0 +1,48 @@
+/*
+ * 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/
+ */
+#ifndef __XFS_SUPPORT_UUID_H__
+#define __XFS_SUPPORT_UUID_H__
+
+typedef struct {
+ unsigned char __u_bits[16];
+} uuid_t;
+
+void uuid_init(void);
+void uuid_create_nil(uuid_t *uuid);
+int uuid_is_nil(uuid_t *uuid);
+int uuid_equal(uuid_t *uuid1, uuid_t *uuid2);
+void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]);
+__uint64_t uuid_hash64(uuid_t *uuid);
+int uuid_table_insert(uuid_t *uuid);
+void uuid_table_remove(uuid_t *uuid);
+
+#endif /* __XFS_SUPPORT_UUID_H__ */