aboutsummaryrefslogtreecommitdiff
path: root/sys/gnu/fs/xfs/FreeBSD
diff options
context:
space:
mode:
authorCraig Rodrigues <rodrigc@FreeBSD.org>2006-06-09 06:04:06 +0000
committerCraig Rodrigues <rodrigc@FreeBSD.org>2006-06-09 06:04:06 +0000
commit331b6cc0eacb0855a2815aaee6560d888bf061e3 (patch)
tree3870274154c262dd1aabe979005608f7e5f40b7d /sys/gnu/fs/xfs/FreeBSD
parent24ea27ad1a11429b4dc097e63e5dfed9cd3c2bba (diff)
downloadsrc-331b6cc0eacb0855a2815aaee6560d888bf061e3.tar.gz
src-331b6cc0eacb0855a2815aaee6560d888bf061e3.zip
Sync XFS for FreeBSD tree with newer changes from SGI XFS for Linux tree.
Improve support for writing to XFS partitions. Work done by: Russell Cattelan <cattelan at xfs dot org>
Notes
Notes: svn path=/head/; revision=159451
Diffstat (limited to 'sys/gnu/fs/xfs/FreeBSD')
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/atomic.h1
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/debug.h3
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/kmem.h31
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/ktrace.c42
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/rwlock.h1
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/spin.h18
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/support/sv.h24
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_buf.c210
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_buf.h145
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_compat.h16
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_dmistubs.c3
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_freebsd.h48
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c414
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_frw.c362
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_frw.h9
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_globals.c28
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c845
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_iops.h3
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c80
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_super.c167
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_super.h47
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.h68
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vfs.c38
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vfs.h5
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vnode.c115
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vnode.h71
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c356
27 files changed, 1941 insertions, 1209 deletions
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/atomic.h b/sys/gnu/fs/xfs/FreeBSD/support/atomic.h
index f8b6c9171ddc..618de8ccf380 100644
--- a/sys/gnu/fs/xfs/FreeBSD/support/atomic.h
+++ b/sys/gnu/fs/xfs/FreeBSD/support/atomic.h
@@ -14,7 +14,6 @@ typedef struct {
#define atomic_inc(v) atomic_add_int(&(v)->val, 1)
#define atomic_dec(v) atomic_subtract_int(&(v)->val, 1)
#define atomic_sub(i, v) atomic_subtract_int(&(v)->val, (i))
-#define atomic_sub_and_test(i, v) (atomic_fetchadd_int(&(v)->val, (-i) == i)
#define atomic_dec_and_test(v) (atomic_fetchadd_int(&(v)->val, -1) == 1)
/*
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/debug.h b/sys/gnu/fs/xfs/FreeBSD/support/debug.h
index 6c82c84260d2..d35b14fe6d4e 100644
--- a/sys/gnu/fs/xfs/FreeBSD/support/debug.h
+++ b/sys/gnu/fs/xfs/FreeBSD/support/debug.h
@@ -44,6 +44,9 @@
extern void icmn_err(int, char *, va_list);
extern void cmn_err(int, char *, ...);
+#define prdev(fmt,targ,args...) \
+ printf("Device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
+
#ifndef STATIC
# define STATIC static
#endif
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/kmem.h b/sys/gnu/fs/xfs/FreeBSD/support/kmem.h
index f457302c062f..4976008f6497 100644
--- a/sys/gnu/fs/xfs/FreeBSD/support/kmem.h
+++ b/sys/gnu/fs/xfs/FreeBSD/support/kmem.h
@@ -26,26 +26,47 @@ typedef unsigned long xfs_pflags_t;
#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
} while (0)
+/* Restore the PF_FSTRANS state to what was saved in STATEP */
+#define PFLAGS_RESTORE_FSTRANS(STATEP) do { \
+} while (0)
+
/*
* memory management routines
*/
#define KM_SLEEP M_WAITOK
-#define KM_SLEEP_IO M_WAITOK
-#define KM_NOFS M_WAITOK
#define KM_NOSLEEP M_NOWAIT
-#define KM_CACHEALIGN 0
+#define KM_NOFS M_WAITOK
+#define KM_MAYFAIL 0
#define kmem_zone uma_zone
typedef struct uma_zone kmem_zone_t;
typedef struct uma_zone xfs_zone_t;
+
+#define KM_ZONE_HWALIGN 0
+#define KM_ZONE_RECLAIM 0
+#define KM_ZONE_SPREAD 0
+
#define kmem_zone_init(len, name) \
uma_zcreate(name, len, NULL, NULL, NULL, NULL, 0, 0)
+
+static inline kmem_zone_t *
+kmem_zone_init_flags(int size, char *zone_name, unsigned long flags,
+ void (*construct)(void *, kmem_zone_t *, unsigned long))
+{
+ return uma_zcreate(zone_name, size, NULL, NULL, NULL, NULL, 0, 0);
+}
+
#define kmem_zone_free(zone, ptr) \
uma_zfree(zone, ptr)
-#define kmem_cache_destroy(zone) \
- uma_zdestroy(zone)
+
+static inline void
+kmem_zone_destroy(kmem_zone_t *zone)
+{
+ uma_zdestroy(zone);
+}
+
#define kmem_zone_alloc(zone, flg) \
uma_zalloc(zone, flg)
#define kmem_zone_zalloc(zone, flg) \
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/ktrace.c b/sys/gnu/fs/xfs/FreeBSD/support/ktrace.c
index 462a66572adc..45a42bfbb32a 100644
--- a/sys/gnu/fs/xfs/FreeBSD/support/ktrace.c
+++ b/sys/gnu/fs/xfs/FreeBSD/support/ktrace.c
@@ -1,35 +1,20 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 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
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms 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.
+ * 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. See the
+ * GNU General Public License for more details.
*
- * 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/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include <xfs.h>
static kmem_zone_t *ktrace_hdr_zone;
@@ -57,8 +42,9 @@ ktrace_init(int zentries)
void
ktrace_uninit(void)
{
- kmem_cache_destroy(ktrace_hdr_zone);
- kmem_cache_destroy(ktrace_ent_zone);
+ kmem_zone_destroy(ktrace_hdr_zone);
+ kmem_zone_destroy(ktrace_ent_zone);
+
mtx_destroy(&wrap_lock);
}
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/rwlock.h b/sys/gnu/fs/xfs/FreeBSD/support/rwlock.h
index 05f489e1e4f6..bfbec23709e1 100644
--- a/sys/gnu/fs/xfs/FreeBSD/support/rwlock.h
+++ b/sys/gnu/fs/xfs/FreeBSD/support/rwlock.h
@@ -14,6 +14,7 @@ typedef int wait_queue_head_t;
#define read_lock(lock) sx_slock(lock)
#define read_unlock(lock) sx_sunlock(lock)
#define write_lock(lock) sx_xlock(lock)
+#define write_trylock(lock) sx_try_xlock(lock)
#define write_unlock(lock) sx_xunlock(lock)
#define rwlock_trypromote(lock) sx_try_upgrade(lock)
#define rwlock_demote(lock) sx_downgrade(lock)
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/spin.h b/sys/gnu/fs/xfs/FreeBSD/support/spin.h
index 2b09be477959..717c13cc8e90 100644
--- a/sys/gnu/fs/xfs/FreeBSD/support/spin.h
+++ b/sys/gnu/fs/xfs/FreeBSD/support/spin.h
@@ -11,7 +11,8 @@
/*
* Map the spinlocks from IRIX to FreeBSD
*/
-#define spinlock_init(lock, name) mtx_init(lock, name, NULL, MTX_DEF)
+/* These spin locks should map to mutex_spin locks? */
+#define spinlock_init(lock, name) mtx_init(lock, name, NULL, /*MTX_SPIN*/ MTX_DEF)
#define spinlock_destroy(lock) mtx_destroy(lock)
/*
@@ -23,20 +24,21 @@ typedef struct mtx lock_t;
#define nested_spinlock(lock) mtx_lock(lock)
#define nested_spintrylock(lock) mtx_trylock(lock)
-#define spin_lock(lock) mtx_lock(lock)
-#define spin_unlock(lock) mtx_unlock(lock)
+#define spin_lock(lock) mtx_lock_spin(lock)
+#define spin_unlock(lock) mtx_unlock_spin(lock)
+#if 0
#if LOCK_DEBUG > 0
#define mutex_spinlock(lock) (spin_lock(lock),0)
#else
static __inline register_t
mutex_spinlock(lock_t *lock) { mtx_lock(lock); return 0; }
#endif
+#endif
-#define mutex_spinunlock(lock,s) \
- do { \
- spin_unlock(lock); \
- if (&s) {} \
- } while (0)
+#define mutex_spinlock(lock) (mtx_lock(lock),0)
+#define mutex_spinunlock(lock,s) mtx_unlock(lock)
+//#define mutex_spinlock(lock) (mtx_lock_spin(lock),0)
+//#define mutex_spinunlock(lock,s) mtx_unlock_spin(lock)
#endif /* __XFS_SUPPORT_SPIN_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/support/sv.h b/sys/gnu/fs/xfs/FreeBSD/support/sv.h
index fa37129c6037..1a378d227591 100644
--- a/sys/gnu/fs/xfs/FreeBSD/support/sv.h
+++ b/sys/gnu/fs/xfs/FreeBSD/support/sv.h
@@ -3,8 +3,8 @@
#include <sys/condvar.h>
-/*
- * Synchronisation variables
+/*
+ * Synchronisation variables
*
* parameters "pri", "svf" and "rts" are not (yet?) implemented
*
@@ -12,18 +12,14 @@
typedef struct cv sv_t;
-#define init_sv(sv,type,name,flag) \
- cv_init(sv, name)
-#define sv_init(sv,flag,name) \
- cv_init(sv, name)
-#define sv_wait(sv, pri, lock, spl) \
- cv_wait_unlock(sv, lock)
-#define sv_signal(sv) \
- cv_signal(sv)
-#define sv_broadcast(sv) \
- cv_broadcast(sv)
-#define sv_destroy(sv) \
- cv_destroy(sv)
+#define init_sv(sv,type,name,flag) cv_init(sv, name)
+#define sv_init(sv,flag,name) cv_init(sv, name)
+/* sv_wait should exit with lock unlocked */
+#define sv_wait(sv, pri, lock, spl) cv_wait_unlock(sv, lock)
+#define sv_wait_sig(sv, pri, lock, spl) cv_wait_sig_nolock(sv, lock)
+#define sv_signal(sv) cv_signal(sv)
+#define sv_broadcast(sv) cv_broadcast(sv)
+#define sv_destroy(sv) cv_destroy(sv)
#define SV_FIFO 0x0 /* sv_t is FIFO type */
#define SV_LIFO 0x2 /* sv_t is LIFO type */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c b/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c
index ac300dbed01c..30aafc4626e0 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_buf.c
@@ -1,9 +1,32 @@
/*
+ * Copyright (c) 2001,2005 Russell Cattelan
+ * 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.
*
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
*/
+
#include "xfs.h"
-#include "xfs_macros.h"
#include "xfs_types.h"
#include "xfs_inum.h"
#include "xfs_log.h"
@@ -16,41 +39,29 @@
#include "xfs_mount.h"
#include "xfs_clnt.h"
#include "xfs_mountops.h"
+
#include <geom/geom.h>
+#include <geom/geom_vfs.h>
xfs_buf_t *
xfs_buf_read_flags(xfs_buftarg_t *target, xfs_daddr_t blkno, size_t len, int flags)
{
struct buf *bp;
- struct g_consumer *cp;
-
KASSERT((target != NULL), ("got NULL buftarg_t"));
- cp = target->specvp->v_bufobj.bo_private;
- if (cp == NULL) {
- bp = NULL;
- goto done;
- }
-
- /* This restriction is in GEOM's g_io_request() */
- if ((BBTOB(len) % cp->provider->sectorsize) != 0) {
- printf("Read request %ld does not align with sector size: %d\n",
- (long)BBTOB(len), cp->provider->sectorsize);
- bp = NULL;
- goto done;
- }
-
if (bread(target->specvp, blkno, BBTOB(len), NOCRED, &bp)) {
printf("bread failed specvp %p blkno %qd BBTOB(len) %ld\n",
target->specvp, blkno, (long)BBTOB(len));
bp = NULL;
- goto done;
}
+
+ /* not really sure what B_MANAGED really does for us
+ * maybe we should drop this and just stick with a locked buf
+ */
+
if (flags & B_MANAGED)
bp->b_flags |= B_MANAGED;
xfs_buf_set_target(bp, target);
-
-done:
return (bp);
}
@@ -97,7 +108,6 @@ xfs_buf_get_noaddr(size_t len, xfs_buftarg_t *target)
xfs_buf_set_target(bp, target);
}
-
return (bp);
}
@@ -116,14 +126,18 @@ xfs_buf_free(xfs_buf_t *bp)
}
void
-xfs_baread(xfs_buftarg_t *targp, xfs_daddr_t ioff, size_t isize)
+xfs_buf_readahead(
+ xfs_buftarg_t *target,
+ xfs_daddr_t ioff,
+ size_t isize,
+ xfs_buf_flags_t flags)
{
daddr_t rablkno;
int rabsize;
rablkno = ioff;
rabsize = BBTOB(isize);
- breada(targp->specvp, &rablkno, &rabsize, 1, NOCRED);
+ breada(target->specvp, &rablkno, &rabsize, 1, NOCRED);
}
void
@@ -148,10 +162,13 @@ XFS_bwrite(xfs_buf_t *bp)
if ((bp->b_flags & B_ASYNC) == 0) {
error = bufwait(bp);
+#if 0
if (BUF_REFCNT(bp) > 1)
BUF_UNLOCK(bp);
else
brelse(bp);
+#endif
+ brelse(bp);
}
return (error);
}
@@ -160,29 +177,160 @@ XFS_bwrite(xfs_buf_t *bp)
}
void
-xfs_bpin(xfs_buf_t *bp)
+xfs_buf_pin(xfs_buf_t *bp)
{
- printf("xfs_bpin(%p)\n", bp);
bpin(bp);
}
void
-xfs_bunpin(xfs_buf_t *bp)
+xfs_buf_unpin(xfs_buf_t *bp)
{
- printf("xfs_bunpin(%p)\n", bp);
bunpin(bp);
}
int
-xfs_ispin(xfs_buf_t *bp)
+xfs_buf_ispin(xfs_buf_t *bp)
{
- printf("xfs_ispin(%p)\n", bp);
return bp->b_pin_count;
}
+#if 0
void
-xfs_bwait_unpin(xfs_buf_t *bp)
+xfs_buf_wait_unpin(
+ xfs_buf_t *bp)
{
- printf("xfs_bwait_unpin(%p)\n", bp);
bunpin_wait(bp);
}
+#endif
+
+/*
+ * Move data into or out of a buffer.
+ */
+void
+xfs_buf_iomove(
+ xfs_buf_t *bp, /* buffer to process */
+ size_t boff, /* starting buffer offset */
+ size_t bsize, /* length to copy */
+ caddr_t data, /* data address */
+ xfs_buf_rw_t mode) /* read/write/zero flag */
+{
+
+ printf("xfs_buf_iomove NI\n");
+#ifdef RMC
+ size_t bend, cpoff, csize;
+ struct page *page;
+
+ bend = boff + bsize;
+ while (boff < bend) {
+ page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)];
+ cpoff = xfs_buf_poff(boff + bp->b_offset);
+ csize = min_t(size_t,
+ PAGE_CACHE_SIZE-cpoff, bp->b_count_desired-boff);
+
+ ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE));
+
+ switch (mode) {
+ case XBRW_ZERO:
+ memset(page_address(page) + cpoff, 0, csize);
+ break;
+ case XBRW_READ:
+ memcpy(data, page_address(page) + cpoff, csize);
+ break;
+ case XBRW_WRITE:
+ memcpy(page_address(page) + cpoff, data, csize);
+ }
+
+ boff += csize;
+ data += csize;
+ }
+#endif
+}
+
+/*
+ * Handling of buffer targets (buftargs).
+ */
+
+/*
+ * Wait for any bufs with callbacks that have been submitted but
+ * have not yet returned... walk the hash list for the target.
+ */
+void
+xfs_wait_buftarg(
+ xfs_buftarg_t *bp)
+{
+ printf("xfs_wait_buftarg(%p) NI\n", bp);
+}
+
+int
+xfs_flush_buftarg(
+ xfs_buftarg_t *btp,
+ int wait)
+{
+ int error = 0;
+
+ error = vinvalbuf(btp->specvp, V_SAVE|V_NORMAL, curthread, 0, 0);
+ return error;
+}
+
+void
+xfs_free_buftarg(
+ xfs_buftarg_t *btp,
+ int external)
+{
+ xfs_flush_buftarg(btp, /* wait */ 0);
+ kmem_free(btp, sizeof(*btp));
+}
+
+int
+xfs_readonly_buftarg(
+ xfs_buftarg_t *btp)
+{
+ struct g_consumer *cp;
+
+ KASSERT(btp->specvp->v_bufobj.bo_ops == &xfs_bo_ops,
+ ("Bogus xfs_buftarg_t pointer"));
+ cp = btp->specvp->v_bufobj.bo_private;
+ return (cp->acw == 0);
+}
+
+#if 0
+void
+xfs_relse_buftarg(
+ xfs_buftarg_t *btp)
+{
+ printf("xfs_relse_buftargNI %p\n",btp);
+}
+#endif
+
+unsigned int
+xfs_getsize_buftarg(
+ xfs_buftarg_t *btp)
+{
+ struct g_consumer *cp;
+ cp = btp->specvp->v_bufobj.bo_private;
+ return (cp->provider->sectorsize);
+}
+
+int
+xfs_setsize_buftarg(
+ xfs_buftarg_t *btp,
+ unsigned int blocksize,
+ unsigned int sectorsize)
+{
+ printf("xfs_setsize_buftarg NI %p\n",btp);
+ return 0;
+}
+
+xfs_buftarg_t *
+xfs_alloc_buftarg(
+ struct vnode *bdev,
+ int external)
+{
+ xfs_buftarg_t *btp;
+
+ btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
+
+ btp->dev = bdev->v_rdev;
+ btp->specvp = bdev;
+ return btp;
+}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_buf.h b/sys/gnu/fs/xfs/FreeBSD/xfs_buf.h
index 54a7fc656e45..c27a14c261ff 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_buf.h
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_buf.h
@@ -35,30 +35,58 @@
#include <sys/bio.h>
#include <sys/buf.h>
-/* XXX: move this into buf.h */
-#ifndef B_MANAGED
-#define B_MANAGED B_08000000
-#endif
-
struct xfs_buf;
struct xfs_mount;
struct vnode;
+typedef struct buf xfs_buf_t;
+typedef uint32_t xfs_buf_flags_t;
+#define xfs_buf buf
+
+extern struct buf_ops xfs_bo_ops;
+
+typedef enum {
+ XBRW_READ = 1, /* transfer into target memory */
+ XBRW_WRITE = 2, /* transfer from target memory */
+ XBRW_ZERO = 3, /* Zero target memory */
+} xfs_buf_rw_t;
+
+/* Buffer Read and Write Routines */
+extern void xfs_buf_ioend(xfs_buf_t *, int);
+extern void xfs_buf_ioerror(xfs_buf_t *, int);
+extern int xfs_buf_iostart(xfs_buf_t *, xfs_buf_flags_t);
+extern int xfs_buf_iorequest(xfs_buf_t *);
+extern int xfs_buf_iowait(xfs_buf_t *);
+extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, xfs_caddr_t, xfs_buf_rw_t);
+
+/* Pinning Buffer Storage in Memory */
+extern void xfs_buf_pin(xfs_buf_t *);
+extern void xfs_buf_unpin(xfs_buf_t *);
+extern int xfs_buf_ispin(xfs_buf_t *);
+
typedef void (*xfs_buf_iodone_t)(struct xfs_buf *); /* call-back function on I/O completion */
typedef void (*xfs_buf_relse_t)(struct xfs_buf *); /* call-back function on I/O completion */
typedef int (*xfs_buf_bdstrat_t)(struct xfs_buf *);
typedef struct xfs_buftarg {
+ /* this probaby redundant info, but stick with linux conventions for now */
+ unsigned int bt_bsize;
+ unsigned int bt_sshift;
+ size_t bt_smask;
struct cdev *dev;
struct vnode *specvp;
} xfs_buftarg_t;
-typedef struct buf xfs_buf_t;
-#define xfs_buf buf
+
+/* Finding and Reading Buffers */
+extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t, xfs_buf_flags_t);
+/* Misc buffer rountines */
+extern int xfs_readonly_buftarg(xfs_buftarg_t *);
/* These are just for xfs_syncsub... it sets an internal variable
* then passes it to VOP_FLUSH_PAGES or adds the flags to a newly gotten buf_t
*/
+#define XBF_DONT_BLOCK 0
#define XFS_B_ASYNC B_ASYNC
#define XFS_B_DELWRI B_DELWRI
@@ -71,13 +99,15 @@ typedef struct buf xfs_buf_t;
#define XFS_BUF_MAPPED 0
#define BUF_BUSY 0
+#define XBF_ORDERED 0
+
/* debugging routines might need this */
#define XFS_BUF_BFLAGS(x) ((x)->b_flags)
#define XFS_BUF_ZEROFLAGS(x) ((x)->b_flags = 0)
-#define XFS_BUF_STALE(x) ((x)->b_flags |= XFS_B_STALE)
-#define XFS_BUF_UNSTALE(x) ((x)->b_flags &= ~XFS_B_STALE)
-#define XFS_BUF_ISSTALE(x) ((x)->b_flags & XFS_B_STALE)
-#define XFS_BUF_SUPER_STALE(x) {(x)->b_flags |= XFS_B_STALE;\
+#define XFS_BUF_STALE(x) ((x)->b_flags |= (XFS_B_STALE|B_NOCACHE))
+#define XFS_BUF_UNSTALE(x) ((x)->b_flags &= ~(XFS_B_STALE|B_NOCACHE))
+#define XFS_BUF_ISSTALE(x) ((x)->b_flags & (XFS_B_STALE|B_NOCACHE))
+#define XFS_BUF_SUPER_STALE(x) {(x)->b_flags |= (XFS_B_STALE|B_NOCACHE); \
(x)->b_flags &= ~(XFS_B_DELWRI|B_CACHE);}
#define XFS_BUF_MANAGE B_MANAGED
@@ -116,6 +146,10 @@ xfs_buf_get_error(struct buf *bp)
#define XFS_BUF_UNASYNC(x) ((x)->b_flags &= ~B_ASYNC)
#define XFS_BUF_ISASYNC(x) ((x)->b_flags & B_ASYNC)
+#define XFS_BUF_ORDERED(bp) ((bp)->b_flags |= XBF_ORDERED)
+#define XFS_BUF_UNORDERED(bp) ((bp)->b_flags &= ~XBF_ORDERED)
+#define XFS_BUF_ISORDERED(bp) ((bp)->b_flags & XBF_ORDERED)
+
#define XFS_BUF_FLUSH(x) ((x)->b_flags |= B_00800000)
#define XFS_BUF_UNFLUSH(x) ((x)->b_flags &= ~B_00800000)
#define XFS_BUF_ISFLUSH(x) ((x)->b_flags & B_00800000)
@@ -203,8 +237,10 @@ xfs_buf_offset(xfs_buf_t *bp, size_t offset)
#define XFS_BUF_VALUSEMA(bp) (BUF_REFCNT(bp)? 0 : 1)
#define XFS_BUF_CPSEMA(bp) \
(BUF_LOCK(bp, LK_EXCLUSIVE|LK_CANRECURSE | LK_SLEEPFAIL, NULL) == 0)
+
#define XFS_BUF_PSEMA(bp,x) BUF_LOCK(bp, LK_EXCLUSIVE|LK_CANRECURSE, NULL)
#define XFS_BUF_VSEMA(bp) BUF_UNLOCK(bp)
+
#define XFS_BUF_V_IODONESEMA(bp) bdone(bp)
/* setup the buffer target from a buftarg structure */
@@ -222,7 +258,7 @@ xfs_buftarg_t *xfs_buf_get_target(xfs_buf_t *);
#define XFS_BUF_SET_VTYPE(bp, type)
#define XFS_BUF_SET_REF(bp, ref)
-#define XFS_BUF_ISPINNED(bp) xfs_ispin(bp)
+#define XFS_BUF_ISPINNED(bp) xfs_buf_ispin(bp)
xfs_buf_t *
xfs_buf_read_flags(xfs_buftarg_t *, xfs_daddr_t, size_t, int);
@@ -238,16 +274,34 @@ xfs_buf_get_flags(xfs_buftarg_t *, xfs_daddr_t, size_t, int);
xfs_buf_get_flags(target, blkno, len, \
XFS_BUF_LOCK | XFS_BUF_MAPPED)
-#define xfs_bdwrite(mp, bp) bdwrite(bp)
-/*
- { ((bp)->b_vp == NULL) ? (bp)->b_bdstrat = xfs_bdstrat_cb: 0; \
- (bp)->b_fsprivate3 = (mp); bdwrite(bp);}
-*/
-#define xfs_bawrite(mp, bp) bawrite(bp)
-/*
- { ((bp)->b_vp == NULL) ? (bp)->b_bdstrat = xfs_bdstrat_cb: 0; \
- (bp)->b_fsprivate3 = (mp); bawrite(bp);}
-*/
+/* the return value is never used ... why does linux define this functions this way? */
+static inline int xfs_bawrite(void *mp, xfs_buf_t *bp)
+{
+ /* Ditto for xfs_bawrite
+ bp->b_fspriv3 = mp;
+ bp->b_strat = xfs_bdstrat_cb;
+ xfs_buf_delwri_dequeue(bp);
+ return xfs_buf_iostart(bp, XBF_WRITE | XBF_ASYNC | _XBF_RUN_QUEUES);
+ */
+ bawrite(bp);
+ return 0;
+}
+
+static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp)
+{
+ /* this is for io shutdown checking need to do this at some point RMC */
+ /* probably should just change xfs to call a buf write function */
+#if 0 /* RMC */
+ bp->b_strat = xfs_bdstrat_cb;
+ bp->b_fspriv3 = mp;
+ return xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC);
+#endif
+ bdwrite(bp);
+ return 0;
+}
+
+#define xfs_bpin(bp) xfs_buf_pin(bp)
+#define xfs_bunpin(bp) xfs_buf_unpin(bp)
#define xfs_buf_relse(bp) brelse(bp)
#define xfs_bp_mapin(bp) bp_mapin(bp)
@@ -258,32 +312,21 @@ xfs_buf_get_flags(xfs_buftarg_t *, xfs_daddr_t, size_t, int);
#define xfs_incore(xfs_buftarg,blkno,len,lockit) \
incore(&xfs_buftarg->specvp->v_bufobj, blkno);
-#define xfs_biomove(pb, off, len, data, rw) \
- panic("%s:%d: xfs_biomove NI", __FILE__, __LINE__)
+#define xfs_biomove(bp, off, len, data, rw) \
+ xfs_buf_iomove((bp), (off), (len), (data), \
+ ((rw) == XFS_B_WRITE) ? XBRW_WRITE : XBRW_READ)
-#define xfs_biozero(pb, off, len) \
- panic("%s:%d: xfs_biozero NI", __FILE__, __LINE__)
+#define xfs_biozero(bp, off, len) \
+ xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO)
/* already a function xfs_bwrite... fix this */
-#define XFS_bdwrite(bp) bdwrite(bp)
-#define xfs_iowait(bp) bufwait(bp)
-
-#define xfs_binval(buftarg) printf("binval(buftarg.dev) NI\n")
-#define XFS_bflush(buftarg) printf("bflush(buftarg.dev) NI\n")
-
-#define XFS_bdstrat(bp) printf("XFS_bdstrat NI\n")
-
-#define xfs_incore_relse(buftarg,delwri_only,wait) \
- printf("incore_relse(buftarg.dev,delwri_only,wait) NI\n")
-
-#define xfs_incore_match(buftarg,blkno,len,field,value) \
- printf("incore_match(buftarg.dev,blkno,len,field,value) NI \n")
+#define XFS_bdwrite(bp) bdwrite(bp)
+#define xfs_iowait(bp) bufwait(bp)
-void xfs_baread(xfs_buftarg_t *targp, xfs_daddr_t ioff, size_t isize);
+#define XFS_bdstrat(bp) xfs_buf_iorequest(bp)
-extern void pdflush(struct vnode *, uint64_t);
-#define XFS_pdflush(vnode,flags) \
- pdflush(vnode,flags)
+#define xfs_baread(target, rablkno, ralen) \
+ xfs_buf_readahead((target), (rablkno), (ralen), XBF_DONT_BLOCK)
struct xfs_mount;
@@ -291,14 +334,16 @@ int XFS_bwrite(xfs_buf_t *bp);
xfs_buf_t* xfs_buf_get_empty(size_t, xfs_buftarg_t *targ);
xfs_buf_t* xfs_buf_get_noaddr(size_t, xfs_buftarg_t *targ);
void xfs_buf_free(xfs_buf_t *);
-int xfs_buf_iorequest(struct xfs_buf *bp);
-void XFS_freerbuf(xfs_buf_t *bp);
-void XFS_nfreerbuf(xfs_buf_t *bp);
+extern void xfs_bwait_unpin(xfs_buf_t *bp);
+extern xfs_buftarg_t *xfs_alloc_buftarg(struct vnode *, int);
+extern void xfs_free_buftarg(xfs_buftarg_t *, int);
+extern void xfs_wait_buftarg(xfs_buftarg_t *);
+extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
+extern unsigned int xfs_getsize_buftarg(struct xfs_buftarg *);
+extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
-void xfs_bpin(xfs_buf_t *bp);
-void xfs_bunpin(xfs_buf_t *bp);
-int xfs_ispin(xfs_buf_t *bp);
-void xfs_bwait_unpin(xfs_buf_t *bp);
+#define xfs_binval(buftarg) xfs_flush_buftarg(buftarg, 1)
+#define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg, 1)
#endif
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_compat.h b/sys/gnu/fs/xfs/FreeBSD/xfs_compat.h
index d89e38b1593c..a98a7ee571df 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_compat.h
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_compat.h
@@ -42,6 +42,11 @@ typedef unsigned int __u32;
typedef signed long long int __s64;
typedef unsigned long long int __u64;
+/* linus now has sparse which expects big endian or little endian */
+typedef __u16 __be16;
+typedef __u32 __be32;
+typedef __u64 __be64;
+
/*
* Linux types with direct FreeBSD conterparts
*/
@@ -70,6 +75,7 @@ typedef dev_t os_dev_t;
#define BITS_PER_LONG 32
#endif
+#define rol32(x, y) (((x)<<(y))|((x)>>(32-(y))))
/*
* boolean_t is enum on Linux, int on FreeBSD.
* Provide value defines.
@@ -156,10 +162,20 @@ typedef dev_t os_dev_t;
#define max_t(type,x,y) MAX((x),(y))
+typedef struct mtx xfs_mutex_t;
/*
* Cedentials manipulation.
*/
#define current_fsuid(credp) (credp)->cr_uid
#define current_fsgid(credp) (credp)->cr_groups[0]
+#define PAGE_CACHE_SIZE PAGE_SIZE
+
+#define IS_ERR(err) (err)
+
+static inline unsigned long ffz(unsigned long val)
+{
+ return ffsl(~val);
+}
+
#endif /* __XFS_COMPAT_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_dmistubs.c b/sys/gnu/fs/xfs/FreeBSD/xfs_dmistubs.c
index 746747efe7cc..8f0eda17fb2d 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_dmistubs.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_dmistubs.c
@@ -31,7 +31,6 @@
#include "xfs.h"
-#include "xfs_macros.h"
#include "xfs_types.h"
#include "xfs_inum.h"
#include "xfs_log.h"
@@ -51,12 +50,14 @@ nopkg()
return (ENOSYS);
}
+int dmapi_init(void);
int
dmapi_init (void)
{
return (0);
}
+void dmapi_uninit(void);
void
dmapi_uninit (void)
{
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd.h b/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd.h
index 66b7a85aad9e..3a8312ad0c22 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd.h
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd.h
@@ -73,7 +73,6 @@
#include <xfs_fs_subr.h>
#include <xfs_buf.h>
#include <xfs_frw.h>
-#include <xfs_log.h>
/*
* Feature macros (disable/enable)
@@ -85,14 +84,12 @@
#define EVMS_MAJOR 117
#endif
-#define xfs_refcache_size xfs_params.refcache_size.val
-#define xfs_refcache_purge_count xfs_params.refcache_purge.val
#define restricted_chown xfs_params.restrict_chown.val
#define irix_sgid_inherit xfs_params.sgid_inherit.val
#define irix_symlink_mode xfs_params.symlink_mode.val
#define xfs_panic_mask xfs_params.panic_mask.val
#define xfs_error_level xfs_params.error_level.val
-#define xfs_syncd_interval xfs_params.sync_interval.val
+#define xfs_syncd_centisecs xfs_params.syncd_timer.val
#define xfs_probe_dmapi xfs_params.probe_dmapi.val
#define xfs_probe_ioops xfs_params.probe_ioops.val
#define xfs_probe_quota xfs_params.probe_quota.val
@@ -100,9 +97,10 @@
#define xfs_inherit_sync xfs_params.inherit_sync.val
#define xfs_inherit_nodump xfs_params.inherit_nodump.val
#define xfs_inherit_noatime xfs_params.inherit_noatim.val
-#define xfs_flush_interval xfs_params.flush_interval.val
-#define xfs_age_buffer xfs_params.age_buffer.val
-#define xfs_io_bypass xfs_params.io_bypass.val
+#define xfs_buf_timer_centisecs xfs_params.xfs_buf_timer.val
+#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val
+#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
+#define xfs_rotorstep xfs_params.rotorstep.val
#define current_cpu() smp_processor_id()
#define current_pid() (curthread->td_proc->p_pid)
@@ -118,8 +116,20 @@
#define NBPC PAGE_SIZE /* Number of bytes per click */
#define BPCSHIFT PAGE_SHIFT /* LOG2(NBPC) if exact */
+/*
+ * Size of block device i/o is parameterized here.
+ * Currently the system supports page-sized i/o.
+ */
+#define BLKDEV_IOSHIFT BPCSHIFT
+#ifndef BLKDEV_IOSIZE
+#define BLKDEV_IOSIZE (1<<BLKDEV_IOSHIFT)
+#else
+# if NBPC != BLKDEV_IOSIZE
+# error Wrong BLKDEV_IOSIZE
+# endif
+#endif
/* number of BB's per block device block */
-#define BLKDEV_BB BTOBB(BLKDEV_IOSIZE)
+#define BLKDEV_BB BTOBB(BLKDEV_IOSIZE)
/* bytes to clicks */
#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT)
@@ -194,9 +204,13 @@
#define howmany(x, y) (((x)+((y)-1))/(y))
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
-#ifndef __user
-#define __user
-#endif
+#define xfs_sort(a,n,s,fn) qsort(a,n,s,fn)
+
+
+static inline int xfs_itruncate_data(void *ip, xfs_off_t off) {
+ printf ("xfs_itruncate_data NI\n");
+ return 0;
+}
/*
* Juggle IRIX device numbers - still used in ondisk structures
@@ -221,6 +235,12 @@ static inline void xfs_stack_trace(void)
kdb_backtrace();
}
+#define xfs_statvfs_fsid(statp, mp) \
+ ({ \
+ (statp)->f_fsid.val[0] = /*dev2udev(mp->m_dev) */ 1; \
+ (statp)->f_fsid.val[1] = 0; \
+ })
+
/* Move the kernel do_div definition off to one side */
@@ -339,10 +359,4 @@ static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y)
return(x * y);
}
-static inline unsigned long ffz(unsigned long val)
-{
- val = ffsl(~val);
- return val;
-}
-
#endif /* __XFS_FREEBSD__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c b/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c
new file mode 100644
index 000000000000..de5284c5747f
--- /dev/null
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_freebsd_iget.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2006 Russell Cattelan Digital Elves, 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 "xfs_types.h"
+#include "xfs_bit.h"
+#include "xfs_inum.h"
+#include "xfs_log.h"
+#include "xfs_trans.h"
+#include "xfs_sb.h"
+#include "xfs_ag.h"
+#include "xfs_dir.h"
+#include "xfs_dir2.h"
+#include "xfs_dmapi.h"
+#include "xfs_mount.h"
+#include "xfs_alloc_btree.h"
+#include "xfs_bmap_btree.h"
+#include "xfs_ialloc_btree.h"
+#include "xfs_attr_sf.h"
+#include "xfs_dir_sf.h"
+#include "xfs_dir2_sf.h"
+#include "xfs_dinode.h"
+#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
+#include "xfs_quota.h"
+#include "xfs_utils.h"
+#include "xfs_vnode.h"
+
+static int xfs_vn_allocate(xfs_mount_t *, xfs_inode_t *, struct xfs_vnode **);
+
+/*
+ * Look up an inode by number in the given file system.
+ * The inode is looked up in the hash table for the file system
+ * represented by the mount point parameter mp. Each bucket of
+ * the hash table is guarded by an individual semaphore.
+ *
+ * If the inode is found in the hash table, its corresponding vnode
+ * is obtained with a call to vn_get(). This call takes care of
+ * coordination with the reclamation of the inode and vnode. Note
+ * that the vmap structure is filled in while holding the hash lock.
+ * This gives us the state of the inode/vnode when we found it and
+ * is used for coordination in vn_get().
+ *
+ * If it is not in core, read it in from the file system's device and
+ * add the inode into the hash table.
+ *
+ * The inode is locked according to the value of the lock_flags parameter.
+ * This flag parameter indicates how and if the inode's IO lock and inode lock
+ * should be taken.
+ *
+ * mp -- the mount point structure for the current file system. It points
+ * to the inode hash table.
+ * tp -- a pointer to the current transaction if there is one. This is
+ * simply passed through to the xfs_iread() call.
+ * ino -- the number of the inode desired. This is the unique identifier
+ * within the file system for the inode being requested.
+ * lock_flags -- flags indicating how to lock the inode. See the comment
+ * for xfs_ilock() for a list of valid values.
+ * bno -- the block number starting the buffer containing the inode,
+ * if known (as by bulkstat), else 0.
+ */
+int
+xfs_iget(
+ xfs_mount_t *mp,
+ xfs_trans_t *tp,
+ xfs_ino_t ino,
+ uint flags,
+ uint lock_flags,
+ xfs_inode_t **ipp,
+ xfs_daddr_t bno)
+{
+ xfs_ihash_t *ih;
+ xfs_inode_t *ip;
+ xfs_inode_t *iq;
+ xfs_vnode_t *vp;
+ ulong version;
+ int error;
+ /* REFERENCED */
+ int newnode;
+ xfs_chash_t *ch;
+ xfs_chashlist_t *chl, *chlnew;
+ vmap_t vmap;
+ SPLDECL(s);
+
+ XFS_STATS_INC(xs_ig_attempts);
+
+ ih = XFS_IHASH(mp, ino);
+
+again:
+ read_lock(&ih->ih_lock);
+
+ for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) {
+ if (ip->i_ino == ino) {
+ vp = XFS_ITOV(ip);
+ VMAP(vp, vmap);
+ /*
+ * Inode cache hit: if ip is not at the front of
+ * its hash chain, move it there now.
+ * Do this with the lock held for update, but
+ * do statistics after releasing the lock.
+ */
+ if (ip->i_prevp != &ih->ih_next
+ && rwlock_trypromote(&ih->ih_lock)) {
+
+ if ((iq = ip->i_next)) {
+ iq->i_prevp = ip->i_prevp;
+ }
+ *ip->i_prevp = iq;
+ iq = ih->ih_next;
+ iq->i_prevp = &ip->i_next;
+ ip->i_next = iq;
+ ip->i_prevp = &ih->ih_next;
+ ih->ih_next = ip;
+ write_unlock(&ih->ih_lock);
+ } else {
+ read_unlock(&ih->ih_lock);
+ }
+
+ XFS_STATS_INC(xs_ig_found);
+
+ /*
+ * Get a reference to the vnode/inode.
+ * vn_get() takes care of coordination with
+ * the file system inode release and reclaim
+ * functions. If it returns NULL, the inode
+ * has been reclaimed so just start the search
+ * over again. We probably won't find it,
+ * but we could be racing with another cpu
+ * looking for the same inode so we have to at
+ * least look.
+ */
+ if (!(vp = vn_get(vp, &vmap))) {
+ XFS_STATS_INC(xs_ig_frecycle);
+ goto again;
+ }
+
+ if (lock_flags != 0) {
+ ip->i_flags &= ~XFS_IRECLAIM;
+ xfs_ilock(ip, lock_flags);
+ }
+
+ newnode = (ip->i_d.di_mode == 0);
+ if (newnode) {
+ xfs_iocore_inode_reinit(ip);
+ }
+ ip->i_flags &= ~XFS_ISTALE;
+
+ vn_trace_exit(vp, "xfs_iget.found",
+ (inst_t *)__return_address);
+ goto return_ip;
+ }
+ }
+
+ /*
+ * Inode cache miss: save the hash chain version stamp and unlock
+ * the chain, so we don't deadlock in vn_alloc.
+ */
+ XFS_STATS_INC(xs_ig_missed);
+
+ version = ih->ih_version;
+
+ read_unlock(&ih->ih_lock);
+
+ /*
+ * Read the disk inode attributes into a new inode structure and get
+ * a new vnode for it. This should also initialize i_ino and i_mount.
+ */
+ error = xfs_iread(mp, tp, ino, &ip, bno);
+ if (error) {
+ return error;
+ }
+
+ error = xfs_vn_allocate(mp, ip, &vp);
+ if (error) {
+ return error;
+ }
+ vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address);
+
+ xfs_inode_lock_init(ip, vp);
+ xfs_iocore_inode_init(ip);
+
+ if (lock_flags != 0) {
+ xfs_ilock(ip, lock_flags);
+ }
+
+ /*
+ * Put ip on its hash chain, unless someone else hashed a duplicate
+ * after we released the hash lock.
+ */
+ write_lock(&ih->ih_lock);
+
+ if (ih->ih_version != version) {
+ for (iq = ih->ih_next; iq != NULL; iq = iq->i_next) {
+ if (iq->i_ino == ino) {
+ write_unlock(&ih->ih_lock);
+ xfs_idestroy(ip);
+
+ XFS_STATS_INC(xs_ig_dup);
+ goto again;
+ }
+ }
+ }
+
+ /*
+ * These values _must_ be set before releasing ihlock!
+ */
+ ip->i_hash = ih;
+ if ((iq = ih->ih_next)) {
+ iq->i_prevp = &ip->i_next;
+ }
+ ip->i_next = iq;
+ ip->i_prevp = &ih->ih_next;
+ ih->ih_next = ip;
+ ip->i_udquot = ip->i_gdquot = NULL;
+ ih->ih_version++;
+
+ write_unlock(&ih->ih_lock);
+
+ /*
+ * put ip on its cluster's hash chain
+ */
+ ASSERT(ip->i_chash == NULL && ip->i_cprev == NULL &&
+ ip->i_cnext == NULL);
+
+ chlnew = NULL;
+ ch = XFS_CHASH(mp, ip->i_blkno);
+ chlredo:
+ s = mutex_spinlock(&ch->ch_lock);
+ for (chl = ch->ch_list; chl != NULL; chl = chl->chl_next) {
+ if (chl->chl_blkno == ip->i_blkno) {
+
+ /* insert this inode into the doubly-linked list
+ * where chl points */
+ if ((iq = chl->chl_ip)) {
+ ip->i_cprev = iq->i_cprev;
+ iq->i_cprev->i_cnext = ip;
+ iq->i_cprev = ip;
+ ip->i_cnext = iq;
+ } else {
+ ip->i_cnext = ip;
+ ip->i_cprev = ip;
+ }
+ chl->chl_ip = ip;
+ ip->i_chash = chl;
+ break;
+ }
+ }
+
+ /* no hash list found for this block; add a new hash list */
+ if (chl == NULL) {
+ if (chlnew == NULL) {
+ mutex_spinunlock(&ch->ch_lock, s);
+ ASSERT(xfs_chashlist_zone != NULL);
+ chlnew = (xfs_chashlist_t *)
+ kmem_zone_alloc(xfs_chashlist_zone,
+ KM_SLEEP);
+ ASSERT(chlnew != NULL);
+ goto chlredo;
+ } else {
+ ip->i_cnext = ip;
+ ip->i_cprev = ip;
+ ip->i_chash = chlnew;
+ chlnew->chl_ip = ip;
+ chlnew->chl_blkno = ip->i_blkno;
+ chlnew->chl_next = ch->ch_list;
+ ch->ch_list = chlnew;
+ chlnew = NULL;
+ }
+ } else {
+ if (chlnew != NULL) {
+ kmem_zone_free(xfs_chashlist_zone, chlnew);
+ }
+ }
+
+ mutex_spinunlock(&ch->ch_lock, s);
+
+ /*
+ * Link ip to its mount and thread it on the mount's inode list.
+ */
+ XFS_MOUNT_ILOCK(mp);
+ if ((iq = mp->m_inodes)) {
+ ASSERT(iq->i_mprev->i_mnext == iq);
+ ip->i_mprev = iq->i_mprev;
+ iq->i_mprev->i_mnext = ip;
+ iq->i_mprev = ip;
+ ip->i_mnext = iq;
+ } else {
+ ip->i_mnext = ip;
+ ip->i_mprev = ip;
+ }
+ mp->m_inodes = ip;
+
+ XFS_MOUNT_IUNLOCK(mp);
+
+ newnode = 1;
+
+ return_ip:
+ ASSERT(ip->i_df.if_ext_max ==
+ XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t));
+
+ ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) ==
+ ((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0));
+
+ *ipp = ip;
+
+ /*
+ * If we have a real type for an on-disk inode, we can set ops(&unlock)
+ * now. If it's a new inode being created, xfs_ialloc will handle it.
+ */
+ XVFS_INIT_VNODE(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
+
+ return 0;
+}
+
+/*
+ * Special iput for brand-new inodes that are still locked
+ */
+void
+xfs_iput_new(xfs_inode_t *ip,
+ uint lock_flags)
+{
+ xfs_vnode_t *vp = XFS_ITOV(ip);
+
+ vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
+
+ printf("xfs_iput_new: ip %p\n",ip);
+
+ if ((ip->i_d.di_mode == 0)) {
+ ASSERT(!(ip->i_flags & XFS_IRECLAIMABLE));
+ //vn_mark_bad(vp);
+ printf("xfs_iput_new: ip %p di_mode == 0\n",ip);
+ /* mabe call vgone here? RMC */
+ }
+ if (lock_flags)
+ xfs_iunlock(ip, lock_flags);
+
+ ASSERT_VOP_LOCKED(vp->v_vnode, "xfs_iput_new");
+ vput(vp->v_vnode);
+}
+
+extern struct vop_vector xfs_vnops;
+
+static int
+xfs_vn_allocate(xfs_mount_t *mp, xfs_inode_t *ip, struct xfs_vnode **vpp)
+{
+ struct vnode *vp;
+ struct xfs_vnode *vdata;
+ int error;
+
+ /* Use zone allocator here? */
+ vdata = kmem_zalloc(sizeof(*vdata), KM_SLEEP);
+
+ error = getnewvnode("xfs", XVFSTOMNT(XFS_MTOVFS(mp)),
+ &xfs_vnops, &vp);
+ if (error) {
+ kmem_free(vdata, sizeof(*vdata));
+ return (error);
+ }
+
+ vp->v_vnlock->lk_flags |= LK_CANRECURSE;
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
+
+ vp->v_data = (void *)vdata;
+ vdata->v_number= 0;
+ vdata->v_inode = ip;
+ vdata->v_vfsp = XFS_MTOVFS(mp);
+ vdata->v_vnode = vp;
+
+ vn_bhv_head_init(VN_BHV_HEAD(vdata), "vnode");
+
+
+#ifdef CONFIG_XFS_VNODE_TRACING
+ vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
+#endif /* CONFIG_XFS_VNODE_TRACING */
+
+ vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address);
+
+ if (error == 0)
+ *vpp = vdata;
+
+ return (error);
+}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_frw.c b/sys/gnu/fs/xfs/FreeBSD/xfs_frw.c
index 6007d4167c8d..557ef1a52fc8 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_frw.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_frw.c
@@ -1,45 +1,25 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 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
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms 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/
- */
-/*
- * fs/xfs/linux/xfs_lrw.c (Linux Read Write stuff)
+ * 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. See the
+ * GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
@@ -49,23 +29,21 @@
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
#include "xfs_rw.h"
-#include "xfs_refcache.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
#include "xfs_mac.h"
@@ -153,16 +131,17 @@ xfs_inval_cached_trace(
STATIC int
xfs_iozero(
xfs_vnode_t *vp, /* vnode */
- loff_t pos, /* offset in file */
+ xfs_off_t pos, /* offset in file */
size_t count, /* size of data to zero */
- loff_t end_size) /* max file size to set */
+ xfs_off_t end_size) /* max file size to set */
{
+ int status;
+ status = 0; /* XXXKAN: */
#ifdef XXXKAN
unsigned bytes;
struct page *page;
struct address_space *mapping;
char *kaddr;
- int status;
mapping = ip->i_mapping;
do {
@@ -204,68 +183,10 @@ unlock:
if (status)
break;
} while (count);
-
+#endif
return (-status);
-#endif /* XXXKAN */
- return (0);
}
-/*
- * xfs_inval_cached_pages
- *
- * This routine is responsible for keeping direct I/O and buffered I/O
- * somewhat coherent. From here we make sure that we're at least
- * temporarily holding the inode I/O lock exclusively and then call
- * the page cache to flush and invalidate any cached pages. If there
- * are no cached pages this routine will be very quick.
- */
-void
-xfs_inval_cached_pages(
- xfs_vnode_t *vp,
- xfs_iocore_t *io,
- xfs_off_t offset,
- int write,
- int relock)
-{
- xfs_mount_t *mp;
-
- if (!VN_CACHED(vp)) {
- return;
- }
-
- mp = io->io_mount;
-
- /*
- * We need to get the I/O lock exclusively in order
- * to safely invalidate pages and mappings.
- */
- if (relock) {
- XFS_IUNLOCK(mp, io, XFS_IOLOCK_SHARED);
- XFS_ILOCK(mp, io, XFS_IOLOCK_EXCL);
- }
-
- /* Writing beyond EOF creates a hole that must be zeroed */
- if (write && (offset > XFS_SIZE(mp, io))) {
- xfs_fsize_t isize;
-
- XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
- isize = XFS_SIZE(mp, io);
- if (offset > isize) {
- xfs_zero_eof(vp, io, offset, isize, offset);
- }
- XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
- }
-
- xfs_inval_cached_trace(io, offset, -1, ctooff(offtoct(offset)), -1);
- XVOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(offset)), -1, FI_REMAPF_LOCKED);
- if (relock) {
- XFS_ILOCK_DEMOTE(mp, io, XFS_IOLOCK_EXCL);
- }
-}
-
-int
-xfs_read_file(xfs_mount_t *mp, xfs_inode_t *ip, struct uio *uio, int ioflag);
-
ssize_t /* bytes read, or (-) error */
xfs_read(
bhv_desc_t *bdp,
@@ -306,9 +227,9 @@ xfs_read(
return EIO;
}
- if (!(ioflags & IO_ISLOCKED))
- xfs_ilock(ip, XFS_IOLOCK_SHARED);
-#ifdef XXXKAN
+ xfs_ilock(ip, XFS_IOLOCK_SHARED);
+
+#ifdef XXX
if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
!(ioflags & IO_INVIS)) {
int error;
@@ -318,37 +239,15 @@ xfs_read(
error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
uio->uio_offset, size, dmflags, &locktype);
if (error) {
- if (!(ioflags & IO_ISLOCKED))
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
return (error);
}
}
-
- if (unlikely(ioflags & IO_ISDIRECT)) {
- xfs_rw_enter_trace(XFS_DIORD_ENTER, &ip->i_iocore,
- buf, size, *offset, ioflags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
- xfs_off_t pos = uio->uio_offset;
-
- ret = generic_file_direct_IO(READ, file, buf, size, pos);
- if (ret > 0)
- uio->uio_offset = pos + ret;
-
- UPDATE_ATIME(file->f_dentry->d_inode);
-#else
- ret = generic_file_read(file, buf, size, offset);
#endif
- } else {
- xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
- buf, size, *offset, ioflags);
- ret = generic_file_read(file, buf, size, offset);
- }
-#else /* XXXKAN */
+
ret = xfs_read_file(mp, ip, uio, ioflags);
-#endif /* XXXKAN */
- if (!(ioflags & IO_ISLOCKED))
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
XFS_STATS_ADD(xs_read_bytes, ret);
@@ -369,7 +268,6 @@ STATIC int /* error (positive) */
xfs_zero_last_block(
xfs_vnode_t *vp,
xfs_iocore_t *io,
- xfs_off_t offset,
xfs_fsize_t isize,
xfs_fsize_t end_size)
{
@@ -378,19 +276,16 @@ xfs_zero_last_block(
int nimaps;
int zero_offset;
int zero_len;
- int isize_fsb_offset;
int error = 0;
xfs_bmbt_irec_t imap;
- loff_t loff;
- size_t lsize;
+ xfs_off_t loff;
ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0);
- ASSERT(offset > isize);
mp = io->io_mount;
- isize_fsb_offset = XFS_B_FSB_OFFSET(mp, isize);
- if (isize_fsb_offset == 0) {
+ zero_offset = XFS_B_FSB_OFFSET(mp, isize);
+ if (zero_offset == 0) {
/*
* There are no extra bytes in the last block on disk to
* zero, so return.
@@ -401,7 +296,7 @@ xfs_zero_last_block(
last_fsb = XFS_B_TO_FSBT(mp, isize);
nimaps = 1;
error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap,
- &nimaps, NULL);
+ &nimaps, NULL, NULL);
if (error) {
return error;
}
@@ -420,10 +315,8 @@ xfs_zero_last_block(
*/
XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD);
loff = XFS_FSB_TO_B(mp, last_fsb);
- lsize = XFS_FSB_TO_B(mp, 1);
- zero_offset = isize_fsb_offset;
- zero_len = mp->m_sb.sb_blocksize - isize_fsb_offset;
+ zero_len = mp->m_sb.sb_blocksize - zero_offset;
error = xfs_iozero(vp, loff + zero_offset, zero_len, end_size);
@@ -453,20 +346,17 @@ xfs_zero_eof(
{
xfs_fileoff_t start_zero_fsb;
xfs_fileoff_t end_zero_fsb;
- xfs_fileoff_t prev_zero_fsb;
xfs_fileoff_t zero_count_fsb;
xfs_fileoff_t last_fsb;
xfs_extlen_t buf_len_fsb;
- xfs_extlen_t prev_zero_count;
xfs_mount_t *mp;
int nimaps;
int error = 0;
xfs_bmbt_irec_t imap;
- loff_t loff;
- size_t lsize;
ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
+ ASSERT(offset > isize);
mp = io->io_mount;
@@ -474,7 +364,7 @@ xfs_zero_eof(
* First handle zeroing the block on which isize resides.
* We only zero a part of that block so it is handled specially.
*/
- error = xfs_zero_last_block(vp, io, offset, isize, end_size);
+ error = xfs_zero_last_block(vp, io, isize, end_size);
if (error) {
ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@@ -502,13 +392,11 @@ xfs_zero_eof(
}
ASSERT(start_zero_fsb <= end_zero_fsb);
- prev_zero_fsb = NULLFILEOFF;
- prev_zero_count = 0;
while (start_zero_fsb <= end_zero_fsb) {
nimaps = 1;
zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb,
- 0, NULL, 0, &imap, &nimaps, NULL);
+ 0, NULL, 0, &imap, &nimaps, NULL, NULL);
if (error) {
ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@@ -525,10 +413,7 @@ xfs_zero_eof(
* that sits on a hole and sets the page as P_HOLE
* and calls remapf if it is a mapped file.
*/
- prev_zero_fsb = NULLFILEOFF;
- prev_zero_count = 0;
- start_zero_fsb = imap.br_startoff +
- imap.br_blockcount;
+ start_zero_fsb = imap.br_startoff + imap.br_blockcount;
ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
continue;
}
@@ -549,17 +434,15 @@ xfs_zero_eof(
*/
XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
- loff = XFS_FSB_TO_B(mp, start_zero_fsb);
- lsize = XFS_FSB_TO_B(mp, buf_len_fsb);
-
- error = xfs_iozero(vp, loff, lsize, end_size);
+ error = xfs_iozero(vp,
+ XFS_FSB_TO_B(mp, start_zero_fsb),
+ XFS_FSB_TO_B(mp, buf_len_fsb),
+ end_size);
if (error) {
goto out_lock;
}
- prev_zero_fsb = start_zero_fsb;
- prev_zero_count = buf_len_fsb;
start_zero_fsb = imap.br_startoff + buf_len_fsb;
ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
@@ -578,41 +461,43 @@ out_lock:
ssize_t /* bytes written, or (-) error */
xfs_write(
bhv_desc_t *bdp,
- uio_t *uiop,
- int ioflags,
+ uio_t *uio,
+ int ioflag,
cred_t *credp)
{
-#ifdef XXXKAN
xfs_inode_t *xip;
xfs_mount_t *mp;
- ssize_t ret;
+ ssize_t ret = 0;
int error = 0;
xfs_fsize_t isize, new_size;
xfs_fsize_t n, limit;
+ xfs_fsize_t size;
xfs_iocore_t *io;
xfs_vnode_t *vp;
int iolock;
- int eventsent = 0;
+ //int eventsent = 0;
vrwlock_t locktype;
+ xfs_off_t offset_c;
+ xfs_off_t *offset;
+ xfs_off_t pos;
XFS_STATS_INC(xs_write_calls);
vp = BHV_TO_VNODE(bdp);
xip = XFS_BHVTOI(bdp);
- if (size == 0)
- return 0;
-
io = &xip->i_iocore;
mp = io->io_mount;
- xfs_check_frozen(mp, bdp, XFS_FREEZE_WRITE);
-
if (XFS_FORCED_SHUTDOWN(xip->i_mount)) {
return EIO;
}
- if (unlikely(ioflags & IO_ISDIRECT)) {
+ size = uio->uio_resid;
+ pos = offset_c = uio->uio_offset;
+ offset = &offset_c;
+
+ if (unlikely(ioflag & IO_ISDIRECT)) {
if (((__psint_t)buf & BBMASK) ||
(*offset & mp->m_blockmask) ||
(size & mp->m_blockmask)) {
@@ -627,18 +512,18 @@ xfs_write(
locktype = VRWLOCK_WRITE;
}
- if (ioflags & IO_ISLOCKED)
- iolock = 0;
+ iolock = XFS_IOLOCK_EXCL;
+ locktype = VRWLOCK_WRITE;
xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
isize = xip->i_d.di_size;
limit = XFS_MAXIOFFSET(mp);
- if (file->f_flags & O_APPEND)
+ if (ioflag & O_APPEND)
*offset = isize;
-start:
+//start:
n = limit - *offset;
if (n <= 0) {
xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
@@ -652,6 +537,8 @@ start:
io->io_new_size = new_size;
}
+#ifdef RMC
+ /* probably be a long time before if ever that we do dmapi */
if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
!(ioflags & IO_INVIS) && !eventsent)) {
loff_t savedsize = *offset;
@@ -681,6 +568,7 @@ start:
goto start;
}
}
+#endif
/*
* If the offset is beyond the size of the file, we have a couple
@@ -691,7 +579,7 @@ start:
* to zero it out up to the new size.
*/
- if (!(ioflags & IO_ISDIRECT) && (*offset > isize && isize)) {
+ if (!(ioflag & IO_ISDIRECT) && (*offset > isize && isize)) {
error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, *offset,
isize, *offset + size);
if (error) {
@@ -701,6 +589,7 @@ start:
}
xfs_iunlock(xip, XFS_ILOCK_EXCL);
+#if 0
/*
* If we're writing the file then make sure to clear the
* setuid and setgid bits if the process is not being run
@@ -713,33 +602,21 @@ start:
(S_ISGID | S_IXGRP))) &&
!capable(CAP_FSETID)) {
error = xfs_write_clear_setuid(xip);
- if (error) {
+ if (likely(!error))
+ error = -remove_suid(file->f_dentry);
+ if (unlikely(error)) {
xfs_iunlock(xip, iolock);
- return -error;
+ goto out_unlock_mutex;
}
}
+#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
- if ((ssize_t) size < 0) {
- ret = EINVAL;
- goto error;
- }
-
- if (!access_ok(VERIFY_READ, buf, size)) {
- ret = EINVAL;
- goto error;
- }
-#else
-#define do_generic_direct_write(file, buf, size, offset) \
- generic_file_write_nolock(file, buf, size, offset)
-#define do_generic_file_write(file, buf, size, offset) \
- generic_file_write_nolock(file, buf, size, offset)
-#endif
+//retry:
+ if (unlikely(ioflag & IO_ISDIRECT)) {
-retry:
- if (unlikely(ioflags & IO_ISDIRECT)) {
- loff_t pos = *offset;
+#ifdef RMC
+ xfs_off_t pos = *offset;
struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
struct inode *inode = mapping->host;
@@ -753,43 +630,19 @@ retry:
xfs_rw_enter_trace(XFS_DIOWR_ENTER, io, buf, size, pos, ioflags);
ret = generic_file_direct_IO(WRITE, file, (char *)buf, size, pos);
+ xfs_inval_cached_pages(vp, io, pos, 1, 1);
if (ret > 0)
*offset += ret;
+#endif
} else {
xfs_rw_enter_trace(XFS_WRITE_ENTER, io, buf, size, *offset, ioflags);
- ret = do_generic_file_write(file, buf, size, offset);
+ ret = xfs_write_file(xip,uio,ioflag);
}
- if (unlikely(ioflags & IO_INVIS)) {
- /* generic_file_write updates the mtime/ctime but we need
- * to undo that because this I/O was supposed to be
- * invisible.
- */
- struct inode *inode = LINVFS_GET_IP(vp);
- inode->i_mtime = xip->i_d.di_mtime.t_sec;
- inode->i_ctime = xip->i_d.di_ctime.t_sec;
- } else {
- xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- }
-
- if ((ret == -ENOSPC) &&
- DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) &&
- !(ioflags & IO_INVIS)) {
+ xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- xfs_rwunlock(bdp, locktype);
- error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
- DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
- 0, 0, 0); /* Delay flag intentionally unused */
- if (error)
- return -error;
- xfs_rwlock(bdp, locktype);
- *offset = xip->i_d.di_size;
- goto retry;
- }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
-error:
-#endif
+//error:
if (ret <= 0) {
if (iolock)
xfs_rwunlock(bdp, locktype);
@@ -801,27 +654,33 @@ error:
if (*offset > xip->i_d.di_size) {
xfs_ilock(xip, XFS_ILOCK_EXCL);
if (*offset > xip->i_d.di_size) {
+ printf("xfs_write look at doing more here %s:%d\n",__FILE__,__LINE__);
+#ifdef RMC
struct inode *inode = LINVFS_GET_IP(vp);
+ i_size_write(inode, *offset);
+ mark_inode_dirty_sync(inode);
+#endif
xip->i_d.di_size = *offset;
- i_size_write(inode, *offset);
xip->i_update_core = 1;
xip->i_update_size = 1;
- mark_inode_dirty_sync(inode);
}
xfs_iunlock(xip, XFS_ILOCK_EXCL);
}
/* Handle various SYNC-type writes */
- if ((file->f_flags & O_SYNC) || IS_SYNC(file->f_dentry->d_inode)) {
-
+#if 0
+// if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
+#endif
+ if (ioflag & IO_SYNC) {
/*
* If we're treating this as O_DSYNC and we have not updated the
* size, force the log.
*/
+ if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
+ !(xip->i_update_size)) {
+ xfs_inode_log_item_t *iip = xip->i_itemp;
- if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC)
- && !(xip->i_update_size)) {
/*
* If an allocation transaction occurred
* without extending the size, then we have to force
@@ -841,14 +700,8 @@ error:
* all changes affecting the inode are permanent
* when we return.
*/
-
- xfs_inode_log_item_t *iip;
- xfs_lsn_t lsn;
-
- iip = xip->i_itemp;
if (iip && iip->ili_last_lsn) {
- lsn = iip->ili_last_lsn;
- xfs_log_force(mp, lsn,
+ xfs_log_force(mp, iip->ili_last_lsn,
XFS_LOG_FORCE | XFS_LOG_SYNC);
} else if (xfs_ipincount(xip) > 0) {
xfs_log_force(mp, (xfs_lsn_t)0,
@@ -887,27 +740,27 @@ error:
xfs_trans_ihold(tp, xip);
xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp, 0, (xfs_lsn_t)0);
+ error = xfs_trans_commit(tp, 0, NULL);
xfs_iunlock(xip, XFS_ILOCK_EXCL);
}
+ if (error)
+ goto out_unlock_internal;
}
- } /* (ioflags & O_SYNC) */
-
- /*
- * If we are coming from an nfsd thread then insert into the
- * reference cache.
- */
- if (!strcmp(current->comm, "nfsd"))
- xfs_refcache_insert(xip);
-
- /* Drop lock this way - the old refcache release is in here */
- if (iolock)
xfs_rwunlock(bdp, locktype);
+ return ret;
+
+ } /* (ioflags & O_SYNC) */
- return(ret);
-#endif /* XXXKAN */
- return (0);
+out_unlock_internal:
+ xfs_rwunlock(bdp, locktype);
+#if 0
+out_unlock_mutex:
+ if (need_i_mutex)
+ mutex_unlock(&inode->i_mutex);
+#endif
+ //out_nounlocks:
+ return -error;
}
/*
@@ -1007,11 +860,8 @@ xfsbdstrat(
{
ASSERT(mp);
if (!XFS_FORCED_SHUTDOWN(mp)) {
- /* Grio redirection would go here
- * if (XFS_BUF_IS_GRIO(bp)) {
- */
- return xfs_buf_iorequest(bp);
+ xfs_buf_iorequest(bp);
return 0;
}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_frw.h b/sys/gnu/fs/xfs/FreeBSD/xfs_frw.h
index c08abceef176..78d93f9a85d9 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_frw.h
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_frw.h
@@ -98,12 +98,9 @@ extern void xfs_inval_cached_pages(struct xfs_vnode*, struct xfs_iocore *,
xfs_off_t, int, int);
extern ssize_t xfs_read(bhv_desc_t *, uio_t *, int, cred_t *);
extern ssize_t xfs_write(bhv_desc_t *, uio_t *, int, cred_t *);
-
extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
-#define XFS_FSB_TO_DB_IO(io,fsb) \
- (((io)->io_flags & XFS_IOCORE_RT) ? \
- XFS_FSB_TO_BB((io)->io_mount, (fsb)) : \
- XFS_FSB_TO_DADDR((io)->io_mount, (fsb)))
-
+extern int xfs_read_file(struct xfs_mount *mp, struct xfs_inode *ip, struct uio *uio,
+ int ioflag);
+extern int xfs_write_file(struct xfs_inode *, struct uio *, int);
#endif /* __XFS_FRW_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_globals.c b/sys/gnu/fs/xfs/FreeBSD/xfs_globals.c
index 85f34fc222ce..1d4ac8176119 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_globals.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_globals.c
@@ -36,7 +36,6 @@
*/
#include "xfs.h"
-#include "xfs_macros.h"
#include "xfs_types.h"
#include "xfs_bmap_btree.h"
#include "xfs_bit.h"
@@ -53,16 +52,23 @@ xfs_param_t xfs_params = {
.refcache_size = { 0, 128, XFS_REFCACHE_SIZE_MAX },
.refcache_purge = { 0, 32, XFS_REFCACHE_SIZE_MAX },
#endif
- .restrict_chown = { 0, 1, 1 },
- .sgid_inherit = { 0, 0, 1 },
- .symlink_mode = { 0, 0, 1 },
- .panic_mask = { 0, 0, 127 },
- .error_level = { 0, 3, 11 },
- .sync_interval = { 1, 30, 60 },
- .stats_clear = { 0, 0, 1 },
- .inherit_sync = { 0, 1, 1 },
- .inherit_nodump = { 0, 1, 1 },
- .inherit_noatim = { 0, 1, 1 },
+ .restrict_chown = { 0, 1, 1 },
+ .sgid_inherit = { 0, 0, 1 },
+ .symlink_mode = { 0, 0, 1 },
+ .panic_mask = { 0, 0, 127 },
+ .error_level = { 0, 3, 11 },
+ .syncd_timer = { 1*100, 30*100, 7200*100},
+ .probe_dmapi = { 0, 0, 1 },
+ .probe_ioops = { 0, 0, 1 },
+ .probe_quota = { 0, 1, 1 },
+ .stats_clear = { 0, 0, 1 },
+ .inherit_sync = { 0, 1, 1 },
+ .inherit_nodump = { 0, 1, 1 },
+ .inherit_noatim = { 0, 1, 1 },
+ .xfs_buf_timer = { 100/2, 1*100, 30*100 },
+ .xfs_buf_age = { 1*100, 15*100, 7200*100},
+ .inherit_nosym = { 0, 0, 1 },
+ .rotorstep = { 1, 1, 255 },
};
/*
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c b/sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c
index 323a1c09bcef..e668dc1c866e 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_ioctl.c
@@ -1,75 +1,60 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 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
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms 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.
+ * 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. See the
+ * GNU General Public License for more details.
*
- * 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/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
#include "xfs_fs.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_bmap.h"
-#include "xfs_bit.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_rtalloc.h"
-#include "xfs_error.h"
#include "xfs_itable.h"
+#include "xfs_error.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
#include "xfs_mac.h"
#include "xfs_attr.h"
+#include "xfs_bmap.h"
#include "xfs_buf_item.h"
#include "xfs_utils.h"
#include "xfs_dfrag.h"
#include "xfs_fsops.h"
-#ifdef XXXKAN
+#include <sys/file.h>
+#if 1
/*
* ioctl commands that are used by Linux filesystems
*/
@@ -77,6 +62,18 @@
#define XFS_IOC_SETXFLAGS _IOW('f', 2, long)
#define XFS_IOC_GETVERSION _IOR('v', 1, long)
+#undef copy_to_user
+static __inline__ int
+copy_to_user(void *dst, void *src, int len) {
+ memcpy(dst,src,len);
+ return 0;
+}
+#undef copy_from_user
+static __inline__ int
+copy_from_user(void *dst, void *src, int len) {
+ memcpy(dst,src,len);
+ return 0;
+}
/*
* xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
@@ -92,26 +89,31 @@
STATIC int
xfs_find_handle(
unsigned int cmd,
- unsigned long arg)
+ void __user *arg)
{
+#ifdef RMC
int hsize;
+#endif
xfs_handle_t handle;
xfs_fsop_handlereq_t hreq;
- struct xfs_vnode *vp;
- struct thread *td = curthread;
+#ifdef RMC
+ struct inode *inode;
+ xfs_vnode_t *vp;
+#endif
- if (copy_from_user(&hreq, (xfs_fsop_handlereq_t *)arg, sizeof(hreq)))
- return XFS_ERROR(EFAULT);
+ if (copy_from_user(&hreq, arg, sizeof(hreq)))
+ return -XFS_ERROR(EFAULT);
memset((char *)&handle, 0, sizeof(handle));
switch (cmd) {
+#if 0
case XFS_IOC_PATH_TO_FSHANDLE:
case XFS_IOC_PATH_TO_HANDLE: {
struct nameidata nd;
int error;
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ,
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF,
UIO_USERSPACE, hreq.path, td);
error = namei(&nd);
if (error)
@@ -122,6 +124,7 @@ xfs_find_handle(
case XFS_IOC_FD_TO_HANDLE: {
struct file *file;
+ int error;
error = getvnode(td->td_proc->p_fd, hreq.fd, &file);
if (error)
@@ -135,24 +138,31 @@ xfs_find_handle(
fdrop(file);
break;
}
+#endif
default:
ASSERT(0);
return XFS_ERROR(EINVAL);
}
+#ifdef RMC
if (inode->i_sb->s_magic != XFS_SB_MAGIC) {
/* we're not in XFS anymore, Toto */
iput(inode);
return XFS_ERROR(EINVAL);
}
- /* we need the vnode */
- vp = LINVFS_GET_VP(inode);
- if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) {
+ switch (inode->i_mode & S_IFMT) {
+ case S_IFREG:
+ case S_IFDIR:
+ case S_IFLNK:
+ break;
+ default:
iput(inode);
return XFS_ERROR(EBADF);
}
+ /* we need the vnode */
+ vp = vn_from_inode(inode);
/* now we can grab the fsid */
memcpy(&handle.ha_fsid, vp->v_vfsp->vfs_altfsid, sizeof(xfs_fsid_t));
@@ -160,13 +170,10 @@ xfs_find_handle(
if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
xfs_inode_t *ip;
- bhv_desc_t *bhv;
int lock_mode;
/* need to get access to the xfs_inode to read the generation */
- bhv = vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops);
- ASSERT(bhv);
- ip = XFS_BHVTOI(bhv);
+ ip = xfs_vtoi(vp);
ASSERT(ip);
lock_mode = xfs_ilock_map_shared(ip);
@@ -183,13 +190,14 @@ xfs_find_handle(
}
/* now copy our handle into the user buffer & write out the size */
- if (copy_to_user((xfs_handle_t *)hreq.ohandle, &handle, hsize) ||
+ if (copy_to_user(hreq.ohandle, &handle, hsize) ||
copy_to_user(hreq.ohandlen, &hsize, sizeof(__s32))) {
iput(inode);
- return -XFS_ERROR(EFAULT);
+ return XFS_ERROR(EFAULT);
}
iput(inode);
+#endif
return 0;
}
@@ -208,42 +216,29 @@ STATIC int
xfs_vget_fsop_handlereq(
xfs_mount_t *mp,
struct inode *parinode, /* parent inode pointer */
- int cap, /* capability level for op */
- unsigned long arg, /* userspace data pointer */
- unsigned long size, /* size of expected struct */
- /* output arguments */
xfs_fsop_handlereq_t *hreq,
- vnode_t **vp,
+ xfs_vnode_t **vp,
struct inode **inode)
{
- void *hanp;
+#if 0
+ void __user *hanp;
size_t hlen;
xfs_fid_t *xfid;
xfs_handle_t *handlep;
xfs_handle_t handle;
xfs_inode_t *ip;
struct inode *inodep;
- vnode_t *vpp;
+ xfs_vnode_t *vpp;
xfs_ino_t ino;
__u32 igen;
int error;
- if (!capable(cap))
- return XFS_ERROR(EPERM);
-
/*
* Only allow handle opens under a directory.
*/
if (!S_ISDIR(parinode->i_mode))
return XFS_ERROR(ENOTDIR);
- /*
- * Copy the handle down from the user and validate
- * that it looks to be in the correct format.
- */
- if (copy_from_user(hreq, (struct xfs_fsop_handlereq *)arg, size))
- return XFS_ERROR(EFAULT);
-
hanp = hreq->ihandle;
hlen = hreq->ihandlen;
handlep = &handle;
@@ -276,7 +271,7 @@ xfs_vget_fsop_handlereq(
/*
* Get the XFS inode, building a vnode to go with it.
*/
- error = xfs_iget(mp, NULL, ino, XFS_ILOCK_SHARED, &ip, 0);
+ error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
if (error)
return error;
if (ip == NULL)
@@ -287,40 +282,45 @@ xfs_vget_fsop_handlereq(
}
vpp = XFS_ITOV(ip);
- inodep = LINVFS_GET_IP(vpp);
+ inodep = vn_to_inode(vpp);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
*vp = vpp;
*inode = inodep;
+#endif
return 0;
}
STATIC int
xfs_open_by_handle(
xfs_mount_t *mp,
- unsigned long arg,
+ void __user *arg,
struct file *parfilp,
struct inode *parinode)
{
+ int new_fd = 0;
+#if 0
int error;
- int new_fd;
int permflag;
struct file *filp;
struct inode *inode;
struct dentry *dentry;
- vnode_t *vp;
+ xfs_vnode_t *vp;
xfs_fsop_handlereq_t hreq;
- error = xfs_vget_fsop_handlereq(mp, parinode, CAP_SYS_ADMIN, arg,
- sizeof(xfs_fsop_handlereq_t),
- &hreq, &vp, &inode);
+ if (!capable(CAP_SYS_ADMIN))
+ return -XFS_ERROR(EPERM);
+ if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
+ return XFS_ERROR(EFAULT);
+
+ error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &vp, &inode);
if (error)
- return -error;
+ return error;
/* Restrict xfs_open_by_handle to directories & regular files. */
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
iput(inode);
- return -XFS_ERROR(EINVAL);
+ return XFS_ERROR(EINVAL);
}
#if BITS_PER_LONG != 32
@@ -336,18 +336,18 @@ xfs_open_by_handle(
if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
(permflag & FMODE_WRITE) && IS_APPEND(inode)) {
iput(inode);
- return -XFS_ERROR(EPERM);
+ return XFS_ERROR(EPERM);
}
if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
iput(inode);
- return -XFS_ERROR(EACCES);
+ return XFS_ERROR(EACCES);
}
/* Can't write directories. */
if ( S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) {
iput(inode);
- return -XFS_ERROR(EISDIR);
+ return XFS_ERROR(EISDIR);
}
if ((new_fd = get_unused_fd()) < 0) {
@@ -359,7 +359,7 @@ xfs_open_by_handle(
if (dentry == NULL) {
iput(inode);
put_unused_fd(new_fd);
- return -XFS_ERROR(ENOMEM);
+ return XFS_ERROR(ENOMEM);
}
/* Ensure umount returns EBUSY on umounts while this file is open. */
@@ -372,16 +372,17 @@ xfs_open_by_handle(
return -XFS_ERROR(-PTR_ERR(filp));
}
if (inode->i_mode & S_IFREG)
- filp->f_op = &linvfs_invis_file_operations;
+ filp->f_op = &xfs_invis_file_operations;
fd_install(new_fd, filp);
+#endif
return new_fd;
}
STATIC int
xfs_readlink_by_handle(
xfs_mount_t *mp,
- unsigned long arg,
+ void __user *arg,
struct file *parfilp,
struct inode *parinode)
{
@@ -390,20 +391,25 @@ xfs_readlink_by_handle(
struct uio auio;
struct inode *inode;
xfs_fsop_handlereq_t hreq;
- vnode_t *vp;
+ xfs_vnode_t *vp;
__u32 olen;
- error = xfs_vget_fsop_handlereq(mp, parinode, CAP_SYS_ADMIN, arg,
- sizeof(xfs_fsop_handlereq_t),
- &hreq, &vp, &inode);
+ if (!capable(CAP_SYS_ADMIN))
+ return -XFS_ERROR(EPERM);
+ if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
+ return -XFS_ERROR(EFAULT);
+
+ error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &vp, &inode);
if (error)
return -error;
+#if 0
/* Restrict this handle operation to symlinks only. */
if (vp->v_type != VLNK) {
VN_RELE(vp);
return -XFS_ERROR(EINVAL);
}
+#endif
if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) {
VN_RELE(vp);
@@ -418,7 +424,7 @@ xfs_readlink_by_handle(
auio.uio_segflg = UIO_USERSPACE;
auio.uio_resid = olen;
- VOP_READLINK(vp, &auio, IO_INVIS, NULL, error);
+ XVOP_READLINK(vp, &auio, IO_INVIS, NULL, error);
VN_RELE(vp);
return (olen - auio.uio_resid);
@@ -427,32 +433,35 @@ xfs_readlink_by_handle(
STATIC int
xfs_fssetdm_by_handle(
xfs_mount_t *mp,
- unsigned long arg,
+ void __user *arg,
struct file *parfilp,
struct inode *parinode)
{
- int error;
+ int error = 0;
+#if 0
struct fsdmidata fsd;
xfs_fsop_setdm_handlereq_t dmhreq;
struct inode *inode;
bhv_desc_t *bdp;
- vnode_t *vp;
+ xfs_vnode_t *vp;
- error = xfs_vget_fsop_handlereq(mp, parinode, CAP_MKNOD, arg,
- sizeof(xfs_fsop_setdm_handlereq_t),
- (xfs_fsop_handlereq_t *)&dmhreq,
- &vp, &inode);
+ if (!capable(CAP_MKNOD))
+ return XFS_ERROR(EPERM);
+ if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t)))
+ return XFS_ERROR(EFAULT);
+
+ error = xfs_vget_fsop_handlereq(mp, parinode, &dmhreq.hreq, &vp, &inode);
if (error)
- return -error;
+ return error;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
VN_RELE(vp);
- return -XFS_ERROR(EPERM);
+ return XFS_ERROR(EPERM);
}
if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) {
VN_RELE(vp);
- return -XFS_ERROR(EFAULT);
+ return XFS_ERROR(EFAULT);
}
bdp = bhv_base_unlocked(VN_BHV_HEAD(vp));
@@ -460,96 +469,211 @@ xfs_fssetdm_by_handle(
VN_RELE(vp);
if (error)
- return -error;
- return 0;
+ return error;
+#endif
+ return error;
}
STATIC int
xfs_attrlist_by_handle(
xfs_mount_t *mp,
- unsigned long arg,
+ void __user *arg,
struct file *parfilp,
struct inode *parinode)
{
- int error;
+ int error = 0;
+#if 0
attrlist_cursor_kern_t *cursor;
xfs_fsop_attrlist_handlereq_t al_hreq;
struct inode *inode;
- vnode_t *vp;
+ xfs_vnode_t *vp;
+ char *kbuf;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -XFS_ERROR(EPERM);
+ if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
+ return -XFS_ERROR(EFAULT);
+ if (al_hreq.buflen > XATTR_LIST_MAX)
+ return -XFS_ERROR(EINVAL);
- error = xfs_vget_fsop_handlereq(mp, parinode, CAP_SYS_ADMIN, arg,
- sizeof(xfs_fsop_attrlist_handlereq_t),
- (xfs_fsop_handlereq_t *)&al_hreq,
- &vp, &inode);
+ error = xfs_vget_fsop_handlereq(mp, parinode, &al_hreq.hreq,
+ &vp, &inode);
if (error)
- return -error;
+ goto out;
+
+ kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL);
+ if (!kbuf)
+ goto out_vn_rele;
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
- VOP_ATTR_LIST(vp, al_hreq.buffer, al_hreq.buflen, al_hreq.flags,
+ XVOP_ATTR_LIST(vp, kbuf, al_hreq.buflen, al_hreq.flags,
cursor, NULL, error);
+ if (error)
+ goto out_kfree;
+
+ if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
+ error = -EFAULT;
+
+ out_kfree:
+ kfree(kbuf);
+ out_vn_rele:
VN_RELE(vp);
+ out:
+#endif
+ return error;
+}
+
+#if 0
+STATIC int
+xfs_attrmulti_attr_get(
+ xfs_vnode_t *vp,
+ char *name,
+ char __user *ubuf,
+ __uint32_t *len,
+ __uint32_t flags)
+{
+ int error = EFAULT;
+ char *kbuf;
+
+ if (*len > XATTR_SIZE_MAX)
+ return EINVAL;
+ kbuf = kmalloc(*len, GFP_KERNEL);
+ if (!kbuf)
+ return ENOMEM;
+
+ XVOP_ATTR_GET(vp, name, kbuf, len, flags, NULL, error);
if (error)
- return -error;
- return 0;
+ goto out_kfree;
+
+ if (copy_to_user(ubuf, kbuf, *len))
+ error = EFAULT;
+
+ out_kfree:
+ kfree(kbuf);
+ return error;
}
+#endif
+
+#if 0
+STATIC int
+xfs_attrmulti_attr_set(
+ xfs_vnode_t *vp,
+ char *name,
+ const char __user *ubuf,
+ __uint32_t len,
+ __uint32_t flags)
+{
+ int error = EFAULT;
+ char *kbuf;
+
+ if (IS_RDONLY(&vp->v_inode))
+ return -EROFS;
+ if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
+ return EPERM;
+ if (len > XATTR_SIZE_MAX)
+ return EINVAL;
+
+ kbuf = kmalloc(len, GFP_KERNEL);
+ if (!kbuf)
+ return ENOMEM;
+
+ if (copy_from_user(kbuf, ubuf, len))
+ goto out_kfree;
+
+ XVOP_ATTR_SET(vp, name, kbuf, len, flags, NULL, error);
+
+ out_kfree:
+ kfree(kbuf);
+ return error;
+}
+#endif
+
+#if 0
+STATIC int
+xfs_attrmulti_attr_remove(
+ xfs_vnode_t *vp,
+ char *name,
+ __uint32_t flags)
+{
+ int error;
+
+ if (IS_RDONLY(&vp->v_inode))
+ return -EROFS;
+ if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
+ return EPERM;
+
+ XVOP_ATTR_REMOVE(vp, name, flags, NULL, error);
+ return error;
+}
+#endif
STATIC int
xfs_attrmulti_by_handle(
xfs_mount_t *mp,
- unsigned long arg,
+ void __user *arg,
struct file *parfilp,
struct inode *parinode)
{
- int error;
+ int error = 0;
+#if 0
xfs_attr_multiop_t *ops;
xfs_fsop_attrmulti_handlereq_t am_hreq;
struct inode *inode;
- vnode_t *vp;
- int i, size;
+ xfs_vnode_t *vp;
+ unsigned int i, size;
+ char *attr_name;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -XFS_ERROR(EPERM);
+ if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
+ return -XFS_ERROR(EFAULT);
- error = xfs_vget_fsop_handlereq(mp, parinode, CAP_SYS_ADMIN, arg,
- sizeof(xfs_fsop_attrmulti_handlereq_t),
- (xfs_fsop_handlereq_t *)&am_hreq,
- &vp, &inode);
+ error = xfs_vget_fsop_handlereq(mp, parinode, &am_hreq.hreq, &vp, &inode);
if (error)
- return -error;
+ goto out;
+ error = E2BIG;
size = am_hreq.opcount * sizeof(attr_multiop_t);
- ops = (xfs_attr_multiop_t *)kmalloc(size, GFP_KERNEL);
- if (!ops) {
- VN_RELE(vp);
- return -XFS_ERROR(ENOMEM);
- }
+ if (!size || size > 16 * PAGE_SIZE)
+ goto out_vn_rele;
- if (copy_from_user(ops, am_hreq.ops, size)) {
- kfree(ops);
- VN_RELE(vp);
- return -XFS_ERROR(EFAULT);
- }
+ error = ENOMEM;
+ ops = kmalloc(size, GFP_KERNEL);
+ if (!ops)
+ goto out_vn_rele;
+
+ error = EFAULT;
+ if (copy_from_user(ops, am_hreq.ops, size))
+ goto out_kfree_ops;
+
+ attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
+ if (!attr_name)
+ goto out_kfree_ops;
+
+ error = 0;
for (i = 0; i < am_hreq.opcount; i++) {
- switch(ops[i].am_opcode) {
+ ops[i].am_error = strncpy_from_user(attr_name,
+ ops[i].am_attrname, MAXNAMELEN);
+ if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
+ error = -ERANGE;
+ if (ops[i].am_error < 0)
+ break;
+
+ switch (ops[i].am_opcode) {
case ATTR_OP_GET:
- VOP_ATTR_GET(vp,ops[i].am_attrname, ops[i].am_attrvalue,
- &ops[i].am_length, ops[i].am_flags,
- NULL, ops[i].am_error);
+ ops[i].am_error = xfs_attrmulti_attr_get(vp,
+ attr_name, ops[i].am_attrvalue,
+ &ops[i].am_length, ops[i].am_flags);
break;
case ATTR_OP_SET:
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
- ops[i].am_error = EPERM;
- break;
- }
- VOP_ATTR_SET(vp,ops[i].am_attrname, ops[i].am_attrvalue,
- ops[i].am_length, ops[i].am_flags,
- NULL, ops[i].am_error);
+ ops[i].am_error = xfs_attrmulti_attr_set(vp,
+ attr_name, ops[i].am_attrvalue,
+ ops[i].am_length, ops[i].am_flags);
break;
case ATTR_OP_REMOVE:
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
- ops[i].am_error = EPERM;
- break;
- }
- VOP_ATTR_REMOVE(vp, ops[i].am_attrname, ops[i].am_flags,
- NULL, ops[i].am_error);
+ ops[i].am_error = xfs_attrmulti_attr_remove(vp,
+ attr_name, ops[i].am_flags);
break;
default:
ops[i].am_error = EINVAL;
@@ -557,10 +681,15 @@ xfs_attrmulti_by_handle(
}
if (copy_to_user(am_hreq.ops, ops, size))
- error = -XFS_ERROR(EFAULT);
+ error = XFS_ERROR(EFAULT);
+ kfree(attr_name);
+ out_kfree_ops:
kfree(ops);
+ out_vn_rele:
VN_RELE(vp);
+ out:
+#endif
return error;
}
@@ -571,35 +700,35 @@ xfs_attrmulti_by_handle(
STATIC int
xfs_ioc_space(
bhv_desc_t *bdp,
- vnode_t *vp,
+ xfs_vnode_t *vp,
struct file *filp,
int flags,
unsigned int cmd,
- unsigned long arg);
+ void __user *arg);
STATIC int
xfs_ioc_bulkstat(
xfs_mount_t *mp,
unsigned int cmd,
- unsigned long arg);
+ void __user *arg);
STATIC int
xfs_ioc_fsgeometry_v1(
xfs_mount_t *mp,
- unsigned long arg);
+ void __user *arg);
STATIC int
xfs_ioc_fsgeometry(
xfs_mount_t *mp,
- unsigned long arg);
+ void __user *arg);
STATIC int
xfs_ioc_xattr(
- vnode_t *vp,
+ xfs_vnode_t *vp,
xfs_inode_t *ip,
struct file *filp,
unsigned int cmd,
- unsigned long arg);
+ void __user *arg);
STATIC int
xfs_ioc_getbmap(
@@ -607,12 +736,12 @@ xfs_ioc_getbmap(
struct file *filp,
int flags,
unsigned int cmd,
- unsigned long arg);
+ void __user *arg);
STATIC int
xfs_ioc_getbmapx(
bhv_desc_t *bdp,
- unsigned long arg);
+ void __user *arg);
int
xfs_ioctl(
@@ -621,20 +750,36 @@ xfs_ioctl(
struct file *filp,
int ioflags,
unsigned int cmd,
- unsigned long arg)
+ void *arg)
{
int error;
- vnode_t *vp;
+ xfs_vnode_t *vp;
xfs_inode_t *ip;
xfs_mount_t *mp;
- vp = LINVFS_GET_VP(inode);
+// vp = vn_from_inode(inode);
+ vp = BHV_TO_VNODE(bdp);
+
+ printf("xfs_ioctl: bdp %p flags 0x%x cmd 0x%x basecmd 0x%x arg %p\n",
+ bdp, ioflags, cmd,
+ IOCBASECMD(cmd),
+ arg);
+
vn_trace_entry(vp, "xfs_ioctl", (inst_t *)__return_address);
ip = XFS_BHVTOI(bdp);
mp = ip->i_mount;
+
+#if 0
+ if ((cmd << 24 >> 24) == (XFS_IOC_GETBMAPX << 24 >> 24)) {
+ cmd = XFS_IOC_GETBMAPX;
+ }
+#endif
+
+
+
switch (cmd) {
case XFS_IOC_ALLOCSP:
@@ -657,20 +802,15 @@ xfs_ioctl(
case XFS_IOC_DIOINFO: {
struct dioattr da;
+ xfs_buftarg_t *target =
+ (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
+ mp->m_rtdev_targp : mp->m_ddev_targp;
- da.d_miniosz = mp->m_sb.sb_blocksize;
- da.d_mem = mp->m_sb.sb_blocksize;
+ da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
+ da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
- /*
- * this only really needs to be BBSIZE.
- * it is set to the file system block size to
- * avoid having to do block zeroing on short writes.
- */
- da.d_maxiosz = XFS_FSB_TO_B(mp,
- XFS_B_TO_FSBT(mp, KIO_MAX_ATOMIC_IO << 10));
-
- if (copy_to_user((struct dioattr *)arg, &da, sizeof(da)))
- return -XFS_ERROR(EFAULT);
+ if (copy_to_user(arg, &da, sizeof(da)))
+ return XFS_ERROR(EFAULT);
return 0;
}
@@ -696,12 +836,12 @@ xfs_ioctl(
case XFS_IOC_FSSETDM: {
struct fsdmidata dmi;
- if (copy_from_user(&dmi, (struct fsdmidata *)arg, sizeof(dmi)))
- return -XFS_ERROR(EFAULT);
+ if (copy_from_user(&dmi, arg, sizeof(dmi)))
+ return XFS_ERROR(EFAULT);
error = xfs_set_dmattrs(bdp, dmi.fsd_dmevmask, dmi.fsd_dmstate,
NULL);
- return -error;
+ return error;
}
case XFS_IOC_GETBMAP:
@@ -732,8 +872,8 @@ xfs_ioctl(
return xfs_attrmulti_by_handle(mp, arg, filp, inode);
case XFS_IOC_SWAPEXT: {
- error = xfs_swapext((struct xfs_swapext *)arg);
- return -error;
+ error = xfs_swapext((struct xfs_swapext __user *)arg);
+ return error;
}
case XFS_IOC_FSCOUNTS: {
@@ -741,10 +881,10 @@ xfs_ioctl(
error = xfs_fs_counts(mp, &out);
if (error)
- return -error;
+ return error;
- if (copy_to_user((char *)arg, &out, sizeof(out)))
- return -XFS_ERROR(EFAULT);
+ if (copy_to_user(arg, &out, sizeof(out)))
+ return XFS_ERROR(EFAULT);
return 0;
}
@@ -753,19 +893,19 @@ xfs_ioctl(
__uint64_t in;
if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ return EPERM;
- if (copy_from_user(&inout, (char *)arg, sizeof(inout)))
- return -XFS_ERROR(EFAULT);
+ if (copy_from_user(&inout, arg, sizeof(inout)))
+ return XFS_ERROR(EFAULT);
/* input parameter is passed in resblks field of structure */
in = inout.resblks;
error = xfs_reserve_blocks(mp, &in, &inout);
if (error)
- return -error;
+ return error;
- if (copy_to_user((char *)arg, &inout, sizeof(inout)))
- return -XFS_ERROR(EFAULT);
+ if (copy_to_user(arg, &inout, sizeof(inout)))
+ return XFS_ERROR(EFAULT);
return 0;
}
@@ -773,14 +913,14 @@ xfs_ioctl(
xfs_fsop_resblks_t out;
if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ return EPERM;
error = xfs_reserve_blocks(mp, NULL, &out);
if (error)
- return -error;
+ return error;
- if (copy_to_user((char *)arg, &out, sizeof(out)))
- return -XFS_ERROR(EFAULT);
+ if (copy_to_user(arg, &out, sizeof(out)))
+ return XFS_ERROR(EFAULT);
return 0;
}
@@ -789,41 +929,41 @@ xfs_ioctl(
xfs_growfs_data_t in;
if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ return EPERM;
- if (copy_from_user(&in, (char *)arg, sizeof(in)))
- return -XFS_ERROR(EFAULT);
+ if (copy_from_user(&in, arg, sizeof(in)))
+ return XFS_ERROR(EFAULT);
error = xfs_growfs_data(mp, &in);
- return -error;
+ return error;
}
case XFS_IOC_FSGROWFSLOG: {
xfs_growfs_log_t in;
if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ return EPERM;
- if (copy_from_user(&in, (char *)arg, sizeof(in)))
- return -XFS_ERROR(EFAULT);
+ if (copy_from_user(&in, arg, sizeof(in)))
+ return XFS_ERROR(EFAULT);
error = xfs_growfs_log(mp, &in);
- return -error;
+ return error;
}
case XFS_IOC_FSGROWFSRT: {
xfs_growfs_rt_t in;
if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ return EPERM;
- if (copy_from_user(&in, (char *)arg, sizeof(in)))
- return -XFS_ERROR(EFAULT);
+ if (copy_from_user(&in, arg, sizeof(in)))
+ return XFS_ERROR(EFAULT);
error = xfs_growfs_rt(mp, &in);
- return -error;
+ return error;
}
-
+#if 0
case XFS_IOC_FREEZE:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -835,71 +975,83 @@ xfs_ioctl(
return -EPERM;
xfs_fs_thaw(mp);
return 0;
+#endif
case XFS_IOC_GOINGDOWN: {
__uint32_t in;
if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ return EPERM;
- if (get_user(in, (__uint32_t *)arg))
- return -XFS_ERROR(EFAULT);
+ if (copy_from_user(&in, arg, sizeof(__uint32_t)))
+ return XFS_ERROR(EFAULT);
error = xfs_fs_goingdown(mp, in);
- return -error;
+ return error;
}
case XFS_IOC_ERROR_INJECTION: {
xfs_error_injection_t in;
- if (copy_from_user(&in, (char *)arg, sizeof(in)))
- return -XFS_ERROR(EFAULT);
+ if (!capable(CAP_SYS_ADMIN))
+ return EPERM;
+
+ if (copy_from_user(&in, arg, sizeof(in)))
+ return XFS_ERROR(EFAULT);
error = xfs_errortag_add(in.errtag, mp);
- return -error;
+ return error;
}
case XFS_IOC_ERROR_CLEARALL:
+ if (!capable(CAP_SYS_ADMIN))
+ return EPERM;
+
error = xfs_errortag_clearall(mp);
- return -error;
+ return error;
default:
- return -ENOTTY;
+ return ENOTTY;
}
}
STATIC int
xfs_ioc_space(
bhv_desc_t *bdp,
- vnode_t *vp,
+ xfs_vnode_t *vp,
struct file *filp,
int ioflags,
unsigned int cmd,
- unsigned long arg)
+ void __user *arg)
{
xfs_flock64_t bf;
int attr_flags = 0;
int error;
+#if 0
if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
return -XFS_ERROR(EPERM);
- if (filp->f_flags & O_RDONLY)
+ if (!(filp->f_mode & FMODE_WRITE))
return -XFS_ERROR(EBADF);
+#endif
- if (vp->v_type != VREG)
+ if (!VN_ISREG(vp))
return -XFS_ERROR(EINVAL);
- if (copy_from_user(&bf, (xfs_flock64_t *)arg, sizeof(bf)))
+ if (copy_from_user(&bf, arg, sizeof(bf)))
return -XFS_ERROR(EFAULT);
+#if 0
if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
attr_flags |= ATTR_NONBLOCK;
+#endif
if (ioflags & IO_INVIS)
attr_flags |= ATTR_DMI;
- error = xfs_change_file_space(bdp, cmd, &bf, filp->f_pos,
- NULL, attr_flags);
+ error = xfs_change_file_space(bdp, cmd,
+ &bf, filp->f_offset,
+ NULL, attr_flags);
return -error;
}
@@ -907,7 +1059,7 @@ STATIC int
xfs_ioc_bulkstat(
xfs_mount_t *mp,
unsigned int cmd,
- unsigned long arg)
+ void __user *arg)
{
xfs_fsop_bulkreq_t bulkreq;
int count; /* # of records returned */
@@ -918,25 +1070,25 @@ xfs_ioc_bulkstat(
/* done = 1 if there are more stats to get and if bulkstat */
/* should be called again (unused here, but used in dmapi) */
+#if 0
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+#endif
if (XFS_FORCED_SHUTDOWN(mp))
return -XFS_ERROR(EIO);
- if (copy_from_user(&bulkreq, (xfs_fsop_bulkreq_t *)arg,
- sizeof(xfs_fsop_bulkreq_t)))
+ if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t)))
return -XFS_ERROR(EFAULT);
- if (copy_from_user(&inlast, (__s64 *)bulkreq.lastip,
- sizeof(__s64)))
+ if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64)))
return -XFS_ERROR(EFAULT);
if ((count = bulkreq.icount) <= 0)
return -XFS_ERROR(EINVAL);
if (cmd == XFS_IOC_FSINUMBERS)
- error = xfs_inumbers(mp, NULL, &inlast, &count,
+ error = xfs_inumbers(mp, &inlast, &count,
bulkreq.ubuffer);
else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE)
error = xfs_bulkstat_single(mp, &inlast,
@@ -947,7 +1099,7 @@ xfs_ioc_bulkstat(
error = xfs_bulkstat_single(mp, &inlast,
bulkreq.ubuffer, &done);
} else {
- error = xfs_bulkstat(mp, NULL, &inlast, &count,
+ error = xfs_bulkstat(mp, &inlast, &count,
(bulkstat_one_pf)xfs_bulkstat_one, NULL,
sizeof(xfs_bstat_t), bulkreq.ubuffer,
BULKSTAT_FG_QUICK, &done);
@@ -958,12 +1110,11 @@ xfs_ioc_bulkstat(
return -error;
if (bulkreq.ocount != NULL) {
- if (copy_to_user((xfs_ino_t *)bulkreq.lastip, &inlast,
+ if (copy_to_user(bulkreq.lastip, &inlast,
sizeof(xfs_ino_t)))
return -XFS_ERROR(EFAULT);
- if (copy_to_user((__s32 *)bulkreq.ocount, &count,
- sizeof(count)))
+ if (copy_to_user(bulkreq.ocount, &count, sizeof(count)))
return -XFS_ERROR(EFAULT);
}
@@ -973,7 +1124,7 @@ xfs_ioc_bulkstat(
STATIC int
xfs_ioc_fsgeometry_v1(
xfs_mount_t *mp,
- unsigned long arg)
+ void __user *arg)
{
xfs_fsop_geom_v1_t fsgeo;
int error;
@@ -982,7 +1133,7 @@ xfs_ioc_fsgeometry_v1(
if (error)
return -error;
- if (copy_to_user((xfs_fsop_geom_t *)arg, &fsgeo, sizeof(fsgeo)))
+ if (copy_to_user(arg, &fsgeo, sizeof(fsgeo)))
return -XFS_ERROR(EFAULT);
return 0;
}
@@ -990,18 +1141,26 @@ xfs_ioc_fsgeometry_v1(
STATIC int
xfs_ioc_fsgeometry(
xfs_mount_t *mp,
- unsigned long arg)
+ void __user *arg)
{
xfs_fsop_geom_t fsgeo;
int error;
error = xfs_fs_geometry(mp, &fsgeo, 4);
if (error)
- return -error;
+ goto error;
- if (copy_to_user((xfs_fsop_geom_t *)arg, &fsgeo, sizeof(fsgeo)))
- return -XFS_ERROR(EFAULT);
- return 0;
+ printf ("xfs_ioc_fsgeometry: error? %d arg %p\n",error,arg);
+
+#if 0
+ if (copy_to_user(arg, &fsgeo, sizeof(fsgeo)))
+ return XFS_ERROR(EFAULT);
+#endif
+ memcpy(arg, &fsgeo, sizeof(fsgeo));
+
+ printf ("xfs_ioc_fsgeometry: error? %d arg %p\n",error,arg);
+error:
+ return error;
}
/*
@@ -1044,118 +1203,170 @@ xfs_merge_ioc_xflags(
return xflags;
}
+STATIC unsigned int
+xfs_di2lxflags(
+ __uint16_t di_flags)
+{
+ unsigned int flags = 0;
+
+ if (di_flags & XFS_DIFLAG_IMMUTABLE)
+ flags |= LINUX_XFLAG_IMMUTABLE;
+ if (di_flags & XFS_DIFLAG_APPEND)
+ flags |= LINUX_XFLAG_APPEND;
+ if (di_flags & XFS_DIFLAG_SYNC)
+ flags |= LINUX_XFLAG_SYNC;
+ if (di_flags & XFS_DIFLAG_NOATIME)
+ flags |= LINUX_XFLAG_NOATIME;
+ if (di_flags & XFS_DIFLAG_NODUMP)
+ flags |= LINUX_XFLAG_NODUMP;
+ return flags;
+}
+
STATIC int
xfs_ioc_xattr(
- vnode_t *vp,
+ xfs_vnode_t *vp,
xfs_inode_t *ip,
struct file *filp,
unsigned int cmd,
- unsigned long arg)
+ void __user *arg)
{
struct fsxattr fa;
- vattr_t va;
+ struct xfs_vattr *vattr;
int error;
int attr_flags;
unsigned int flags;
+ error = 0;
+ attr_flags = 0;
+
+ vattr = kmem_alloc(sizeof(struct xfs_vattr), KM_SLEEP);
+ if (unlikely(!vattr))
+ return ENOMEM;
+
switch (cmd) {
case XFS_IOC_FSGETXATTR: {
- va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS;
- VOP_GETATTR(vp, &va, 0, NULL, error);
- if (error)
- return -error;
+ vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
+ XFS_AT_NEXTENTS | XFS_AT_PROJID;
+ XVOP_GETATTR(vp, vattr, 0, NULL, error);
+ if (unlikely(error)) {
+ error = error;
+ break;
+ }
- fa.fsx_xflags = va.va_xflags;
- fa.fsx_extsize = va.va_extsize;
- fa.fsx_nextents = va.va_nextents;
+ fa.fsx_xflags = vattr->va_xflags;
+ fa.fsx_extsize = vattr->va_extsize;
+ fa.fsx_nextents = vattr->va_nextents;
+ fa.fsx_projid = vattr->va_projid;
- if (copy_to_user((struct fsxattr *)arg, &fa, sizeof(fa)))
- return -XFS_ERROR(EFAULT);
- return 0;
+ if (copy_to_user(arg, &fa, sizeof(fa))) {
+ error = EFAULT;
+ break;
+ }
+ break;
}
case XFS_IOC_FSSETXATTR: {
- if (copy_from_user(&fa, (struct fsxattr *)arg, sizeof(fa)))
- return -XFS_ERROR(EFAULT);
+ if (copy_from_user(&fa, arg, sizeof(fa))) {
+ error = EFAULT;
+ break;
+ }
attr_flags = 0;
+#if 0
if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
attr_flags |= ATTR_NONBLOCK;
+#endif
- va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE;
- va.va_xflags = fa.fsx_xflags;
- va.va_extsize = fa.fsx_extsize;
+ vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
+ vattr->va_xflags = fa.fsx_xflags;
+ vattr->va_extsize = fa.fsx_extsize;
+ vattr->va_projid = fa.fsx_projid;
- VOP_SETATTR(vp, &va, attr_flags, NULL, error);
- if (!error)
- vn_revalidate(vp); /* update Linux inode flags */
- return -error;
+ XVOP_SETATTR(vp, vattr, attr_flags, NULL, error);
+#if 0
+ if (likely(!error))
+ __vn_revalidate(vp, vattr); /* update flags */
+#endif
+ error = error;
+ break;
}
case XFS_IOC_FSGETXATTRA: {
- va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_ANEXTENTS;
- VOP_GETATTR(vp, &va, 0, NULL, error);
- if (error)
- return -error;
+ vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
+ XFS_AT_ANEXTENTS | XFS_AT_PROJID;
+ XVOP_GETATTR(vp, vattr, 0, NULL, error);
+ if (unlikely(error)) {
+ error = error;
+ break;
+ }
- fa.fsx_xflags = va.va_xflags;
- fa.fsx_extsize = va.va_extsize;
- fa.fsx_nextents = va.va_anextents;
+ fa.fsx_xflags = vattr->va_xflags;
+ fa.fsx_extsize = vattr->va_extsize;
+ fa.fsx_nextents = vattr->va_anextents;
+ fa.fsx_projid = vattr->va_projid;
- if (copy_to_user((struct fsxattr *)arg, &fa, sizeof(fa)))
- return -XFS_ERROR(EFAULT);
- return 0;
+ if (copy_to_user(arg, &fa, sizeof(fa))) {
+ error = EFAULT;
+ break;
+ }
+ break;
}
case XFS_IOC_GETXFLAGS: {
- flags = 0;
- if (ip->i_d.di_flags & XFS_XFLAG_IMMUTABLE)
- flags |= LINUX_XFLAG_IMMUTABLE;
- if (ip->i_d.di_flags & XFS_XFLAG_APPEND)
- flags |= LINUX_XFLAG_APPEND;
- if (ip->i_d.di_flags & XFS_XFLAG_SYNC)
- flags |= LINUX_XFLAG_SYNC;
- if (ip->i_d.di_flags & XFS_XFLAG_NOATIME)
- flags |= LINUX_XFLAG_NOATIME;
- if (ip->i_d.di_flags & XFS_XFLAG_NODUMP)
- flags |= LINUX_XFLAG_NODUMP;
- if (copy_to_user((unsigned int *)arg, &flags, sizeof(flags)))
- return -XFS_ERROR(EFAULT);
- return 0;
+ flags = xfs_di2lxflags(ip->i_d.di_flags);
+ if (copy_to_user(arg, &flags, sizeof(flags)))
+ error = EFAULT;
+ break;
}
case XFS_IOC_SETXFLAGS: {
- if (copy_from_user(&flags, (unsigned int *)arg, sizeof(flags)))
- return -XFS_ERROR(EFAULT);
+ if (copy_from_user(&flags, arg, sizeof(flags))) {
+ error = EFAULT;
+ break;
+ }
if (flags & ~(LINUX_XFLAG_IMMUTABLE | LINUX_XFLAG_APPEND | \
LINUX_XFLAG_NOATIME | LINUX_XFLAG_NODUMP | \
- LINUX_XFLAG_SYNC))
- return -XFS_ERROR(EOPNOTSUPP);
+ LINUX_XFLAG_SYNC)) {
+ error = EOPNOTSUPP;
+ break;
+ }
+#if 0
attr_flags = 0;
if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
attr_flags |= ATTR_NONBLOCK;
+#endif
- va.va_mask = XFS_AT_XFLAGS;
- va.va_xflags = xfs_merge_ioc_xflags(flags, ip->i_d.di_flags);
+ vattr->va_mask = XFS_AT_XFLAGS;
+ vattr->va_xflags = xfs_merge_ioc_xflags(flags,
+ xfs_ip2xflags(ip));
- VOP_SETATTR(vp, &va, attr_flags, NULL, error);
- if (!error)
- vn_revalidate(vp); /* update Linux inode flags */
- return -error;
+ XVOP_SETATTR(vp, vattr, attr_flags, NULL, error);
+#if 0
+ if (likely(!error))
+ __vn_revalidate(vp, vattr); /* update flags */
+#endif
+ error = error;
+ break;
}
+#if 0
case XFS_IOC_GETVERSION: {
- flags = LINVFS_GET_IP(vp)->i_generation;
- if (copy_to_user((unsigned int *)arg, &flags, sizeof(flags)))
- return -XFS_ERROR(EFAULT);
- return 0;
+ flags = vn_to_inode(vp)->i_generation;
+ if (copy_to_user(arg, &flags, sizeof(flags)))
+ error = EFAULT;
+ break;
}
+#endif
default:
- return -ENOTTY;
+ error = ENOTTY;
+ break;
}
+
+ kmem_free(vattr,sizeof(struct xfs_vattr));
+ return error;
}
STATIC int
@@ -1164,13 +1375,13 @@ xfs_ioc_getbmap(
struct file *filp,
int ioflags,
unsigned int cmd,
- unsigned long arg)
+ void __user *arg)
{
struct getbmap bm;
int iflags;
int error;
- if (copy_from_user(&bm, (struct getbmap *)arg, sizeof(bm)))
+ if (copy_from_user(&bm, arg, sizeof(bm)))
return -XFS_ERROR(EFAULT);
if (bm.bmv_count < 2)
@@ -1180,11 +1391,11 @@ xfs_ioc_getbmap(
if (ioflags & IO_INVIS)
iflags |= BMV_IF_NO_DMAPI_READ;
- error = xfs_getbmap(bdp, &bm, (struct getbmap *)arg+1, iflags);
+ error = xfs_getbmap(bdp, &bm, (struct getbmap __user *)arg+1, iflags);
if (error)
return -error;
- if (copy_to_user((struct getbmap *)arg, &bm, sizeof(bm)))
+ if (copy_to_user(arg, &bm, sizeof(bm)))
return -XFS_ERROR(EFAULT);
return 0;
}
@@ -1192,18 +1403,20 @@ xfs_ioc_getbmap(
STATIC int
xfs_ioc_getbmapx(
bhv_desc_t *bdp,
- unsigned long arg)
+ void __user *arg)
{
struct getbmapx bmx;
struct getbmap bm;
int iflags;
int error;
- if (copy_from_user(&bmx, (struct getbmapx *)arg, sizeof(bmx)))
- return -XFS_ERROR(EFAULT);
+ printf("%s:%d\n",__FILE__,__LINE__);
+ if (copy_from_user(&bmx, arg, sizeof(bmx)))
+ return XFS_ERROR(EFAULT);
+ printf("%s:%d\n",__FILE__,__LINE__);
if (bmx.bmv_count < 2)
- return -XFS_ERROR(EINVAL);
+ return XFS_ERROR(EINVAL);
/*
* Map input getbmapx structure to a getbmap
@@ -1214,23 +1427,27 @@ xfs_ioc_getbmapx(
iflags = bmx.bmv_iflags;
if (iflags & (~BMV_IF_VALID))
- return -XFS_ERROR(EINVAL);
+ return XFS_ERROR(EINVAL);
iflags |= BMV_IF_EXTENDED;
- error = xfs_getbmap(bdp, &bm, (struct getbmapx *)arg+1, iflags);
+ printf("%s:%d arg+1 %p arg %p\n",__FILE__,__LINE__,(struct getbmapx __user *)arg+1,arg);
+ error = xfs_getbmap(bdp, &bm, (struct getbmapx __user *)arg+1, iflags);
if (error)
- return -error;
+ return error;
+ printf("%s:%d\n",__FILE__,__LINE__);
GETBMAP_CONVERT(bm, bmx);
- if (copy_to_user((struct getbmapx *)arg, &bmx, sizeof(bmx)))
- return -XFS_ERROR(EFAULT);
+ printf("%s:%d\n",__FILE__,__LINE__);
+ if (copy_to_user(arg, &bmx, sizeof(bmx)))
+ return XFS_ERROR(EFAULT);
+ printf("%s:%d\n",__FILE__,__LINE__);
return 0;
}
-#endif
+#else
int
xfs_ioctl(
@@ -1243,3 +1460,5 @@ xfs_ioctl(
{
return EINVAL;
}
+
+#endif
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_iops.h b/sys/gnu/fs/xfs/FreeBSD/xfs_iops.h
index 20549a793ce4..a30019e552db 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_iops.h
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_iops.h
@@ -56,5 +56,6 @@ typedef struct xattr_namespace {
extern struct xattr_namespace *xfs_namespaces;
extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *,
- int, unsigned int, unsigned long);
+ int, unsigned int, void *);
+
#endif /* __XFS_IOPS_H__ */
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c b/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
index 569e74a77e7a..6bc2cd558c73 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2001,2006 Alexander Kabaev, Russell Cattelan Digital Elves Inc.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -11,8 +39,8 @@
#include <geom/geom_vfs.h>
#include "xfs.h"
-#include "xfs_macros.h"
#include "xfs_types.h"
+#include "xfs_bit.h"
#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_trans.h"
@@ -26,17 +54,16 @@
#include "xfs_bmap_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_btree.h"
-#include "xfs_ialloc.h"
#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
+#include "xfs_ialloc.h"
#include "xfs_inode.h"
#include "xfs_alloc.h"
#include "xfs_rtalloc.h"
#include "xfs_bmap.h"
#include "xfs_error.h"
-#include "xfs_bit.h"
#include "xfs_rw.h"
#include "xfs_quota.h"
#include "xfs_fsops.h"
@@ -54,7 +81,6 @@ static vfs_statfs_t _xfs_statfs;
static vfs_sync_t _xfs_sync;
static vfs_vget_t _xfs_vget;
static vfs_fhtovp_t _xfs_fhtovp;
-static vfs_checkexp_t _xfs_checkexp;
static vfs_vptofh_t _xfs_vptofh;
static vfs_init_t _xfs_init;
static vfs_uninit_t _xfs_uninit;
@@ -168,15 +194,8 @@ _xfs_mount(struct mount *mp,
if (vfs_filteropt(mp->mnt_optnew, xfs_opts))
return (EINVAL);
- if (mp->mnt_flag & MNT_UPDATE) {
- /*
- * XXX: Only support update mounts for NFS export.
- */
- if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0))
- return (0);
- else
- return EOPNOTSUPP;
- }
+ if (mp->mnt_flag & MNT_UPDATE)
+ return (0);
xmp = xfsmount_allocate(mp);
if (xmp == NULL)
@@ -185,10 +204,6 @@ _xfs_mount(struct mount *mp,
if((error = _xfs_param_copyin(mp, td)) != 0)
goto fail;
- /* Force read-only mounts in this branch. */
- XFSTOVFS(xmp)->vfs_flag |= VFS_RDONLY;
- mp->mnt_flag |= MNT_RDONLY;
-
curcred = td->td_ucred;
XVFS_MOUNT(XFSTOVFS(xmp), &xmp->m_args, curcred, error);
if (error)
@@ -198,13 +213,13 @@ _xfs_mount(struct mount *mp,
if (error)
goto fail_unmount;
- ddev = XFS_VFSTOM(XFSTOVFS(xmp))->m_dev;
+ ddev = XFS_VFSTOM(XFSTOVFS(xmp))->m_ddev_targp->dev;
if (ddev->si_iosize_max != 0)
mp->mnt_iosize_max = ddev->si_iosize_max;
if (mp->mnt_iosize_max > MAXPHYS)
mp->mnt_iosize_max = MAXPHYS;
- mp->mnt_flag |= MNT_LOCAL | MNT_RDONLY;
+ mp->mnt_flag |= MNT_LOCAL;
mp->mnt_stat.f_fsid.val[0] = dev2udev(ddev);
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
@@ -269,7 +284,7 @@ _xfs_quotactl(mp, cmd, uid, arg, td)
struct thread *td;
{
printf("xfs_quotactl\n");
- return ENOSYS;
+ return EOPNOTSUPP;
}
static int
@@ -335,17 +350,6 @@ _xfs_fhtovp(mp, fidp, vpp)
}
static int
-_xfs_checkexp(mp, nam, extflagsp, credanonp)
- struct mount *mp;
- struct sockaddr *nam;
- int *extflagsp;
- struct ucred **credanonp;
-{
- printf("xfs_checkexp\n");
- return ENOSYS;
-}
-
-static int
_xfs_vptofh(vp, fhp)
struct vnode *vp;
struct fid *fhp;
@@ -392,15 +396,13 @@ static struct vfsops xfs_fsops = {
.vfs_sync = _xfs_sync,
.vfs_vget = _xfs_vget,
.vfs_fhtovp = _xfs_fhtovp,
- .vfs_checkexp = _xfs_checkexp,
.vfs_vptofh = _xfs_vptofh,
.vfs_init = _xfs_init,
.vfs_uninit = _xfs_uninit,
.vfs_extattrctl = _xfs_extattrctl,
};
-/* XXX: Read-only for now */
-VFS_SET(xfs_fsops, xfs, VFCF_READONLY);
+VFS_SET(xfs_fsops, xfs, 0);
/*
* Copy GEOM VFS functions here to provide a conveniet place to
@@ -456,9 +458,15 @@ xfs_geom_bufwrite(struct buf *bp)
return bufwrite(bp);
}
-struct buf_ops xfs_ops = {
+static int
+xfs_geom_bufsync(struct bufobj *bo, int waitfor, struct thread *td)
+{
+ return bufsync(bo,waitfor,td);
+}
+
+struct buf_ops xfs_bo_ops = {
.bop_name = "XFS",
.bop_write = xfs_geom_bufwrite,
.bop_strategy = xfs_geom_strategy,
- .bop_sync = bufsync,
+ .bop_sync = xfs_geom_bufsync,
};
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_super.c b/sys/gnu/fs/xfs/FreeBSD/xfs_super.c
index b971287b7119..d01ff4e08372 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_super.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_super.c
@@ -1,61 +1,45 @@
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 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
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms 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.
+ * 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. See the
+ * GNU General Public License for more details.
*
- * 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/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
-
-#include "xfs_macros.h"
-#include "xfs_inum.h"
+#include "xfs_bit.h"
#include "xfs_log.h"
#include "xfs_clnt.h"
+#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.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"
+#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_btree.h"
+#include "xfs_ialloc.h"
#include "xfs_bmap.h"
-#include "xfs_bit.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
@@ -67,12 +51,13 @@
#include "xfs_buf_item.h"
#include "xfs_utils.h"
#include "xfs_version.h"
+#include "xfs_buf.h"
#include <geom/geom.h>
#include <geom/geom_vfs.h>
extern struct vop_vector xfs_fifoops;
-extern struct buf_ops xfs_ops;
+extern struct xfs_vnodeops xfs_vnodeops;
__uint64_t
xfs_max_file_offset(
@@ -85,16 +70,16 @@ xfs_max_file_offset(
void
xfs_initialize_vnode(
bhv_desc_t *bdp,
- xfs_vnode_t *vp,
+ xfs_vnode_t *xvp,
bhv_desc_t *inode_bhv,
int unlock)
{
xfs_inode_t *ip = XFS_BHVTOI(inode_bhv);
if (!inode_bhv->bd_vobj) {
- vp->v_vfsp = bhvtovfs(bdp);
- bhv_desc_init(inode_bhv, ip, vp, &xfs_vnodeops);
- bhv_insert(VN_BHV_HEAD(vp), inode_bhv);
+ xvp->v_vfsp = bhvtovfs(bdp);
+ bhv_desc_init(inode_bhv, ip, xvp, &xfs_vnodeops);
+ bhv_insert(VN_BHV_HEAD(xvp), inode_bhv);
}
/*
@@ -103,24 +88,25 @@ xfs_initialize_vnode(
* This is _not_ like the same place in Linux version of
* routine.
*/
- if (vp->v_type != VNON)
- return;
- vp->v_type = IFTOVT(ip->i_d.di_mode);
- vp->v_vnode->v_type = vp->v_type;
+ if (xvp->v_vnode->v_type != VNON)
+ return;
+
+ xvp->v_vnode->v_type = IFTOVT(ip->i_d.di_mode);
- if (vp->v_type == VFIFO)
- vp->v_vnode->v_op = &xfs_fifoops;
+ if (xvp->v_vnode->v_type == VFIFO)
+ xvp->v_vnode->v_op = &xfs_fifoops;
- ASSERT_VOP_LOCKED(vp->v_vnode, "xfs_initialize_vnode");
+ ASSERT_VOP_LOCKED(xvp->v_vnode, "xfs_initialize_vnode");
/* For new inodes we need to set the ops vectors,
* and unlock the inode.
*/
- if (unlock)
- VOP_UNLOCK(vp->v_vnode, 0, curthread);
+ if (ip->i_d.di_mode != 0 && unlock)
+ VOP_UNLOCK(xvp->v_vnode, 0, curthread);
}
+#if 0
struct vnode *
xfs_get_inode(
bhv_desc_t *bdp,
@@ -129,21 +115,7 @@ xfs_get_inode(
{
return NULL;
}
-
-void
-xfs_flush_inode(
- xfs_inode_t *ip)
-{
- printf("xfs_flush_inode NI\n");
-}
-
-void
-xfs_flush_device(
- xfs_inode_t *ip)
-{
- printf("xfs_flush_device NI\n");
- xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
-}
+#endif
/*ARGSUSED*/
int
@@ -217,7 +189,7 @@ xfs_blkdev_get(
}
devvp->v_bufobj.bo_private = cp;
- devvp->v_bufobj.bo_ops = &xfs_ops;
+ devvp->v_bufobj.bo_ops = &xfs_bo_ops;
*bdevp = devvp;
return (0);
@@ -245,70 +217,32 @@ xfs_blkdev_put(
}
void
-xfs_flush_buftarg(
- xfs_buftarg_t *btp)
+xfs_mountfs_check_barriers(xfs_mount_t *mp)
{
- printf("xfs_flush_buftarg NI %p\n",btp);
+ printf("xfs_mountfs_check_barriers NI\n");
}
void
-xfs_free_buftarg(
- xfs_buftarg_t *btp)
-{
- xfs_flush_buftarg(btp);
- kmem_free(btp, sizeof(*btp));
-}
-
-int
-xfs_readonly_buftarg(
- xfs_buftarg_t *btp)
+xfs_flush_inode(
+ xfs_inode_t *ip)
{
- struct g_consumer *cp;
-
- KASSERT(btp->specvp->v_bufobj.bo_ops == &xfs_ops,
- ("Bogus xfs_buftarg_t pointer"));
- cp = btp->specvp->v_bufobj.bo_private;
-
- return (cp->acw == 0);
+ printf("xfs_flush_inode NI\n");
}
void
-xfs_relse_buftarg(
- xfs_buftarg_t *btp)
+xfs_flush_device(
+ xfs_inode_t *ip)
{
- printf("xfs_readonly_buftarg NI %p\n",btp);
+ printf("xfs_flush_device NI\n");
+ xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
}
-unsigned int
-xfs_getsize_buftarg(
- xfs_buftarg_t *btp)
-{
- struct g_consumer *cp;
- cp = btp->specvp->v_bufobj.bo_private;
- return (cp->provider->sectorsize);
-}
void
-xfs_setsize_buftarg(
- xfs_buftarg_t *btp,
- unsigned int blocksize,
- unsigned int sectorsize)
+xfs_blkdev_issue_flush(
+ xfs_buftarg_t *buftarg)
{
- printf("xfs_setsize_buftarg NI %p\n",btp);
-}
-
-xfs_buftarg_t *
-xfs_alloc_buftarg(
- struct vnode *bdev)
-{
- xfs_buftarg_t *btp;
-
- btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
-
- btp->dev = bdev->v_rdev;
- btp->specvp = bdev;
-
- return btp;
+ printf("xfs_blkdev_issue_flush NI\n");
}
int
@@ -322,7 +256,9 @@ init_xfs_fs( void )
vn_init();
xfs_init();
uuid_init();
+#ifdef RMC
vfs_initdmapi();
+#endif
vfs_initquota();
return 0;
@@ -333,7 +269,8 @@ exit_xfs_fs(void)
{
xfs_cleanup();
vfs_exitquota();
+#ifdef RMC
vfs_exitdmapi();
- uuid_cleanup();
+#endif
}
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_super.h b/sys/gnu/fs/xfs/FreeBSD/xfs_super.h
index 2665806ed943..0180451eb742 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_super.h
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_super.h
@@ -1,33 +1,19 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 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
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms 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.
+ * 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. See the
+ * GNU General Public License for more details.
*
- * 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/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_SUPER_H__
#define __XFS_SUPER_H__
@@ -111,24 +97,17 @@ extern __uint64_t xfs_max_file_offset(unsigned int);
extern void xfs_initialize_vnode(bhv_desc_t *, xfs_vnode_t *, bhv_desc_t *, int);
-extern struct vnode * xfs_get_inode( bhv_desc_t *, xfs_ino_t, int);
extern void xfs_flush_inode(struct xfs_inode *);
extern void xfs_flush_device(struct xfs_inode *);
extern int xfs_blkdev_get(struct xfs_mount *, const char *,
struct block_device **);
extern void xfs_blkdev_put(struct block_device *);
+extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
-extern struct xfs_buftarg *xfs_alloc_buftarg(struct vnode *);
-extern void xfs_relse_buftarg(struct xfs_buftarg *);
-extern void xfs_free_buftarg(struct xfs_buftarg *);
-extern void xfs_flush_buftarg(struct xfs_buftarg *);
-extern int xfs_readonly_buftarg(struct xfs_buftarg *);
-extern void xfs_setsize_buftarg(struct xfs_buftarg *, unsigned int, unsigned int);
-extern unsigned int xfs_getsize_buftarg(struct xfs_buftarg *);
+extern struct export_operations xfs_export_operations;
extern int init_xfs_fs(void);
extern void exit_xfs_fs(void);
#endif /* __XFS_SUPER_H__ */
-
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.h b/sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.h
index b4b58b487c45..fa68ff0ca0c2 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.h
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_sysctl.h
@@ -1,35 +1,20 @@
/*
- * Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2001-2005 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
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms 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.
+ * 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. See the
+ * GNU General Public License for more details.
*
- * 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/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#ifndef __XFS_SYSCTL_H__
#define __XFS_SYSCTL_H__
@@ -47,13 +32,12 @@ typedef struct xfs_param {
xfs_sysctl_val_t refcache_size; /* Size of NFS reference cache. */
xfs_sysctl_val_t refcache_purge;/* # of entries to purge each time. */
xfs_sysctl_val_t restrict_chown;/* Root/non-root can give away files.*/
- xfs_sysctl_val_t sgid_inherit; /* Inherit S_ISGID bit if process' GID
- * is not a member of the parent dir
- * GID */
+ xfs_sysctl_val_t sgid_inherit; /* Inherit S_ISGID if process' GID is
+ * not a member of parent dir GID. */
xfs_sysctl_val_t symlink_mode; /* Link creat mode affected by umask */
xfs_sysctl_val_t panic_mask; /* bitmask to cause panic on errors. */
xfs_sysctl_val_t error_level; /* Degree of reporting for problems */
- xfs_sysctl_val_t sync_interval; /* time between sync calls */
+ xfs_sysctl_val_t syncd_timer; /* Interval between xfssyncd wakeups */
xfs_sysctl_val_t stats_clear; /* Reset all XFS statistics to zero. */
xfs_sysctl_val_t probe_dmapi; /* probe for DMAPI module on mount. */
xfs_sysctl_val_t probe_ioops; /* probe for an IO module on mount. */
@@ -61,11 +45,10 @@ typedef struct xfs_param {
xfs_sysctl_val_t inherit_sync; /* Inherit the "sync" inode flag. */
xfs_sysctl_val_t inherit_nodump;/* Inherit the "nodump" inode flag. */
xfs_sysctl_val_t inherit_noatim;/* Inherit the "noatime" inode flag. */
- xfs_sysctl_val_t flush_interval;/* interval between runs of the
- * delwri flush daemon. */
- xfs_sysctl_val_t age_buffer; /* time for buffer to age before
- * we flush it. */
- xfs_sysctl_val_t io_bypass; /* toggle for directio io bypass */
+ xfs_sysctl_val_t xfs_buf_timer; /* Interval between xfsbufd wakeups. */
+ xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */
+ xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */
+ xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */
} xfs_param_t;
/*
@@ -84,14 +67,14 @@ typedef struct xfs_param {
*/
enum {
- XFS_REFCACHE_SIZE = 1,
- XFS_REFCACHE_PURGE = 2,
+ /* XFS_REFCACHE_SIZE = 1 */
+ /* XFS_REFCACHE_PURGE = 2 */
XFS_RESTRICT_CHOWN = 3,
XFS_SGID_INHERIT = 4,
XFS_SYMLINK_MODE = 5,
XFS_PANIC_MASK = 6,
XFS_ERRLEVEL = 7,
- XFS_SYNC_INTERVAL = 8,
+ XFS_SYNCD_TIMER = 8,
XFS_PROBE_DMAPI = 9,
XFS_PROBE_IOOPS = 10,
XFS_PROBE_QUOTA = 11,
@@ -99,9 +82,11 @@ enum {
XFS_INHERIT_SYNC = 13,
XFS_INHERIT_NODUMP = 14,
XFS_INHERIT_NOATIME = 15,
- XFS_FLUSH_INTERVAL = 16,
- XFS_AGE_BUFFER = 17,
- XFS_IO_BYPASS = 18,
+ XFS_BUF_TIMER = 16,
+ XFS_BUF_AGE = 17,
+ /* XFS_IO_BYPASS = 18 */
+ XFS_INHERIT_NOSYM = 19,
+ XFS_ROTORSTEP = 20,
};
extern xfs_param_t xfs_params;
@@ -115,4 +100,3 @@ extern void xfs_sysctl_unregister(void);
#endif /* CONFIG_SYSCTL */
#endif /* __XFS_SYSCTL_H__ */
-
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.c b/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.c
index a621e200ba95..cae7bcffb60f 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.c
@@ -1,38 +1,22 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 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
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms 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.
+ * 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. See the
+ * GNU General Public License for more details.
*
- * 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/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
#include "xfs.h"
#include "xfs_fs.h"
-#include "xfs_macros.h"
#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_clnt.h"
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.h b/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.h
index c16ddcd0310c..ada484997c43 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.h
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_vfs.h
@@ -84,7 +84,7 @@ typedef enum {
#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_UMOUNT 0x0008 /* unmount in progress */
+#define VFS_32BITINODES 0x0008 /* do not use inums above 32 bits */
#define VFS_END 0x0008 /* max flag */
#define SYNC_ATTR 0x0001 /* sync attributes */
@@ -95,6 +95,7 @@ typedef enum {
#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
+#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */
#define IGET_NOALLOC 0x0001 /* vfs_get_inode may return NULL */
@@ -116,6 +117,7 @@ typedef void (*xvfs_init_vnode_t)(bhv_desc_t *,
struct xfs_vnode *, bhv_desc_t *, int);
typedef void (*xvfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
typedef struct inode * (*xvfs_get_inode_t)(bhv_desc_t *, xfs_ino_t, int);
+typedef void (*xvfs_freeze_t)(bhv_desc_t *);
typedef struct xvfsops {
bhv_position_t xvfs_position; /* behavior chain position */
@@ -133,6 +135,7 @@ typedef struct xvfsops {
xvfs_get_inode_t xvfs_get_inode; /* bhv specific iget */
xvfs_init_vnode_t xvfs_init_vnode; /* initialize a new vnode */
xvfs_force_shutdown_t xvfs_force_shutdown; /* crash and burn */
+ xvfs_freeze_t xvfs_freeze; /* freeze fs for snapshot */
} xvfsops_t;
/*
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.c b/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.c
index ac85f877f093..0d245c65613d 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.c
@@ -31,8 +31,8 @@
*/
#include "xfs.h"
-#include "xfs_macros.h"
#include "xfs_types.h"
+#include "xfs_bit.h"
#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_trans.h"
@@ -49,19 +49,26 @@
#include "xfs_btree.h"
#include "xfs_imap.h"
#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
+#include "xfs_ialloc.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
void
vn_init(void)
{
}
+void
+vn_iowait(
+ struct xfs_vnode *vp)
+{
+ printf("vn_iowait doing nothing on FreeBSD?\n");
+}
+
struct xfs_vnode *
vn_initialize(
xfs_vnode_t *vp)
@@ -120,44 +127,94 @@ vn_get(
* get a handle (via vn_get) on the vnode (usually done via a mount/vfs lock).
*/
void
-vn_purge(
- struct xfs_vnode *xfs_vp,
- vmap_t *vmap)
+vn_purge(struct xfs_vnode *xfs_vp)
{
- struct vnode *vp;
+ struct vnode *vp;
- vn_trace_entry(vp, "vn_purge", (inst_t *)__return_address);
+ vn_trace_entry(vp, "vn_purge", (inst_t *)__return_address);
- vp = vmap->v_vp;
+ vp = xfs_vp->v_vnode;
- vn_lock(vp, LK_EXCLUSIVE, curthread);
+ vn_lock(vp, LK_EXCLUSIVE, curthread);
+ if (vp->v_holdcnt == 0)
+ vhold(vp);
vgone(vp);
- VOP_UNLOCK(vp, 0, curthread);
- vdrop(vp);
+ VOP_UNLOCK(vp, 0, curthread);
+}
+
+void xfs_ichgtime(
+ xfs_inode_t *ip,
+ int flags)
+{
+ timespec_t tv;
+
+ vfs_timestamp(&tv);
+ if (flags & XFS_ICHGTIME_MOD) {
+ 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) {
+ 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) {
+ ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec;
+ ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec;
+ }
+
+//printf ("xfs_ichgtime NI\n");
+
}
+
+/*
+ * Bring the atime in the XFS inode uptodate.
+ * Used before logging the inode to disk or when the Linux inode goes away.
+ */
+
/*
- * Finish the removal of a vnode.
+ * It's unclear if we need this since this is for syncing the linux inode's atime
+ * to the xfs inode's atime.
+ * Since FreeBSD doesn't have atime in the vnode is there anything to really
+ * sync over?
+ * For now just make this a update atime call
*/
+
void
-vn_remove(
- struct xfs_vnode *vp)
+xfs_synchronize_atime(
+ xfs_inode_t *ip)
+{
+#if 0
+ xfs_vnode_t *vp;
+#endif
+
+ timespec_t tv;
+
+/* vfs_timestamp looks at the system time accuracy variable */
+ vfs_timestamp(&tv);
+#if 0
+ printf("xfs_synchronize_atime old (%d,%d) new (%d,%ld)\n",
+ ip->i_d.di_atime.t_sec,
+ ip->i_d.di_atime.t_nsec,
+ tv.tv_sec,
+ tv.tv_nsec);
+#endif
+
+ ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec;
+ ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec;
+}
+
+#ifdef RMC
+/*
+ * Extracting atime values in various formats
+ */
+void vn_atime_to_bstime(struct xfs_vnode *vp, xfs_bstime_t *bs_atime)
{
- vmap_t vmap;
-
- /* Make sure we don't do this to the same vnode twice */
- if (!(vp->v_fbhv))
- return;
-
- XFS_STATS_INC(vn_remove);
- vn_trace_exit(vp, "vn_remove", (inst_t *)__return_address);
- /*
- * After the following purge the vnode
- * will no longer exist.
- */
- VMAP(vp, vmap);
- vn_purge(vp, &vmap);
+ bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
+ bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
+ printf("vn_atime_to_bstime NI\n");
}
+#endif
#ifdef CONFIG_XFS_VNODE_TRACING
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.h b/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.h
index d224cb86a0c0..b173442a3d45 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.h
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_vnode.h
@@ -63,7 +63,6 @@
#include <sys/namei.h>
struct xfs_iomap;
-typedef xfs_ino_t vnumber_t;
typedef struct componentname vname_t;
typedef bhv_head_t vn_bhv_head_t;
@@ -74,9 +73,8 @@ typedef bhv_head_t vn_bhv_head_t;
*/
typedef struct xfs_vnode {
__u32 v_flag; /* vnode flags (see below) */
- enum vtype v_type; /* vnode type */
struct xfs_vfs *v_vfsp; /* ptr to containing VFS */
- vnumber_t v_number; /* in-core vnode number */
+ xfs_ino_t v_number; /* in-core vnode number */
vn_bhv_head_t v_bh; /* behavior head */
struct vnode *v_vnode; /* FreeBSD vnode */
struct xfs_inode *v_inode; /* XFS inode */
@@ -85,6 +83,15 @@ typedef struct xfs_vnode {
#endif
} xfs_vnode_t;
+
+/* vnode types */
+#define VN_ISLNK(vp) ((vp)->v_vnode->v_type & VLNK)
+#define VN_ISREG(vp) ((vp)->v_vnode->v_type & VREG)
+#define VN_ISDIR(vp) ((vp)->v_vnode->v_type & VDIR)
+#define VN_ISCHR(vp) ((vp)->v_vnode->v_type & VCHR)
+#define VN_ISBLK(vp) ((vp)->v_vnode->v_type & VBLK)
+#define VN_BAD(vp) ((vp)->v_vnode->v_type & VBAD)
+
#define v_fbhv v_bh.bh_first /* first behavior */
#define v_fops v_bh.bh_first->bd_ops /* first behavior ops */
@@ -126,19 +133,6 @@ typedef enum {
#define LINVFS_GET_VP(inode) ((xfs_vnode_t *)NULL)
#define LINVFS_GET_IP(vp) ((xfs_inode_t *)NULL)
-#ifndef __FreeBSD__
-/*
- * Convert between vnode types and inode formats (since POSIX.1
- * defines mode word of stat structure in terms of inode formats).
- */
-extern enum vtype iftovt_tab[];
-extern u_short vttoif_tab[];
-#define IFTOVT(mode) (iftovt_tab[((mode) & S_IFMT) >> 12])
-#define VTTOIF(indx) (vttoif_tab[(int)(indx)])
-#define MAKEIMODE(indx, mode) (int)(VTTOIF(indx) | (mode))
-#endif
-
-
/*
* Vnode flags.
*/
@@ -188,7 +182,7 @@ typedef int (*xfs_vop_open_t)(bhv_desc_t *, struct cred *);
typedef ssize_t (*xfs_vop_read_t)(bhv_desc_t *, uio_t *, int, struct cred *);
typedef ssize_t (*xfs_vop_write_t)(bhv_desc_t *, uio_t *, int, struct cred *);
typedef int (*xfs_vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
- int, unsigned int, unsigned long);
+ int, unsigned int, void *);
typedef int (*xfs_vop_getattr_t)(bhv_desc_t *, struct xfs_vattr *, int,
struct cred *);
typedef int (*xfs_vop_setattr_t)(bhv_desc_t *, struct xfs_vattr *, int,
@@ -198,7 +192,7 @@ typedef int (*xfs_vop_lookup_t)(bhv_desc_t *, vname_t *, xfs_vnode_t **,
int, xfs_vnode_t *, struct cred *);
typedef int (*xfs_vop_create_t)(bhv_desc_t *, vname_t *, struct xfs_vattr *,
xfs_vnode_t **, struct cred *);
-typedef int (*xfs_vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *);
+typedef int (*xfs_vop_remove_t)(bhv_desc_t *, bhv_desc_t *, vname_t *, struct cred *);
typedef int (*xfs_vop_link_t)(bhv_desc_t *, xfs_vnode_t *, vname_t *,
struct cred *);
typedef int (*xfs_vop_rename_t)(bhv_desc_t *, vname_t *, xfs_vnode_t *, vname_t *,
@@ -378,7 +372,7 @@ typedef struct xfs_vnodeops {
*/
#define IO_ISDIRECT IO_DIRECT /* bypass page cache */
#define IO_INVIS 0x02000 /* don't update inode timestamps */
-#define IO_ISLOCKED 0x04000 /* don't do inode locking */
+/* #define IO_ISLOCKED 0x04000 don't do inode locking, strictly a CXFS thing */
/*
* Flags for VOP_IFLUSH call
@@ -404,7 +398,6 @@ typedef struct xfs_vnodeops {
*/
typedef struct xfs_vattr {
int va_mask; /* bit-mask of attributes present */
- enum vtype va_type; /* vnode type (for create) */
mode_t va_mode; /* file access mode and type */
nlink_t va_nlink; /* number of references to file */
uid_t va_uid; /* owner user id */
@@ -496,10 +489,11 @@ typedef struct xfs_vattr {
* Check whether mandatory file locking is enabled.
*/
#define MANDLOCK(vp, mode) \
- ((vp)->v_type == VREG && ((mode) & (VSGID|(VEXEC>>3))) == VSGID)
+ ((vp)->v_vnode->v_type == VREG && ((mode) & (VSGID|(VEXEC>>3))) == VSGID)
-extern void vn_init(void);
-extern int vn_wait(struct xfs_vnode *);
+extern void vn_init(void);
+extern int vn_wait(struct xfs_vnode *);
+extern void vn_iowait(struct xfs_vnode *);
extern xfs_vnode_t *vn_initialize(struct xfs_vnode *);
/*
@@ -525,16 +519,17 @@ typedef struct vnode_map {
struct vnode *v_vp;
} vmap_t;
+#if 1
#define VMAP(vp, vmap) {(vmap).v_vfsp = (vp)->v_vfsp; \
(vmap).v_vp = (vp)->v_vnode; \
(vmap).v_ino = (vp)->v_inode->i_ino;\
vhold((vp)->v_vnode); \
}
+#endif
-extern void vn_purge(struct xfs_vnode *, vmap_t *);
+extern void vn_purge(struct xfs_vnode *);
extern xfs_vnode_t *vn_get(struct xfs_vnode *, vmap_t *);
extern int vn_revalidate(struct xfs_vnode *);
-extern void vn_remove(struct xfs_vnode *);
static inline int vn_count(struct xfs_vnode *vp)
{
@@ -604,6 +599,7 @@ static __inline__ void vn_flagclr(struct xfs_vnode *vp, __u32 flag)
#define VMODIFY(vp) VN_FLAGSET(vp, VMODIFIED)
#define VUNMODIFY(vp) VN_FLAGCLR(vp, VMODIFIED)
+
/*
* Flags to VOP_SETATTR/VOP_GETATTR.
*/
@@ -611,6 +607,8 @@ static __inline__ void vn_flagclr(struct xfs_vnode *vp, __u32 flag)
#define ATTR_DMI 0x08 /* invocation from a DMI function */
#define ATTR_LAZY 0x80 /* set/get attributes lazily */
#define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */
+#define ATTR_NOLOCK 0x200 /* Don't grab any conflicting locks */
+#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
/*
* Flags to VOP_FSYNC and VOP_RECLAIM.
@@ -620,6 +618,27 @@ static __inline__ void vn_flagclr(struct xfs_vnode *vp, __u32 flag)
#define FSYNC_INVAL 0x2 /* flush and invalidate cached data */
#define FSYNC_DATA 0x4 /* synchronous fsync of data only */
+
+static inline struct xfs_vnode *vn_grab(struct xfs_vnode *vp)
+{
+ printf("vn_grab NI\n");
+// struct inode *inode = igrab(vn_to_inode(vp));
+// return inode ? vn_from_inode(inode) : NULL;
+ return NULL;
+}
+
+static inline void vn_atime_to_bstime(struct xfs_vnode *vp, xfs_bstime_t *bs_atime)
+{
+ printf("%s NI\n", __func__);
+// bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
+// bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
+}
+
+static inline void vn_atime_to_timespec(struct xfs_vnode *vp, struct timespec *ts)
+{
+// *ts = vp->v_vnode->va_atime;
+}
+
/*
* Tracking vnode activity.
*/
@@ -638,6 +657,8 @@ extern void vn_trace_hold(struct xfs_vnode *, char *, int, inst_t *);
extern void vn_trace_ref(struct xfs_vnode *, char *, int, inst_t *);
extern void vn_trace_rele(struct xfs_vnode *, char *, int, inst_t *);
+
+
#define VN_TRACE(vp) \
vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)
#else
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c b/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
index dc9f6f698834..f2bd91105689 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2001, Alexander Kabaev
+ * Copyright (c) 2006, Russell Cattelan Digital Elves Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,7 +37,6 @@
#include <sys/dirent.h>
#include <sys/ioccom.h>
#include <sys/malloc.h>
-#include <sys/extattr.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -49,8 +49,8 @@
#define NO_VFS_MACROS
#include "xfs.h"
-#include "xfs_macros.h"
#include "xfs_types.h"
+#include "xfs_bit.h"
#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_trans.h"
@@ -66,15 +66,14 @@
#include "xfs_ialloc_btree.h"
#include "xfs_btree.h"
#include "xfs_imap.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr.h"
#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
-#include "xfs_inode_item.h"
+#include "xfs_ialloc.h"
+#include "xfs_alloc.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
#include "xfs_mac.h"
@@ -93,11 +92,9 @@ static vop_close_t _xfs_close;
static vop_create_t _xfs_create;
static vop_fsync_t _xfs_fsync;
static vop_getattr_t _xfs_getattr;
-static vop_getextattr_t _xfs_getextattr;
static vop_inactive_t _xfs_inactive;
static vop_ioctl_t _xfs_ioctl;
static vop_link_t _xfs_link;
-static vop_listextattr_t _xfs_listextattr;
static vop_mkdir_t _xfs_mkdir;
static vop_mknod_t _xfs_mknod;
static vop_open_t _xfs_open;
@@ -123,11 +120,9 @@ struct vop_vector xfs_vnops = {
.vop_create = _xfs_create,
.vop_fsync = _xfs_fsync,
.vop_getattr = _xfs_getattr,
- .vop_getextattr = _xfs_getextattr,
.vop_inactive = _xfs_inactive,
.vop_ioctl = _xfs_ioctl,
.vop_link = _xfs_link,
- .vop_listextattr = _xfs_listextattr,
.vop_lookup = vfs_cache_lookup,
.vop_mkdir = _xfs_mkdir,
.vop_mknod = _xfs_mknod,
@@ -230,18 +225,20 @@ _xfs_getattr(
struct mount *mp;
xfs_vattr_t va;
int error;
-
+ /* extract the xfs vnode from the private data */
+ //xfs_vnode_t *xvp = (xfs_vnode_t *)vp->v_data;
VATTR_NULL(vap);
memset(&va,0,sizeof(xfs_vattr_t));
va.va_mask = XFS_AT_STAT|XFS_AT_GENCOUNT|XFS_AT_XFLAGS;
XVOP_GETATTR(VPTOXFSVP(vp), &va, 0, ap->a_cred, error);
- if (error) return (error);
+ if (error)
+ return (error);
mp = vp->v_mount;
- vap->va_type = va.va_type;
+ vap->va_type = IFTOVT(((xfs_vnode_t *)vp->v_data)->v_inode->i_d.di_mode);
vap->va_mode = va.va_mode;
vap->va_nlink = va.va_nlink;
vap->va_uid = va.va_uid;
@@ -294,11 +291,13 @@ _xfs_setattr(
/*
* Check for unsettable attributes.
*/
+#ifdef RMC
if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
(vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
(vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL))
return (EINVAL);
+#endif
memset(&va, 0, sizeof(va));
@@ -377,9 +376,6 @@ _xfs_read(
}
int
-xfs_read_file(xfs_mount_t *mp, xfs_inode_t *ip, struct uio *uio, int ioflag);
-
-int
xfs_read_file(xfs_mount_t *mp, xfs_inode_t *ip, struct uio *uio, int ioflag)
{
xfs_fileoff_t lbn, nextlbn;
@@ -553,11 +549,164 @@ _xfs_write(struct vop_write_args /* {
} */ *ap)
{
struct vnode *vp = ap->a_vp;
-/* struct uio *uio = ap->a_uio; */
+ struct uio *uio = ap->a_uio;
+ int ioflag = ap->a_ioflag;
+ int error;
- if (vp->v_type != VREG)
- return (EPERM);
- return (EPERM);
+ xfs_vnode_t *xvp = (xfs_vnode_t *)vp->v_data;
+
+ error = xfs_write(xvp->v_bh.bh_first, uio, ioflag, ap->a_cred);
+
+ if (error < 0) {
+ printf("Xfs_write got error %d\n",error);
+ return -error;
+ }
+ return 0;
+}
+
+
+int
+xfs_write_file(xfs_inode_t *xip, struct uio *uio, int ioflag)
+{
+ struct buf *bp;
+ //struct thread *td;
+ daddr_t lbn;
+ off_t osize = 0;
+ off_t offset= 0;
+ int blkoffset, error, resid, xfersize;
+ int fsblocksize;
+ int seqcount;
+ xfs_iomap_t iomap;
+ int maps = 1;
+
+ xfs_vnode_t *xvp = XFS_ITOV(xip);
+ struct vnode *vp = xvp->v_vnode;
+
+ xfs_mount_t *mp = (&xip->i_iocore)->io_mount;
+
+ seqcount = ioflag >> IO_SEQSHIFT;
+
+ memset(&iomap,0,sizeof(xfs_iomap_t));
+
+ /*
+ * Maybe this should be above the vnode op call, but so long as
+ * file servers have no limits, I don't think it matters.
+ */
+#if 0
+ td = uio->uio_td;
+ if (vp->v_type == VREG && td != NULL) {
+ PROC_LOCK(td->td_proc);
+ if (uio->uio_offset + uio->uio_resid >
+ lim_cur(td->td_proc, RLIMIT_FSIZE)) {
+ psignal(td->td_proc, SIGXFSZ);
+ PROC_UNLOCK(td->td_proc);
+ return (EFBIG);
+ }
+ PROC_UNLOCK(td->td_proc);
+ }
+#endif
+
+ resid = uio->uio_resid;
+ offset = uio->uio_offset;
+ osize = xip->i_d.di_size;
+
+ /* xfs bmap wants bytes for both offset and size */
+ XVOP_BMAP(xvp,
+ uio->uio_offset,
+ uio->uio_resid,
+ BMAPI_WRITE|BMAPI_DIRECT,
+ &iomap, &maps, error);
+ if(error) {
+ printf("XVOP_BMAP failed\n");
+ goto error;
+ }
+
+ for (error = 0; uio->uio_resid > 0;) {
+
+ lbn = XFS_B_TO_FSBT(mp, offset);
+ blkoffset = XFS_B_FSB_OFFSET(mp, offset);
+ xfersize = mp->m_sb.sb_blocksize - blkoffset;
+ fsblocksize = mp->m_sb.sb_blocksize;
+
+ if (uio->uio_resid < xfersize)
+ xfersize = uio->uio_resid;
+
+ /*
+ * getblk sets buf by blkno * bo->bo_bsize
+ * bo_bsize is set from the mnt point fsize
+ * so we call getblk in the case using fsblocks
+ * not basic blocks
+ */
+
+ bp = getblk(vp, lbn, fsblocksize, 0, 0, 0);
+ if(!bp) {
+ printf("getblk failed\n");
+ error = EINVAL;
+ break;
+ }
+
+ if (!(bp->b_flags & B_CACHE) && fsblocksize > xfersize)
+ vfs_bio_clrbuf(bp);
+
+ if (offset + xfersize > xip->i_d.di_size) {
+ xip->i_d.di_size = offset + xfersize;
+ vnode_pager_setsize(vp, offset + fsblocksize);
+ }
+
+ /* move the offset for the next itteration of the loop */
+ offset += xfersize;
+
+ error = uiomove((char *)bp->b_data + blkoffset, xfersize, uio);
+
+ if ((ioflag & IO_VMIO) &&
+ (LIST_FIRST(&bp->b_dep) == NULL)) /* in ext2fs? */
+ bp->b_flags |= B_RELBUF;
+
+ /* force to full direct for now */
+ bp->b_flags |= B_DIRECT;
+ /* and sync ... the delay path is not pushing data out */
+ ioflag |= IO_SYNC;
+
+ if (ioflag & IO_SYNC) {
+ (void)bwrite(bp);
+ } else if (0 /* RMC xfersize + blkoffset == fs->s_frag_size */) {
+ if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0) {
+ bp->b_flags |= B_CLUSTEROK;
+ cluster_write(vp, bp, osize, seqcount);
+ } else {
+ bawrite(bp);
+ }
+ } else {
+ bp->b_flags |= B_CLUSTEROK;
+ bdwrite(bp);
+ }
+ if (error || xfersize == 0)
+ break;
+ }
+ /*
+ * If we successfully wrote any data, and we are not the superuser
+ * we clear the setuid and setgid bits as a precaution against
+ * tampering.
+ */
+#if 0
+ if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0)
+ ip->i_mode &= ~(ISUID | ISGID);
+#endif
+ if (error) {
+ if (ioflag & IO_UNIT) {
+#if 0
+ (void)ext2_truncate(vp, osize,
+ ioflag & IO_SYNC, ap->a_cred, uio->uio_td);
+#endif
+ uio->uio_offset -= resid - uio->uio_resid;
+ uio->uio_resid = resid;
+ }
+ } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) {
+ /* Update the vnode here? */
+ }
+
+error:
+ return error;
}
static int
@@ -582,7 +731,7 @@ _xfs_create(
va.va_mask |= XFS_AT_MODE;
va.va_mode = vap->va_mode;
va.va_mask |= XFS_AT_TYPE;
- va.va_type = vap->va_type;
+ va.va_mode |= VTTOIF(vap->va_type);
xvp = NULL;
XVOP_CREATE(VPTOXFSVP(dvp), cnp, &va, &xvp, credp, error);
@@ -595,6 +744,8 @@ _xfs_create(
return (error);
}
+extern int xfs_remove(bhv_desc_t *, bhv_desc_t *, vname_t *, cred_t *);
+
static int
_xfs_remove(
struct vop_remove_args /* {
@@ -605,6 +756,8 @@ _xfs_remove(
} */ *ap)
{
struct vnode *vp = ap->a_vp;
+ struct thread *td = curthread;
+ struct ucred *credp = td->td_ucred;
/*
struct vnode *dvp = ap->a_dvp;
struct componentname *cnp = ap->a_cnp;
@@ -614,9 +767,12 @@ _xfs_remove(
if (vp->v_type == VDIR || vp->v_usecount != 1)
return (EPERM);
- error = 0;
+ error = xfs_remove(VPTOXFSVP(ap->a_dvp)->v_bh.bh_first,
+ VPTOXFSVP(ap->a_vp)->v_bh.bh_first,
+ ap->a_cnp,credp);
+
cache_purge(vp);
- return (error);
+ return error;
}
static int
@@ -711,7 +867,8 @@ _xfs_symlink(
va.va_mask |= XFS_AT_MODE;
va.va_mode = ap->a_vap->va_mode;
va.va_mask |= XFS_AT_TYPE;
- va.va_type = ap->a_vap->va_type;
+ printf("_xfs_symlink need to implement inode type 0x%x\n",ap->a_vap->va_type);
+ //va.va_type = ap->a_vap->va_type;
XVOP_SYMLINK(VPTOXFSVP(ap->a_dvp), ap->a_cnp, &va, ap->a_target,
&xvp, credp, error);
@@ -746,7 +903,8 @@ _xfs_mknod(
va.va_mask |= XFS_AT_MODE;
va.va_mode = vap->va_mode;
va.va_mask |= XFS_AT_TYPE;
- va.va_type = vap->va_type;
+ printf("_xfs_mknod need to implement inode type 0x%x\n",vap->va_type);
+// va.va_type = vap->va_type;
va.va_mask |= XFS_AT_RDEV;
va.va_rdev = vap->va_rdev;
@@ -783,7 +941,8 @@ _xfs_mkdir(
va.va_mask |= XFS_AT_MODE;
va.va_mode = vap->va_mode;
va.va_mask |= XFS_AT_TYPE;
- va.va_type = vap->va_type;
+ printf("_xfs_mkdir need to implement inode type 0x%x\n",vap->va_type);
+// va.va_type = vap->va_type;
xvp = NULL;
XVOP_MKDIR(VPTOXFSVP(dvp), cnp, &va, &xvp, credp, error);
@@ -888,8 +1047,7 @@ _xfs_fsync(
if (ap->a_waitfor == MNT_WAIT)
flags |= FSYNC_WAIT;
- XVOP_FSYNC(vp, flags, ap->a_td->td_ucred, (xfs_off_t)-1, (xfs_off_t)-1,
- error);
+ XVOP_FSYNC(vp, flags, ap->a_td->td_ucred, (xfs_off_t)0, (xfs_off_t)-1, error);
return (error);
}
@@ -1012,11 +1170,14 @@ _xfs_ioctl(
/* struct file *fp; */
int error;
- switch (ap->a_command) {
- default:
- error = EINVAL;
- }
- return (error);
+ xfs_vnode_t *xvp = VPTOXFSVP(ap->a_vp);
+
+ printf("_xfs_ioctl cmd 0x%lx data %p\n",ap->a_command,ap->a_data);
+
+// XVOP_IOCTL(xvp,(void *)NULL,(void *)NULL,ap->a_fflag,ap->a_command,ap->a_data,error);
+ error = xfs_ioctl(xvp->v_bh.bh_first,NULL,NULL,ap->a_fflag,ap->a_command,ap->a_data);
+
+ return error;
}
int
@@ -1212,13 +1373,10 @@ _xfs_kqfilter(
return (0);
}
-static __inline
struct xfs_inode *
-xfs_vtoi(struct vnode *vp)
+xfs_vtoi(struct xfs_vnode *xvp)
{
- if (VPTOXFSVP(vp) != 0)
- return (XFS_BHVTOI(VPTOXFSVP(vp)->v_fbhv));
- return (NULL);
+ return(XFS_BHVTOI(xvp->v_fbhv));
}
/*
@@ -1240,7 +1398,7 @@ _xfsfifo_read(
uio = ap->a_uio;
resid = uio->uio_resid;
error = fifo_specops.vop_read(ap);
- ip = xfs_vtoi(ap->a_vp);
+ ip = xfs_vtoi(VPTOXFSVP(ap->a_vp));
if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
(uio->uio_resid != resid || (error == 0 && resid != 0)))
xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
@@ -1266,7 +1424,7 @@ _xfsfifo_write(
uio = ap->a_uio;
resid = uio->uio_resid;
error = fifo_specops.vop_write(ap);
- ip = xfs_vtoi(ap->a_vp);
+ ip = xfs_vtoi(VPTOXFSVP(ap->a_vp));
if (ip != NULL && (uio->uio_resid != resid ||
(error == 0 && resid != 0)))
xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -1311,121 +1469,3 @@ _xfsfifo_kqfilter(
error = _xfs_kqfilter(ap);
return (error);
}
-
-static int
-_xfs_getextattr(
- struct vop_getextattr_args /* {
- struct vnode *a_vp;
- int a_attrnamespace;
- const char *a_name;
- struct uio *a_uio;
- size_t *a_size;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- int error;
- char *value;
- int size;
-
- error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
- ap->a_cred, ap->a_td, VREAD);
- if (error)
- return (error);
-
- size = ATTR_MAX_VALUELEN;
- value = (char *)kmem_zalloc(size, KM_SLEEP);
- if (value == NULL)
- return (ENOMEM);
-
- XVOP_ATTR_GET(VPTOXFSVP(ap->a_vp), ap->a_name, value, &size, 1,
- ap->a_cred, error);
-
- if (ap->a_uio != NULL) {
- if (ap->a_uio->uio_iov->iov_len < size)
- error = ERANGE;
- else
- uiomove(value, size, ap->a_uio);
- }
-
- if (ap->a_size != NULL)
- *ap->a_size = size;
-
- kmem_free(value, ATTR_MAX_VALUELEN);
- return (error);
-}
-
-static int
-_xfs_listextattr(
- struct vop_listextattr_args /* {
- struct vnode *a_vp;
- int a_attrnamespace;
- struct uio *a_uio;
- size_t *a_size;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- int error;
- char *buf = NULL;
- int buf_len = 0;
- attrlist_cursor_kern_t cursor = { 0 };
- int i;
- char name_len;
- int attrnames_len = 0;
- int xfs_flags = ATTR_KERNAMELS;
-
- error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
- ap->a_cred, ap->a_td, VREAD);
- if (error)
- return (error);
-
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_USER)
- xfs_flags |= ATTR_KERNORMALS;
-
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_SYSTEM)
- xfs_flags |= ATTR_KERNROOTLS;
-
- if (ap->a_uio == NULL || ap->a_uio->uio_iov[0].iov_base == NULL) {
- xfs_flags |= ATTR_KERNOVAL;
- buf_len = 0;
- } else {
- buf = ap->a_uio->uio_iov[0].iov_base;
- buf_len = ap->a_uio->uio_iov[0].iov_len;
- }
-
- XVOP_ATTR_LIST(VPTOXFSVP(ap->a_vp), buf, buf_len, xfs_flags,
- &cursor, ap->a_cred, error);
- if (error < 0) {
- attrnames_len = -error;
- error = 0;
- }
- if (buf == NULL)
- goto done;
-
- /*
- * extattr_list expects a list of names. Each list
- * entry consists of one byte for the name length, followed
- * by the name (not null terminated)
- */
- name_len=0;
- for(i=attrnames_len-1; i > 0 ; --i) {
- buf[i] = buf[i-1];
- if (buf[i])
- ++name_len;
- else {
- buf[i] = name_len;
- name_len = 0;
- }
- }
- buf[0] = name_len;
-
- if (ap->a_uio != NULL)
- ap->a_uio->uio_resid -= attrnames_len;
-
-done:
- if (ap->a_size != NULL)
- *ap->a_size = attrnames_len;
-
- return (error);
-}