summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-03-02 06:53:03 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-03-02 06:53:03 -0800
commitb2d271d97cf4f1ca83737058cd95921b59ac0dca (patch)
treebd9518958f066b702dafbfb4d722e28fe39ca83b
parentc29ed89cc4a324c26fc442ad0d98413d8222d984 (diff)
parent17b2b36ec535af8605945247fb069ad8891663a9 (diff)
Merge http://xfs.org:8090/xfs-linux-2.6
into ppc970.osdl.org:/home/torvalds/v2.5/linux
-rw-r--r--fs/xfs/Makefile11
-rw-r--r--fs/xfs/linux/mrlock.c274
-rw-r--r--fs/xfs/linux/mrlock.h103
-rw-r--r--fs/xfs/linux/xfs_aops.c173
-rw-r--r--fs/xfs/linux/xfs_buf.c273
-rw-r--r--fs/xfs/linux/xfs_buf.h9
-rw-r--r--fs/xfs/linux/xfs_globals.c2
-rw-r--r--fs/xfs/linux/xfs_ioctl.c39
-rw-r--r--fs/xfs/linux/xfs_iops.c4
-rw-r--r--fs/xfs/linux/xfs_linux.h3
-rw-r--r--fs/xfs/linux/xfs_lrw.c22
-rw-r--r--fs/xfs/linux/xfs_lrw.h10
-rw-r--r--fs/xfs/linux/xfs_stats.c1
-rw-r--r--fs/xfs/linux/xfs_stats.h10
-rw-r--r--fs/xfs/linux/xfs_super.c2
-rw-r--r--fs/xfs/linux/xfs_super.h4
-rw-r--r--fs/xfs/linux/xfs_sysctl.c10
-rw-r--r--fs/xfs/linux/xfs_sysctl.h6
-rw-r--r--fs/xfs/linux/xfs_vfs.c1
-rw-r--r--fs/xfs/xfs_alloc.c6
-rw-r--r--fs/xfs/xfs_attr.h6
-rw-r--r--fs/xfs/xfs_attr_leaf.c22
-rw-r--r--fs/xfs/xfs_clnt.h10
-rw-r--r--fs/xfs/xfs_dmapi.h21
-rw-r--r--fs/xfs/xfs_dmops.c2
-rw-r--r--fs/xfs/xfs_fs.h7
-rw-r--r--fs/xfs/xfs_fsops.c25
-rw-r--r--fs/xfs/xfs_fsops.h5
-rw-r--r--fs/xfs/xfs_iomap.c101
-rw-r--r--fs/xfs/xfs_log.c78
-rw-r--r--fs/xfs/xfs_log_priv.h4
-rw-r--r--fs/xfs/xfs_log_recover.c17
-rw-r--r--fs/xfs/xfs_mount.c1
-rw-r--r--fs/xfs/xfs_mount.h4
-rw-r--r--fs/xfs/xfs_qmops.c2
-rw-r--r--fs/xfs/xfs_quota.h3
-rw-r--r--fs/xfs/xfs_vfsops.c9
-rw-r--r--fs/xfs/xfs_vnodeops.c3
38 files changed, 517 insertions, 766 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 5475efd6a2f7..64b586ee847b 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -54,10 +54,6 @@ endif
obj-$(CONFIG_XFS_FS) += xfs.o
-ifneq ($(CONFIG_XFS_DMAPI),y)
-xfs-y += xfs_dmops.o
-endif
-
xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \
xfs_dquot.o \
xfs_dquot_item.o \
@@ -67,8 +63,6 @@ xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \
xfs_qm.o)
ifeq ($(CONFIG_XFS_QUOTA),y)
xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o
-else
-xfs-y += xfs_qmops.o
endif
xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
@@ -124,13 +118,14 @@ xfs-y += xfs_alloc.o \
xfs_utils.o \
xfs_vfsops.o \
xfs_vnodeops.o \
- xfs_rw.o
+ xfs_rw.o \
+ xfs_dmops.o \
+ xfs_qmops.o
xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o
# Objects in linux/
xfs-y += $(addprefix linux/, \
- mrlock.o \
xfs_aops.o \
xfs_buf.o \
xfs_file.o \
diff --git a/fs/xfs/linux/mrlock.c b/fs/xfs/linux/mrlock.c
deleted file mode 100644
index 5b5dae97af9c..000000000000
--- a/fs/xfs/linux/mrlock.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <asm/system.h>
-#include <linux/interrupt.h>
-#include <asm/current.h>
-
-#include "mrlock.h"
-
-
-#if USE_RW_WAIT_QUEUE_SPINLOCK
-# define wq_write_lock write_lock
-#else
-# define wq_write_lock spin_lock
-#endif
-
-/*
- * We don't seem to need lock_type (only one supported), name, or
- * sequence. But, XFS will pass it so let's leave them here for now.
- */
-/* ARGSUSED */
-void
-mrlock_init(mrlock_t *mrp, int lock_type, char *name, long sequence)
-{
- mrp->mr_count = 0;
- mrp->mr_reads_waiting = 0;
- mrp->mr_writes_waiting = 0;
- init_waitqueue_head(&mrp->mr_readerq);
- init_waitqueue_head(&mrp->mr_writerq);
- mrp->mr_lock = SPIN_LOCK_UNLOCKED;
-}
-
-/*
- * Macros to lock/unlock the mrlock_t.
- */
-
-#define MRLOCK(m) spin_lock(&(m)->mr_lock);
-#define MRUNLOCK(m) spin_unlock(&(m)->mr_lock);
-
-
-/*
- * lock_wait should never be called in an interrupt thread.
- *
- * mrlocks can sleep (i.e. call schedule) and so they can't ever
- * be called from an interrupt thread.
- *
- * threads that wake-up should also never be invoked from interrupt threads.
- *
- * But, waitqueue_lock is locked from interrupt threads - and we are
- * called with interrupts disabled, so it is all OK.
- */
-
-/* ARGSUSED */
-void
-lock_wait(wait_queue_head_t *q, spinlock_t *lock, int rw)
-{
- DECLARE_WAITQUEUE( wait, current );
-
- __set_current_state(TASK_UNINTERRUPTIBLE);
-
- spin_lock(&q->lock);
- if (rw) {
- __add_wait_queue_tail(q, &wait);
- } else {
- __add_wait_queue(q, &wait);
- }
-
- spin_unlock(&q->lock);
- spin_unlock(lock);
-
- schedule();
-
- spin_lock(&q->lock);
- __remove_wait_queue(q, &wait);
- spin_unlock(&q->lock);
-
- spin_lock(lock);
-
- /* return with lock held */
-}
-
-/* ARGSUSED */
-void
-mrfree(mrlock_t *mrp)
-{
-}
-
-/* ARGSUSED */
-void
-mrlock(mrlock_t *mrp, int type, int flags)
-{
- if (type == MR_ACCESS)
- mraccess(mrp);
- else
- mrupdate(mrp);
-}
-
-/* ARGSUSED */
-void
-mraccessf(mrlock_t *mrp, int flags)
-{
- MRLOCK(mrp);
- if(mrp->mr_writes_waiting > 0) {
- mrp->mr_reads_waiting++;
- lock_wait(&mrp->mr_readerq, &mrp->mr_lock, 0);
- mrp->mr_reads_waiting--;
- }
- while (mrp->mr_count < 0) {
- mrp->mr_reads_waiting++;
- lock_wait(&mrp->mr_readerq, &mrp->mr_lock, 0);
- mrp->mr_reads_waiting--;
- }
- mrp->mr_count++;
- MRUNLOCK(mrp);
-}
-
-/* ARGSUSED */
-void
-mrupdatef(mrlock_t *mrp, int flags)
-{
- MRLOCK(mrp);
- while(mrp->mr_count) {
- mrp->mr_writes_waiting++;
- lock_wait(&mrp->mr_writerq, &mrp->mr_lock, 1);
- mrp->mr_writes_waiting--;
- }
-
- mrp->mr_count = -1; /* writer on it */
- MRUNLOCK(mrp);
-}
-
-int
-mrtryaccess(mrlock_t *mrp)
-{
- MRLOCK(mrp);
- /*
- * If anyone is waiting for update access or the lock is held for update
- * fail the request.
- */
- if(mrp->mr_writes_waiting > 0 || mrp->mr_count < 0) {
- MRUNLOCK(mrp);
- return 0;
- }
- mrp->mr_count++;
- MRUNLOCK(mrp);
- return 1;
-}
-
-int
-mrtrypromote(mrlock_t *mrp)
-{
- MRLOCK(mrp);
-
- if(mrp->mr_count == 1) { /* We are the only thread with the lock */
- mrp->mr_count = -1; /* writer on it */
- MRUNLOCK(mrp);
- return 1;
- }
-
- MRUNLOCK(mrp);
- return 0;
-}
-
-int
-mrtryupdate(mrlock_t *mrp)
-{
- MRLOCK(mrp);
-
- if(mrp->mr_count) {
- MRUNLOCK(mrp);
- return 0;
- }
-
- mrp->mr_count = -1; /* writer on it */
- MRUNLOCK(mrp);
- return 1;
-}
-
-static __inline__ void mrwake(mrlock_t *mrp)
-{
- /*
- * First, if the count is now 0, we need to wake-up anyone waiting.
- */
- if (!mrp->mr_count) {
- if (mrp->mr_writes_waiting) { /* Wake-up first writer waiting */
- wake_up(&mrp->mr_writerq);
- } else if (mrp->mr_reads_waiting) { /* Wakeup any readers waiting */
- wake_up(&mrp->mr_readerq);
- }
- }
-}
-
-void
-mraccunlock(mrlock_t *mrp)
-{
- MRLOCK(mrp);
- mrp->mr_count--;
- mrwake(mrp);
- MRUNLOCK(mrp);
-}
-
-void
-mrunlock(mrlock_t *mrp)
-{
- MRLOCK(mrp);
- if (mrp->mr_count < 0) {
- mrp->mr_count = 0;
- } else {
- mrp->mr_count--;
- }
- mrwake(mrp);
- MRUNLOCK(mrp);
-}
-
-int
-ismrlocked(mrlock_t *mrp, int type) /* No need to lock since info can change */
-{
- if (type == MR_ACCESS)
- return (mrp->mr_count > 0); /* Read lock */
- else if (type == MR_UPDATE)
- return (mrp->mr_count < 0); /* Write lock */
- else if (type == (MR_UPDATE | MR_ACCESS))
- return (mrp->mr_count); /* Any type of lock held */
- else /* Any waiters */
- return (mrp->mr_reads_waiting | mrp->mr_writes_waiting);
-}
-
-/*
- * Demote from update to access. We better be the only thread with the
- * lock in update mode so it should be easy to set to 1.
- * Wake-up any readers waiting.
- */
-
-void
-mrdemote(mrlock_t *mrp)
-{
- MRLOCK(mrp);
- mrp->mr_count = 1;
- if (mrp->mr_reads_waiting) { /* Wakeup all readers waiting */
- wake_up(&mrp->mr_readerq);
- }
- MRUNLOCK(mrp);
-}
diff --git a/fs/xfs/linux/mrlock.h b/fs/xfs/linux/mrlock.h
index b2a7b3ad5eff..14aeeef3b23b 100644
--- a/fs/xfs/linux/mrlock.h
+++ b/fs/xfs/linux/mrlock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -32,56 +32,73 @@
#ifndef __XFS_SUPPORT_MRLOCK_H__
#define __XFS_SUPPORT_MRLOCK_H__
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <asm/atomic.h>
-#include <asm/semaphore.h>
+#include <linux/rwsem.h>
-/*
- * Implement mrlocks on Linux that work for XFS.
- *
- * These are sleep locks and not spinlocks. If one wants read/write spinlocks,
- * use read_lock, write_lock, ... see spinlock.h.
- */
+enum { MR_NONE, MR_ACCESS, MR_UPDATE };
-typedef struct mrlock_s {
- int mr_count;
- unsigned short mr_reads_waiting;
- unsigned short mr_writes_waiting;
- wait_queue_head_t mr_readerq;
- wait_queue_head_t mr_writerq;
- spinlock_t mr_lock;
+typedef struct {
+ struct rw_semaphore mr_lock;
+ int mr_writer;
} mrlock_t;
-#define MR_ACCESS 1
-#define MR_UPDATE 2
+#define mrinit(mrp, name) \
+ ( (mrp)->mr_writer = 0, init_rwsem(&(mrp)->mr_lock) )
+#define mrlock_init(mrp, t,n,s) mrinit(mrp, n)
+#define mrfree(mrp) do { } while (0)
+#define mraccess(mrp) mraccessf(mrp, 0)
+#define mrupdate(mrp) mrupdatef(mrp, 0)
-#define MRLOCK_BARRIER 0x1
-#define MRLOCK_ALLOW_EQUAL_PRI 0x8
+static inline void mraccessf(mrlock_t *mrp, int flags)
+{
+ down_read(&mrp->mr_lock);
+}
-/*
- * mraccessf/mrupdatef take flags to be passed in while sleeping;
- * only PLTWAIT is currently supported.
- */
+static inline void mrupdatef(mrlock_t *mrp, int flags)
+{
+ down_write(&mrp->mr_lock);
+ mrp->mr_writer = 1;
+}
-extern void mraccessf(mrlock_t *, int);
-extern void mrupdatef(mrlock_t *, int);
-extern void mrlock(mrlock_t *, int, int);
-extern void mrunlock(mrlock_t *);
-extern void mraccunlock(mrlock_t *);
-extern int mrtryupdate(mrlock_t *);
-extern int mrtryaccess(mrlock_t *);
-extern int mrtrypromote(mrlock_t *);
-extern void mrdemote(mrlock_t *);
+static inline int mrtryaccess(mrlock_t *mrp)
+{
+ return down_read_trylock(&mrp->mr_lock);
+}
-extern int ismrlocked(mrlock_t *, int);
-extern void mrlock_init(mrlock_t *, int type, char *name, long sequence);
-extern void mrfree(mrlock_t *);
+static inline int mrtryupdate(mrlock_t *mrp)
+{
+ if (!down_write_trylock(&mrp->mr_lock))
+ return 0;
+ mrp->mr_writer = 1;
+ return 1;
+}
-#define mrinit(mrp, name) mrlock_init(mrp, MRLOCK_BARRIER, name, -1)
-#define mraccess(mrp) mraccessf(mrp, 0) /* grab for READ/ACCESS */
-#define mrupdate(mrp) mrupdatef(mrp, 0) /* grab for WRITE/UPDATE */
-#define mrislocked_access(mrp) ((mrp)->mr_count > 0)
-#define mrislocked_update(mrp) ((mrp)->mr_count < 0)
+static inline void mrunlock(mrlock_t *mrp)
+{
+ if (mrp->mr_writer) {
+ mrp->mr_writer = 0;
+ up_write(&mrp->mr_lock);
+ } else {
+ up_read(&mrp->mr_lock);
+ }
+}
+
+static inline void mrdemote(mrlock_t *mrp)
+{
+ mrp->mr_writer = 0;
+ downgrade_write(&mrp->mr_lock);
+}
+
+/*
+ * Debug-only routine, without some platform-specific asm code, we can
+ * now only answer requests regarding whether we hold the lock for write
+ * (reader state is outside our visibility, we only track writer state).
+ * Note: means !ismrlocked would give false positivies, so don't do that.
+ */
+static inline int ismrlocked(mrlock_t *mrp, int type)
+{
+ if (type == MR_UPDATE)
+ return mrp->mr_writer;
+ return 1;
+}
#endif /* __XFS_SUPPORT_MRLOCK_H__ */
diff --git a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c
index 1d13a91e3b37..a48ec1d17cfa 100644
--- a/fs/xfs/linux/xfs_aops.c
+++ b/fs/xfs/linux/xfs_aops.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -54,8 +54,54 @@
#include "xfs_iomap.h"
#include <linux/mpage.h>
-STATIC void convert_page(struct inode *, struct page *,
- xfs_iomap_t *, void *, int, int);
+STATIC void xfs_count_page_state(struct page *, int *, int *, int *);
+STATIC void xfs_convert_page(struct inode *, struct page *,
+ xfs_iomap_t *, void *, int, int);
+
+#if defined(XFS_RW_TRACE)
+void
+xfs_page_trace(
+ int tag,
+ struct inode *inode,
+ struct page *page,
+ int mask)
+{
+ xfs_inode_t *ip;
+ bhv_desc_t *bdp;
+ vnode_t *vp = LINVFS_GET_VP(inode);
+ loff_t isize = i_size_read(inode);
+ loff_t offset = page->index << PAGE_CACHE_SHIFT;
+ int delalloc = -1, unmapped = -1, unwritten = -1;
+
+ if (page_has_buffers(page))
+ xfs_count_page_state(page, &delalloc, &unmapped, &unwritten);
+
+ bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), &xfs_vnodeops);
+ ip = XFS_BHVTOI(bdp);
+ if (!ip->i_rwtrace)
+ return;
+
+ ktrace_enter(ip->i_rwtrace,
+ (void *)((unsigned long)tag),
+ (void *)ip,
+ (void *)inode,
+ (void *)page,
+ (void *)((unsigned long)mask),
+ (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)),
+ (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)),
+ (void *)((unsigned long)((isize >> 32) & 0xffffffff)),
+ (void *)((unsigned long)(isize & 0xffffffff)),
+ (void *)((unsigned long)((offset >> 32) & 0xffffffff)),
+ (void *)((unsigned long)(offset & 0xffffffff)),
+ (void *)((unsigned long)delalloc),
+ (void *)((unsigned long)unmapped),
+ (void *)((unsigned long)unwritten),
+ (void *)NULL,
+ (void *)NULL);
+}
+#else
+#define xfs_page_trace(tag, inode, page, mask)
+#endif
void
linvfs_unwritten_done(
@@ -121,7 +167,7 @@ linvfs_unwritten_convert_direct(
}
STATIC int
-map_blocks(
+xfs_map_blocks(
struct inode *inode,
loff_t offset,
ssize_t count,
@@ -151,12 +197,11 @@ retry:
}
/*
- * match_offset_to_mapping
* Finds the corresponding mapping in block @map array of the
* given @offset within a @page.
*/
STATIC xfs_iomap_t *
-match_offset_to_mapping(
+xfs_offset_to_map(
struct page *page,
xfs_iomap_t *iomapp,
unsigned long offset)
@@ -177,7 +222,7 @@ match_offset_to_mapping(
}
STATIC void
-map_buffer_at_offset(
+xfs_map_at_offset(
struct page *page,
struct buffer_head *bh,
unsigned long offset,
@@ -218,7 +263,7 @@ map_buffer_at_offset(
* in units of filesystem blocks.
*/
STATIC struct page *
-probe_unwritten_page(
+xfs_probe_unwritten_page(
struct address_space *mapping,
unsigned long index,
xfs_iomap_t *iomapp,
@@ -244,11 +289,11 @@ probe_unwritten_page(
do {
if (!buffer_unwritten(bh))
break;
- if (!match_offset_to_mapping(page, iomapp, p_offset))
+ if (!xfs_offset_to_map(page, iomapp, p_offset))
break;
if (p_offset >= max_offset)
break;
- map_buffer_at_offset(page, bh, p_offset, bbits, iomapp);
+ xfs_map_at_offset(page, bh, p_offset, bbits, iomapp);
set_buffer_unwritten_io(bh);
bh->b_private = pb;
p_offset += bh->b_size;
@@ -269,7 +314,7 @@ out:
* yet - clustering for mmap write case.
*/
STATIC unsigned int
-probe_unmapped_page(
+xfs_probe_unmapped_page(
struct address_space *mapping,
unsigned long index,
unsigned int pg_offset)
@@ -305,7 +350,7 @@ out:
}
STATIC unsigned int
-probe_unmapped_cluster(
+xfs_probe_unmapped_cluster(
struct inode *inode,
struct page *startpage,
struct buffer_head *bh,
@@ -330,7 +375,7 @@ probe_unmapped_cluster(
/* Prune this back to avoid pathological behavior */
tloff = min(tlast, startpage->index + 64);
for (tindex = startpage->index + 1; tindex < tloff; tindex++) {
- len = probe_unmapped_page(mapping, tindex,
+ len = xfs_probe_unmapped_page(mapping, tindex,
PAGE_CACHE_SIZE);
if (!len)
return total;
@@ -338,7 +383,8 @@ probe_unmapped_cluster(
}
if (tindex == tlast &&
(tloff = i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) {
- total += probe_unmapped_page(mapping, tindex, tloff);
+ total += xfs_probe_unmapped_page(mapping,
+ tindex, tloff);
}
}
return total;
@@ -350,7 +396,7 @@ probe_unmapped_cluster(
* reference count.
*/
STATIC struct page *
-probe_delalloc_page(
+xfs_probe_delalloc_page(
struct inode *inode,
unsigned long index)
{
@@ -386,7 +432,7 @@ out:
}
STATIC int
-map_unwritten(
+xfs_map_unwritten(
struct inode *inode,
struct page *start_page,
struct buffer_head *head,
@@ -434,22 +480,16 @@ map_unwritten(
do {
if (!buffer_unwritten(bh))
break;
- tmp = match_offset_to_mapping(start_page, iomapp, p_offset);
+ tmp = xfs_offset_to_map(start_page, iomapp, p_offset);
if (!tmp)
break;
- map_buffer_at_offset(start_page, bh, p_offset, block_bits, iomapp);
+ xfs_map_at_offset(start_page, bh, p_offset, block_bits, iomapp);
set_buffer_unwritten_io(bh);
bh->b_private = pb;
p_offset += bh->b_size;
nblocks++;
} while ((bh = bh->b_this_page) != head);
- if (unlikely(nblocks == 0)) {
- printk("XFS: bad unwritten extent map: bh=0x%p, iomapp=0x%p\n",
- curr, iomapp);
- BUG();
- }
-
atomic_add(nblocks, &pb->pb_io_remaining);
/* If we reached the end of the page, map forwards in any
@@ -465,13 +505,15 @@ map_unwritten(
tloff = (iomapp->iomap_offset + iomapp->iomap_bsize) >> PAGE_CACHE_SHIFT;
tloff = min(tlast, tloff);
for (tindex = start_page->index + 1; tindex < tloff; tindex++) {
- page = probe_unwritten_page(mapping, tindex, iomapp, pb,
+ page = xfs_probe_unwritten_page(mapping,
+ tindex, iomapp, pb,
PAGE_CACHE_SIZE, &bs, bbits);
if (!page)
break;
nblocks += bs;
atomic_add(bs, &pb->pb_io_remaining);
- convert_page(inode, page, iomapp, pb, startio, all_bh);
+ xfs_convert_page(inode, page, iomapp, pb,
+ startio, all_bh);
/* stop if converting the next page might add
* enough blocks that the corresponding byte
* count won't fit in our ulong page buf length */
@@ -481,12 +523,14 @@ map_unwritten(
if (tindex == tlast &&
(tloff = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1)))) {
- page = probe_unwritten_page(mapping, tindex, iomapp, pb,
+ page = xfs_probe_unwritten_page(mapping,
+ tindex, iomapp, pb,
tloff, &bs, bbits);
if (page) {
nblocks += bs;
atomic_add(bs, &pb->pb_io_remaining);
- convert_page(inode, page, iomapp, pb, startio, all_bh);
+ xfs_convert_page(inode, page, iomapp, pb,
+ startio, all_bh);
if (nblocks >= ((ULONG_MAX - PAGE_SIZE) >> block_bits))
goto enough;
}
@@ -513,7 +557,7 @@ enough:
}
STATIC void
-submit_page(
+xfs_submit_page(
struct page *page,
struct buffer_head *bh_arr[],
int cnt)
@@ -549,7 +593,7 @@ submit_page(
* that the page has no mapping at all.
*/
STATIC void
-convert_page(
+xfs_convert_page(
struct inode *inode,
struct page *page,
xfs_iomap_t *iomapp,
@@ -582,7 +626,7 @@ convert_page(
}
continue;
}
- tmp = match_offset_to_mapping(page, mp, offset);
+ tmp = xfs_offset_to_map(page, mp, offset);
if (!tmp)
continue;
ASSERT(!(tmp->iomap_flags & IOMAP_HOLE));
@@ -594,10 +638,10 @@ convert_page(
*/
if (buffer_unwritten(bh) && !bh->b_end_io) {
ASSERT(tmp->iomap_flags & IOMAP_UNWRITTEN);
- map_unwritten(inode, page, head, bh,
+ xfs_map_unwritten(inode, page, head, bh,
offset, bbits, tmp, startio, all_bh);
} else if (! (buffer_unwritten(bh) && buffer_locked(bh))) {
- map_buffer_at_offset(page, bh, offset, bbits, tmp);
+ xfs_map_at_offset(page, bh, offset, bbits, tmp);
if (buffer_unwritten(bh)) {
set_buffer_unwritten_io(bh);
bh->b_private = private;
@@ -614,7 +658,7 @@ convert_page(
} while (i++, (bh = bh->b_this_page) != head);
if (startio) {
- submit_page(page, bh_arr, index);
+ xfs_submit_page(page, bh_arr, index);
} else {
unlock_page(page);
}
@@ -625,7 +669,7 @@ convert_page(
* by mp and following the start page.
*/
STATIC void
-cluster_write(
+xfs_cluster_write(
struct inode *inode,
unsigned long tindex,
xfs_iomap_t *iomapp,
@@ -637,10 +681,10 @@ cluster_write(
tlast = (iomapp->iomap_offset + iomapp->iomap_bsize) >> PAGE_CACHE_SHIFT;
for (; tindex < tlast; tindex++) {
- page = probe_delalloc_page(inode, tindex);
+ page = xfs_probe_delalloc_page(inode, tindex);
if (!page)
break;
- convert_page(inode, page, iomapp, NULL, startio, all_bh);
+ xfs_convert_page(inode, page, iomapp, NULL, startio, all_bh);
}
}
@@ -664,7 +708,7 @@ cluster_write(
*/
STATIC int
-page_state_convert(
+xfs_page_state_convert(
struct inode *inode,
struct page *page,
int startio,
@@ -707,7 +751,7 @@ page_state_convert(
continue;
if (iomp) {
- iomp = match_offset_to_mapping(page, &iomap, p_offset);
+ iomp = xfs_offset_to_map(page, &iomap, p_offset);
}
/*
@@ -716,17 +760,17 @@ page_state_convert(
*/
if (buffer_unwritten(bh)) {
if (!iomp) {
- err = map_blocks(inode, offset, len, &iomap,
+ err = xfs_map_blocks(inode, offset, len, &iomap,
BMAPI_READ|BMAPI_IGNSTATE);
if (err) {
goto error;
}
- iomp = match_offset_to_mapping(page, &iomap,
+ iomp = xfs_offset_to_map(page, &iomap,
p_offset);
}
if (iomp && startio) {
if (!bh->b_end_io) {
- err = map_unwritten(inode, page,
+ err = xfs_map_unwritten(inode, page,
head, bh, p_offset,
inode->i_blkbits, iomp,
startio, unmapped);
@@ -743,17 +787,17 @@ page_state_convert(
*/
} else if (buffer_delay(bh)) {
if (!iomp) {
- err = map_blocks(inode, offset, len, &iomap,
- BMAPI_ALLOCATE | flags);
+ err = xfs_map_blocks(inode, offset, len, &iomap,
+ BMAPI_ALLOCATE | flags);
if (err) {
goto error;
}
- iomp = match_offset_to_mapping(page, &iomap,
+ iomp = xfs_offset_to_map(page, &iomap,
p_offset);
}
if (iomp) {
- map_buffer_at_offset(page, bh, p_offset,
- inode->i_blkbits, iomp);
+ xfs_map_at_offset(page, bh, p_offset,
+ inode->i_blkbits, iomp);
if (startio) {
bh_arr[cnt++] = bh;
} else {
@@ -775,19 +819,19 @@ page_state_convert(
* need to write the whole page out.
*/
if (!iomp) {
- size = probe_unmapped_cluster(
+ size = xfs_probe_unmapped_cluster(
inode, page, bh, head);
- err = map_blocks(inode, offset,
- size, &iomap,
- BMAPI_WRITE | BMAPI_MMAP);
+ err = xfs_map_blocks(inode, offset,
+ size, &iomap,
+ BMAPI_WRITE|BMAPI_MMAP);
if (err) {
goto error;
}
- iomp = match_offset_to_mapping(page, &iomap,
+ iomp = xfs_offset_to_map(page, &iomap,
p_offset);
}
if (iomp) {
- map_buffer_at_offset(page,
+ xfs_map_at_offset(page,
bh, p_offset,
inode->i_blkbits, iomp);
if (startio) {
@@ -814,10 +858,10 @@ page_state_convert(
SetPageUptodate(page);
if (startio)
- submit_page(page, bh_arr, cnt);
+ xfs_submit_page(page, bh_arr, cnt);
if (iomp)
- cluster_write(inode, page->index + 1, iomp, startio, unmapped);
+ xfs_cluster_write(inode, page->index + 1, iomp, startio, unmapped);
return page_dirty;
@@ -1031,7 +1075,7 @@ linvfs_readpages(
}
STATIC void
-count_page_state(
+xfs_count_page_state(
struct page *page,
int *delalloc,
int *unmapped,
@@ -1085,18 +1129,21 @@ linvfs_writepage(
int delalloc, unmapped, unwritten;
struct inode *inode = page->mapping->host;
+ xfs_page_trace(XFS_WRITEPAGE_ENTER, inode, page, 0);
+
/*
* We need a transaction if:
* 1. There are delalloc buffers on the page
- * 2. The page is upto date and we have unmapped buffers
- * 3. The page is upto date and we have no buffers
+ * 2. The page is uptodate and we have unmapped buffers
+ * 3. The page is uptodate and we have no buffers
* 4. There are unwritten buffers on the page
*/
+
if (!page_has_buffers(page)) {
unmapped = 1;
need_trans = 1;
} else {
- count_page_state(page, &delalloc, &unmapped, &unwritten);
+ xfs_count_page_state(page, &delalloc, &unmapped, &unwritten);
if (!PageUptodate(page))
unmapped = 0;
need_trans = delalloc + unmapped + unwritten;
@@ -1122,7 +1169,7 @@ linvfs_writepage(
* Convert delayed allocate, unwritten or unmapped space
* to real space and flush out to disk.
*/
- error = page_state_convert(inode, page, 1, unmapped);
+ error = xfs_page_state_convert(inode, page, 1, unmapped);
if (error == -EAGAIN)
goto out_fail;
if (unlikely(error < 0))
@@ -1166,7 +1213,9 @@ linvfs_release_page(
struct inode *inode = page->mapping->host;
int dirty, delalloc, unmapped, unwritten;
- count_page_state(page, &delalloc, &unmapped, &unwritten);
+ xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, gfp_mask);
+
+ xfs_count_page_state(page, &delalloc, &unmapped, &unwritten);
if (!delalloc && !unwritten)
goto free_buffers;
@@ -1185,7 +1234,7 @@ linvfs_release_page(
* Never need to allocate space here - we will always
* come back to writepage in that case.
*/
- dirty = page_state_convert(inode, page, 0, 0);
+ dirty = xfs_page_state_convert(inode, page, 0, 0);
if (dirty == 0 && !unwritten)
goto free_buffers;
return 0;
diff --git a/fs/xfs/linux/xfs_buf.c b/fs/xfs/linux/xfs_buf.c
index ca897a836c14..c5f06aad5234 100644
--- a/fs/xfs/linux/xfs_buf.c
+++ b/fs/xfs/linux/xfs_buf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -59,17 +59,7 @@
#include <linux/suspend.h>
#include <linux/percpu.h>
-#include <support/ktrace.h>
-#include <support/debug.h>
-#include "kmem.h"
-
-#include "xfs_types.h"
-#include "xfs_cred.h"
-#include "xfs_lrw.h"
-#include "xfs_buf.h"
-
-#define BBSHIFT 9
-#define BN_ALIGN_MASK ((1 << (PAGE_CACHE_SHIFT - BBSHIFT)) - 1)
+#include "xfs_linux.h"
#ifndef GFP_READAHEAD
#define GFP_READAHEAD (__GFP_NOWARN|__GFP_NORETRY)
@@ -86,60 +76,6 @@ STATIC struct workqueue_struct *pagebuf_logio_workqueue;
STATIC struct workqueue_struct *pagebuf_dataio_workqueue;
/*
- * Pagebuf module configuration parameters, exported via
- * /proc/sys/vm/pagebuf
- */
-
-typedef struct pb_sysctl_val {
- int min;
- int val;
- int max;
-} pb_sysctl_val_t;
-
-struct {
- pb_sysctl_val_t flush_interval; /* interval between runs of the
- * delwri flush daemon. */
- pb_sysctl_val_t age_buffer; /* time for buffer to age before
- * we flush it. */
- pb_sysctl_val_t stats_clear; /* clear the pagebuf stats */
- pb_sysctl_val_t debug; /* debug tracing on or off */
-} pb_params = {
- /* MIN DFLT MAX */
- .flush_interval = { HZ/2, HZ, 30*HZ },
- .age_buffer = { 1*HZ, 15*HZ, 300*HZ },
- .stats_clear = { 0, 0, 1 },
- .debug = { 0, 0, 1 },
-};
-
-enum {
- PB_FLUSH_INT = 1,
- PB_FLUSH_AGE = 2,
- PB_STATS_CLEAR = 3,
- PB_DEBUG = 4,
-};
-
-/*
- * Pagebuf statistics variables
- */
-
-struct pbstats {
- u_int32_t pb_get;
- u_int32_t pb_create;
- u_int32_t pb_get_locked;
- u_int32_t pb_get_locked_waited;
- u_int32_t pb_busy_locked;
- u_int32_t pb_miss_locked;
- u_int32_t pb_page_retries;
- u_int32_t pb_page_found;
- u_int32_t pb_get_read;
-} pbstats;
-DEFINE_PER_CPU(struct pbstats, pbstats);
-
-/* We don't disable preempt, not too worried about poking the
- * wrong cpu's stat for now */
-#define PB_STATS_INC(count) (__get_cpu_var(pbstats).count++)
-
-/*
* Pagebuf debugging
*/
@@ -151,8 +87,6 @@ pagebuf_trace(
void *data,
void *ra)
{
- if (!pb_params.debug.val)
- return;
ktrace_enter(pagebuf_trace_buf,
pb, id,
(void *)(unsigned long)pb->pb_flags,
@@ -326,7 +260,7 @@ _pagebuf_initialize(
atomic_set(&pb->pb_pin_count, 0);
init_waitqueue_head(&pb->pb_waiters);
- PB_STATS_INC(pb_create);
+ XFS_STATS_INC(pb_create);
PB_TRACE(pb, "initialize", target);
}
@@ -382,25 +316,13 @@ _pagebuf_freepages(
* pagebuf_free releases the specified buffer. The modification
* state of any associated pages is left unchanged.
*/
-STATIC void
-__pagebuf_free(
+void
+pagebuf_free(
page_buf_t *pb)
{
- pb_hash_t *hash = pb_hash(pb);
-
PB_TRACE(pb, "free", 0);
-
- spin_lock(&hash->pb_hash_lock);
- /*
- * Someone grabbed a reference while we weren't looking,
- * try again later.
- */
- if (unlikely(atomic_read(&pb->pb_hold))) {
- spin_unlock(&hash->pb_hash_lock);
- return;
- } else if (!list_empty(&pb->pb_hash_list))
- list_del_init(&pb->pb_hash_list);
- spin_unlock(&hash->pb_hash_lock);
+
+ ASSERT(list_empty(&pb->pb_hash_list));
/* release any virtual mapping */ ;
if (pb->pb_flags & _PBF_ADDR_ALLOCATED) {
@@ -429,17 +351,6 @@ __pagebuf_free(
pagebuf_deallocate(pb);
}
-void
-pagebuf_free(
- page_buf_t *pb)
-{
- if (unlikely(!atomic_dec_and_test(&pb->pb_hold))) {
- printk(KERN_ERR "XFS: freeing inuse buffer!\n");
- dump_stack();
- } else
- __pagebuf_free(pb);
-}
-
/*
* _pagebuf_lookup_pages
*
@@ -513,13 +424,13 @@ _pagebuf_lookup_pages(
"possibly deadlocking in %s\n",
__FUNCTION__);
}
- PB_STATS_INC(pb_page_retries);
+ XFS_STATS_INC(pb_page_retries);
pagebuf_daemon_wakeup();
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout(10);
goto retry;
}
- PB_STATS_INC(pb_page_found);
+ XFS_STATS_INC(pb_page_found);
mark_page_accessed(page);
pb->pb_pages[pi] = page;
} else {
@@ -565,6 +476,7 @@ _pagebuf_lookup_pages(
}
}
+ pb->pb_flags |= _PBF_PAGECACHE;
mapit:
pb->pb_flags |= _PBF_MEM_ALLOCATED;
if (all_mapped) {
@@ -649,8 +561,7 @@ _pagebuf_find( /* find buffer for block */
if (pb->pb_target == target &&
pb->pb_file_offset == range_base &&
- pb->pb_buffer_length == range_length &&
- atomic_read(&pb->pb_hold)) {
+ pb->pb_buffer_length == range_length) {
/* If we look at something bring it to the
* front of the list for next time
*/
@@ -667,7 +578,7 @@ _pagebuf_find( /* find buffer for block */
new_pb->pb_hash_index = hval;
list_add(&new_pb->pb_hash_list, &h->pb_hash);
} else {
- PB_STATS_INC(pb_miss_locked);
+ XFS_STATS_INC(pb_miss_locked);
}
spin_unlock(&h->pb_hash_lock);
@@ -686,7 +597,7 @@ found:
/* wait for buffer ownership */
PB_TRACE(pb, "get_lock", 0);
pagebuf_lock(pb);
- PB_STATS_INC(pb_get_locked_waited);
+ XFS_STATS_INC(pb_get_locked_waited);
} else {
/* We asked for a trylock and failed, no need
* to look at file offset and length here, we
@@ -696,7 +607,7 @@ found:
*/
pagebuf_rele(pb);
- PB_STATS_INC(pb_busy_locked);
+ XFS_STATS_INC(pb_busy_locked);
return (NULL);
}
} else {
@@ -711,7 +622,7 @@ found:
_PBF_MEM_ALLOCATED | \
_PBF_MEM_SLAB;
PB_TRACE(pb, "got_lock", 0);
- PB_STATS_INC(pb_get_locked);
+ XFS_STATS_INC(pb_get_locked);
return (pb);
}
@@ -767,7 +678,7 @@ pagebuf_get( /* allocate a buffer */
return (NULL);
}
- PB_STATS_INC(pb_get);
+ XFS_STATS_INC(pb_get);
/* fill in any missing pages */
error = _pagebuf_lookup_pages(pb, pb->pb_target->pbr_mapping, flags);
@@ -787,7 +698,7 @@ pagebuf_get( /* allocate a buffer */
if (flags & PBF_READ) {
if (PBF_NOT_DONE(pb)) {
PB_TRACE(pb, "get_read", (unsigned long)flags);
- PB_STATS_INC(pb_get_read);
+ XFS_STATS_INC(pb_get_read);
pagebuf_iostart(pb, flags);
} else if (flags & PBF_ASYNC) {
PB_TRACE(pb, "get_read_async", (unsigned long)flags);
@@ -1007,16 +918,21 @@ void
pagebuf_rele(
page_buf_t *pb)
{
+ pb_hash_t *hash = pb_hash(pb);
+
PB_TRACE(pb, "rele", pb->pb_relse);
- if (atomic_dec_and_test(&pb->pb_hold)) {
+ if (atomic_dec_and_lock(&pb->pb_hold, &hash->pb_hash_lock)) {
int do_free = 1;
if (pb->pb_relse) {
atomic_inc(&pb->pb_hold);
+ spin_unlock(&hash->pb_hash_lock);
(*(pb->pb_relse)) (pb);
+ spin_lock(&hash->pb_hash_lock);
do_free = 0;
}
+
if (pb->pb_flags & PBF_DELWRI) {
pb->pb_flags |= PBF_ASYNC;
atomic_inc(&pb->pb_hold);
@@ -1027,7 +943,11 @@ pagebuf_rele(
}
if (do_free) {
- __pagebuf_free(pb);
+ list_del_init(&pb->pb_hash_list);
+ spin_unlock(&hash->pb_hash_lock);
+ pagebuf_free(pb);
+ } else {
+ spin_unlock(&hash->pb_hash_lock);
}
}
}
@@ -1282,7 +1202,7 @@ pagebuf_iostart( /* start I/O on a buffer */
page_buf_t *pb, /* buffer to start */
page_buf_flags_t flags) /* PBF_LOCK, PBF_ASYNC, PBF_READ, */
/* PBF_WRITE, PBF_DELWRI, */
- /* PBF_SYNC, PBF_DONT_BLOCK */
+ /* PBF_DONT_BLOCK */
{
int status = 0;
@@ -1290,16 +1210,15 @@ pagebuf_iostart( /* start I/O on a buffer */
if (flags & PBF_DELWRI) {
pb->pb_flags &= ~(PBF_READ | PBF_WRITE | PBF_ASYNC);
- pb->pb_flags |= flags &
- (PBF_DELWRI | PBF_ASYNC | PBF_SYNC);
+ pb->pb_flags |= flags & (PBF_DELWRI | PBF_ASYNC);
pagebuf_delwri_queue(pb, 1);
return status;
}
- pb->pb_flags &= ~(PBF_READ | PBF_WRITE | PBF_ASYNC | \
- PBF_DELWRI | PBF_READ_AHEAD | PBF_RUN_QUEUES);
+ pb->pb_flags &= ~(PBF_READ | PBF_WRITE | PBF_ASYNC | PBF_DELWRI | \
+ PBF_READ_AHEAD | PBF_RUN_QUEUES);
pb->pb_flags |= flags & (PBF_READ | PBF_WRITE | PBF_ASYNC | \
- PBF_SYNC | PBF_READ_AHEAD | PBF_RUN_QUEUES);
+ PBF_READ_AHEAD | PBF_RUN_QUEUES);
BUG_ON(pb->pb_bn == PAGE_BUF_DADDR_NULL);
@@ -1655,7 +1574,7 @@ pagebuf_delwri_queue(
}
list_add_tail(&pb->pb_list, &pbd_delwrite_queue);
- pb->pb_flushtime = jiffies + pb_params.age_buffer.val;
+ pb->pb_flushtime = jiffies + xfs_age_buffer;
spin_unlock(&pbd_delwrite_lock);
if (unlock)
@@ -1703,7 +1622,7 @@ pagebuf_daemon(
struct list_head *curr, *next, tmp;
/* Set up the thread */
- daemonize("pagebufd");
+ daemonize("xfsbufd");
current->flags |= PF_MEMALLOC;
pagebuf_daemon_task = current;
@@ -1717,7 +1636,7 @@ pagebuf_daemon(
refrigerator(PF_IOTHREAD);
set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(pb_params.flush_interval.val);
+ schedule_timeout(xfs_flush_interval);
spin_lock(&pbd_delwrite_lock);
@@ -1876,112 +1795,6 @@ pagebuf_daemon_stop(void)
destroy_workqueue(pagebuf_dataio_workqueue);
}
-
-/*
- * Pagebuf sysctl interface
- */
-
-STATIC int
-pb_stats_clear_handler(
- ctl_table *ctl,
- int write,
- struct file *filp,
- void *buffer,
- size_t *lenp)
-{
- int c, ret;
- int *valp = ctl->data;
-
- ret = proc_dointvec_minmax(ctl, write, filp, buffer, lenp);
-
- if (!ret && write && *valp) {
- printk("XFS Clearing pbstats\n");
- for (c = 0; c < NR_CPUS; c++) {
- if (!cpu_possible(c)) continue;
- memset(&per_cpu(pbstats, c), 0,
- sizeof(struct pbstats));
- }
- pb_params.stats_clear.val = 0;
- }
-
- return ret;
-}
-
-STATIC struct ctl_table_header *pagebuf_table_header;
-
-STATIC ctl_table pagebuf_table[] = {
- {PB_FLUSH_INT, "flush_int", &pb_params.flush_interval.val,
- sizeof(int), 0644, NULL, &proc_dointvec_minmax,
- &sysctl_intvec, NULL,
- &pb_params.flush_interval.min, &pb_params.flush_interval.max},
-
- {PB_FLUSH_AGE, "flush_age", &pb_params.age_buffer.val,
- sizeof(int), 0644, NULL, &proc_dointvec_minmax,
- &sysctl_intvec, NULL,
- &pb_params.age_buffer.min, &pb_params.age_buffer.max},
-
- {PB_STATS_CLEAR, "stats_clear", &pb_params.stats_clear.val,
- sizeof(int), 0644, NULL, &pb_stats_clear_handler,
- &sysctl_intvec, NULL,
- &pb_params.stats_clear.min, &pb_params.stats_clear.max},
-
-#ifdef PAGEBUF_TRACE
- {PB_DEBUG, "debug", &pb_params.debug.val,
- sizeof(int), 0644, NULL, &proc_dointvec_minmax,
- &sysctl_intvec, NULL,
- &pb_params.debug.min, &pb_params.debug.max},
-#endif
- {0}
-};
-
-STATIC ctl_table pagebuf_dir_table[] = {
- {VM_PAGEBUF, "pagebuf", NULL, 0, 0555, pagebuf_table},
- {0}
-};
-
-STATIC ctl_table pagebuf_root_table[] = {
- {CTL_VM, "vm", NULL, 0, 0555, pagebuf_dir_table},
- {0}
-};
-
-#ifdef CONFIG_PROC_FS
-STATIC int
-pagebuf_readstats(
- char *buffer,
- char **start,
- off_t offset,
- int count,
- int *eof,
- void *data)
-{
- int c, i, len, val;
-
- len = 0;
- len += sprintf(buffer + len, "pagebuf");
- for (i = 0; i < sizeof(struct pbstats) / sizeof(u_int32_t); i++) {
- val = 0;
- for (c = 0 ; c < NR_CPUS; c++) {
- if (!cpu_possible(c)) continue;
- val += *(((u_int32_t*)&per_cpu(pbstats, c) + i));
- }
- len += sprintf(buffer + len, " %u", val);
- }
- buffer[len++] = '\n';
-
- if (offset >= len) {
- *start = buffer;
- *eof = 1;
- return 0;
- }
- *start = buffer + offset;
- if ((len -= offset) > count)
- return count;
- *eof = 1;
-
- return len;
-}
-#endif /* CONFIG_PROC_FS */
-
/*
* Initialization and Termination
*/
@@ -1991,14 +1804,6 @@ pagebuf_init(void)
{
int i;
- pagebuf_table_header = register_sysctl_table(pagebuf_root_table, 1);
-
-#ifdef CONFIG_PROC_FS
- if (proc_mkdir("fs/pagebuf", 0))
- create_proc_read_entry(
- "fs/pagebuf/stat", 0, 0, pagebuf_readstats, NULL);
-#endif
-
pagebuf_cache = kmem_cache_create("page_buf_t", sizeof(page_buf_t), 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (pagebuf_cache == NULL) {
@@ -2036,10 +1841,4 @@ pagebuf_terminate(void)
#endif
kmem_cache_destroy(pagebuf_cache);
-
- unregister_sysctl_table(pagebuf_table_header);
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("fs/pagebuf/stat", NULL);
- remove_proc_entry("fs/pagebuf", NULL);
-#endif
}
diff --git a/fs/xfs/linux/xfs_buf.h b/fs/xfs/linux/xfs_buf.h
index 4377710fd370..d58384ebebf9 100644
--- a/fs/xfs/linux/xfs_buf.h
+++ b/fs/xfs/linux/xfs_buf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -76,7 +76,6 @@ typedef enum page_buf_flags_e { /* pb_flags values */
PBF_ASYNC = (1 << 4), /* initiator will not wait for completion */
PBF_NONE = (1 << 5), /* buffer not read at all */
PBF_DELWRI = (1 << 6), /* buffer has dirty pages */
- PBF_SYNC = (1 << 8), /* force updates to disk */
PBF_STALE = (1 << 10), /* buffer has been staled, do not find it */
PBF_FS_MANAGED = (1 << 11), /* filesystem controls freeing memory */
PBF_FS_DATAIOD = (1 << 12), /* schedule IO completion on fs datad */
@@ -87,6 +86,7 @@ typedef enum page_buf_flags_e { /* pb_flags values */
PBF_DONT_BLOCK = (1 << 15), /* do not block in current thread */
/* flags used only internally */
+ _PBF_PAGECACHE = (1 << 16), /* backed by pagecache */
_PBF_ALL_PAGES_MAPPED = (1 << 18), /* all pages in range mapped */
_PBF_ADDR_ALLOCATED = (1 << 19), /* pb_addr space was allocated */
_PBF_MEM_ALLOCATED = (1 << 20), /* underlying pages are allocated */
@@ -260,7 +260,7 @@ extern int pagebuf_iostart( /* start I/O on a buffer */
page_buf_t *, /* buffer to start */
page_buf_flags_t); /* PBF_LOCK, PBF_ASYNC, */
/* PBF_READ, PBF_WRITE, */
- /* PBF_DELWRI, PBF_SYNC */
+ /* PBF_DELWRI */
extern int pagebuf_iorequest( /* start real I/O */
page_buf_t *); /* buffer to convey to device */
@@ -355,7 +355,7 @@ extern void pagebuf_trace(
#define XFS_BUF_BFLAGS(x) ((x)->pb_flags)
#define XFS_BUF_ZEROFLAGS(x) \
- ((x)->pb_flags &= ~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_SYNC|PBF_DELWRI))
+ ((x)->pb_flags &= ~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_DELWRI))
#define XFS_BUF_STALE(x) ((x)->pb_flags |= XFS_B_STALE)
#define XFS_BUF_UNSTALE(x) ((x)->pb_flags &= ~XFS_B_STALE)
@@ -558,7 +558,6 @@ static inline int XFS_bwrite(page_buf_t *pb)
int iowait = (pb->pb_flags & PBF_ASYNC) == 0;
int error = 0;
- pb->pb_flags |= PBF_SYNC;
if (!iowait)
pb->pb_flags |= PBF_RUN_QUEUES;
diff --git a/fs/xfs/linux/xfs_globals.c b/fs/xfs/linux/xfs_globals.c
index 9267e539fd13..73cf327841d2 100644
--- a/fs/xfs/linux/xfs_globals.c
+++ b/fs/xfs/linux/xfs_globals.c
@@ -61,6 +61,8 @@ xfs_param_t xfs_params = {
.inherit_sync = { 0, 1, 1 },
.inherit_nodump = { 0, 1, 1 },
.inherit_noatim = { 0, 1, 1 },
+ .flush_interval = { HZ/2, HZ, 30*HZ },
+ .age_buffer = { 1*HZ, 15*HZ, 300*HZ },
};
/*
diff --git a/fs/xfs/linux/xfs_ioctl.c b/fs/xfs/linux/xfs_ioctl.c
index 1c4faac8e919..b3cc8370b18e 100644
--- a/fs/xfs/linux/xfs_ioctl.c
+++ b/fs/xfs/linux/xfs_ioctl.c
@@ -699,9 +699,7 @@ xfs_ioctl(
error = xfs_set_dmattrs(bdp, dmi.fsd_dmevmask, dmi.fsd_dmstate,
NULL);
- if (error)
- return -error;
- return 0;
+ return -error;
}
case XFS_IOC_GETBMAP:
@@ -733,9 +731,7 @@ xfs_ioctl(
case XFS_IOC_SWAPEXT: {
error = xfs_swapext((struct xfs_swapext *)arg);
- if (error)
- return -error;
- return 0;
+ return -error;
}
case XFS_IOC_FSCOUNTS: {
@@ -763,6 +759,8 @@ xfs_ioctl(
/* input parameter is passed in resblks field of structure */
in = inout.resblks;
error = xfs_reserve_blocks(mp, &in, &inout);
+ if (error)
+ return -error;
if (copy_to_user((char *)arg, &inout, sizeof(inout)))
return -XFS_ERROR(EFAULT);
@@ -795,9 +793,7 @@ xfs_ioctl(
return -XFS_ERROR(EFAULT);
error = xfs_growfs_data(mp, &in);
- if (error)
- return -error;
- return 0;
+ return -error;
}
case XFS_IOC_FSGROWFSLOG: {
@@ -810,9 +806,7 @@ xfs_ioctl(
return -XFS_ERROR(EFAULT);
error = xfs_growfs_log(mp, &in);
- if (error)
- return -error;
- return 0;
+ return -error;
}
case XFS_IOC_FSGROWFSRT: {
@@ -825,9 +819,7 @@ xfs_ioctl(
return -XFS_ERROR(EFAULT);
error = xfs_growfs_rt(mp, &in);
- if (error)
- return -error;
- return 0;
+ return -error;
}
case XFS_IOC_FREEZE:
@@ -842,6 +834,19 @@ xfs_ioctl(
xfs_fs_thaw(mp);
return 0;
+ case XFS_IOC_GOINGDOWN: {
+ __uint32_t in;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (get_user(in, (__uint32_t *)arg))
+ return -XFS_ERROR(EFAULT);
+
+ error = xfs_fs_goingdown(mp, in);
+ return -error;
+ }
+
case XFS_IOC_ERROR_INJECTION: {
xfs_error_injection_t in;
@@ -849,9 +854,7 @@ xfs_ioctl(
return -XFS_ERROR(EFAULT);
error = xfs_errortag_add(in.errtag, mp);
- if (error)
- return -error;
- return 0;
+ return -error;
}
case XFS_IOC_ERROR_CLEARALL:
diff --git a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c
index 790aff8046ca..25f7260482c4 100644
--- a/fs/xfs/linux/xfs_iops.c
+++ b/fs/xfs/linux/xfs_iops.c
@@ -541,7 +541,6 @@ linvfs_setattr(
if (error)
return(-error); /* Positive error up from XFS */
if (ia_valid & ATTR_SIZE) {
- i_size_write(inode, vattr.va_size);
error = vmtruncate(inode, attr->ia_size);
}
@@ -631,8 +630,7 @@ linvfs_listxattr(
if (!size)
xflags |= ATTR_KERNOVAL;
- if (capable(CAP_SYS_ADMIN))
- xflags |= ATTR_KERNFULLS;
+ xflags |= capable(CAP_SYS_ADMIN) ? ATTR_KERNFULLS : ATTR_KERNORMALS;
error = attr_generic_list(vp, data, size, xflags, &result);
if (error < 0)
diff --git a/fs/xfs/linux/xfs_linux.h b/fs/xfs/linux/xfs_linux.h
index c6631b45d6af..e76b25c3b8a7 100644
--- a/fs/xfs/linux/xfs_linux.h
+++ b/fs/xfs/linux/xfs_linux.h
@@ -85,6 +85,7 @@
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
+#include <linux/version.h>
#include <asm/page.h>
#include <asm/div64.h>
@@ -138,6 +139,8 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
#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 current_cpu() smp_processor_id()
#define current_pid() (current->pid)
diff --git a/fs/xfs/linux/xfs_lrw.c b/fs/xfs/linux/xfs_lrw.c
index 4d49f8a33497..2077d8536208 100644
--- a/fs/xfs/linux/xfs_lrw.c
+++ b/fs/xfs/linux/xfs_lrw.c
@@ -283,7 +283,6 @@ xfs_read(
ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp);
mp = ip->i_mount;
- vn_trace_entry(vp, "xfs_read", (inst_t *)__return_address);
XFS_STATS_INC(xs_read_calls);
@@ -334,17 +333,19 @@ xfs_read(
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
!(ioflags & IO_INVIS)) {
- int error;
vrwlock_t locktype = VRWLOCK_READ;
- error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), *offset, size,
- FILP_DELAY_FLAG(file), &locktype);
- if (error) {
+ ret = XFS_SEND_DATA(mp, DM_EVENT_READ,
+ BHV_TO_VNODE(bdp), *offset, size,
+ FILP_DELAY_FLAG(file), &locktype);
+ if (ret) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- return -error;
+ return -ret;
}
}
+ xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
+ iovp, segs, *offset, ioflags);
ret = __generic_file_aio_read(iocb, iovp, segs, offset);
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -377,7 +378,6 @@ xfs_sendfile(
ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp);
mp = ip->i_mount;
- vn_trace_entry(vp, "xfs_sendfile", (inst_t *)__return_address);
XFS_STATS_INC(xs_read_calls);
@@ -405,6 +405,8 @@ xfs_sendfile(
return -error;
}
}
+ xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore,
+ target, count, *offset, ioflags);
ret = generic_file_sendfile(filp, offset, count, actor, target);
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -658,7 +660,6 @@ xfs_write(
XFS_STATS_INC(xs_write_calls);
vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, "xfs_write", (inst_t *)__return_address);
xip = XFS_BHVTOI(bdp);
/* START copy & waste from filemap.c */
@@ -678,7 +679,7 @@ xfs_write(
if (size == 0)
return 0;
- io = &(xip->i_iocore);
+ io = &xip->i_iocore;
mp = io->io_mount;
xfs_check_frozen(mp, bdp, XFS_FREEZE_WRITE);
@@ -729,11 +730,12 @@ start:
if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
!(ioflags & IO_INVIS) && !eventsent)) {
loff_t savedsize = *offset;
+ int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
xfs_iunlock(xip, XFS_ILOCK_EXCL);
error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, vp,
*offset, size,
- FILP_DELAY_FLAG(file), &locktype);
+ dmflags, &locktype);
if (error) {
xfs_iunlock(xip, iolock);
return -error;
diff --git a/fs/xfs/linux/xfs_lrw.h b/fs/xfs/linux/xfs_lrw.h
index eb4cc501a87f..731c88fa910c 100644
--- a/fs/xfs/linux/xfs_lrw.h
+++ b/fs/xfs/linux/xfs_lrw.h
@@ -45,9 +45,7 @@ struct xfs_iomap;
/*
* Defines for the trace mechanisms in xfs_lrw.c.
*/
-#define XFS_RW_KTRACE_SIZE 64
-#define XFS_STRAT_KTRACE_SIZE 64
-#define XFS_STRAT_GTRACE_SIZE 512
+#define XFS_RW_KTRACE_SIZE 128
#define XFS_READ_ENTER 1
#define XFS_WRITE_ENTER 2
@@ -69,6 +67,12 @@ struct xfs_iomap;
#define XFS_INVAL_CACHED 18
#define XFS_DIORD_ENTER 19
#define XFS_DIOWR_ENTER 20
+#define XFS_SENDFILE_ENTER 21
+#define XFS_WRITEPAGE_ENTER 22
+#define XFS_RELEASEPAGE_ENTER 23
+#define XFS_IOMAP_ALLOC_ENTER 24
+#define XFS_IOMAP_ALLOC_MAP 25
+#define XFS_IOMAP_UNWRITTEN 26
extern void xfs_rw_enter_trace(int, struct xfs_iocore *,
const struct iovec *, size_t, loff_t, int);
extern void xfs_inval_cached_trace(struct xfs_iocore *,
diff --git a/fs/xfs/linux/xfs_stats.c b/fs/xfs/linux/xfs_stats.c
index b076a6586444..b7de296e186d 100644
--- a/fs/xfs/linux/xfs_stats.c
+++ b/fs/xfs/linux/xfs_stats.c
@@ -67,6 +67,7 @@ xfs_read_xfsstats(
{ "attr", XFSSTAT_END_ATTRIBUTE_OPS },
{ "icluster", XFSSTAT_END_INODE_CLUSTER },
{ "vnodes", XFSSTAT_END_VNODE_OPS },
+ { "buf", XFSSTAT_END_BUF },
};
/* Loop over all stats groups */
diff --git a/fs/xfs/linux/xfs_stats.h b/fs/xfs/linux/xfs_stats.h
index cac986e80faf..04566006fabc 100644
--- a/fs/xfs/linux/xfs_stats.h
+++ b/fs/xfs/linux/xfs_stats.h
@@ -122,6 +122,16 @@ struct xfsstats {
__uint32_t vn_reclaim; /* # times vn_reclaim called */
__uint32_t vn_remove; /* # times vn_remove called */
__uint32_t vn_free; /* # times vn_free called */
+#define XFSSTAT_END_BUF (XFSSTAT_END_VNODE_OPS+9)
+ __uint32_t pb_get;
+ __uint32_t pb_create;
+ __uint32_t pb_get_locked;
+ __uint32_t pb_get_locked_waited;
+ __uint32_t pb_busy_locked;
+ __uint32_t pb_miss_locked;
+ __uint32_t pb_page_retries;
+ __uint32_t pb_page_found;
+ __uint32_t pb_get_read;
/* Extra precision counters */
__uint64_t xs_xstrat_bytes;
__uint64_t xs_write_bytes;
diff --git a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c
index 2b2e5deed00c..802f8ebf9dc2 100644
--- a/fs/xfs/linux/xfs_super.c
+++ b/fs/xfs/linux/xfs_super.c
@@ -453,7 +453,7 @@ syncd(void *arg)
vfs_t *vfsp = (vfs_t *) arg;
int error;
- daemonize("xfs_syncd");
+ daemonize("xfssyncd");
vfsp->vfs_sync_task = current;
wmb();
diff --git a/fs/xfs/linux/xfs_super.h b/fs/xfs/linux/xfs_super.h
index 2716ad9296fb..f905528a2ea3 100644
--- a/fs/xfs/linux/xfs_super.h
+++ b/fs/xfs/linux/xfs_super.h
@@ -44,6 +44,8 @@
#ifdef CONFIG_XFS_QUOTA
# define vfs_insertquota(vfs) vfs_insertops(vfsp, &xfs_qmops)
+extern void xfs_qm_init(void);
+extern void xfs_qm_exit(void);
# define vfs_initquota() xfs_qm_init()
# define vfs_exitquota() xfs_qm_exit()
#else
@@ -61,7 +63,7 @@
#endif
#ifdef CONFIG_XFS_SECURITY
-# define XFS_SECURITY_STRING "security attrs, "
+# define XFS_SECURITY_STRING "security attributes, "
# define ENOSECURITY 0
#else
# define XFS_SECURITY_STRING
diff --git a/fs/xfs/linux/xfs_sysctl.c b/fs/xfs/linux/xfs_sysctl.c
index 8eefeff3cabe..b9a97c9d77e5 100644
--- a/fs/xfs/linux/xfs_sysctl.c
+++ b/fs/xfs/linux/xfs_sysctl.c
@@ -117,6 +117,16 @@ STATIC ctl_table xfs_table[] = {
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
&sysctl_intvec, NULL,
&xfs_params.inherit_noatim.min, &xfs_params.inherit_noatim.max},
+
+ {XFS_FLUSH_INTERVAL, "flush_interval", &xfs_params.flush_interval.val,
+ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &xfs_params.flush_interval.min, &xfs_params.flush_interval.max},
+
+ {XFS_AGE_BUFFER, "age_buffer", &xfs_params.age_buffer.val,
+ sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+ &sysctl_intvec, NULL,
+ &xfs_params.age_buffer.min, &xfs_params.age_buffer.max},
/* please keep this the last entry */
#ifdef CONFIG_PROC_FS
diff --git a/fs/xfs/linux/xfs_sysctl.h b/fs/xfs/linux/xfs_sysctl.h
index 3f528fc49cd8..0532d4012e0d 100644
--- a/fs/xfs/linux/xfs_sysctl.h
+++ b/fs/xfs/linux/xfs_sysctl.h
@@ -58,6 +58,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_param_t;
/*
@@ -86,6 +90,8 @@ enum {
XFS_INHERIT_SYNC = 13,
XFS_INHERIT_NODUMP = 14,
XFS_INHERIT_NOATIME = 15,
+ XFS_FLUSH_INTERVAL = 16,
+ XFS_AGE_BUFFER = 17,
};
extern xfs_param_t xfs_params;
diff --git a/fs/xfs/linux/xfs_vfs.c b/fs/xfs/linux/xfs_vfs.c
index 00de03bbac06..63adf1d5988e 100644
--- a/fs/xfs/linux/xfs_vfs.c
+++ b/fs/xfs/linux/xfs_vfs.c
@@ -117,7 +117,6 @@ vfs_mntupdate(
return ((*bhvtovfsops(next)->vfs_mntupdate)(next, fl, args));
}
-
int
vfs_root(
struct bhv_desc *bdp,
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 14903f3c6906..74cad985b003 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -780,14 +780,8 @@ xfs_alloc_ag_vextent_near(
/*
* Randomly don't execute the first algorithm.
*/
- static int seed; /* randomizing seed value */
int dofirst; /* set to do first algorithm */
- timespec_t now; /* current time */
- if (!seed) {
- nanotime(&now);
- seed = (int)now.tv_sec ^ (int)now.tv_nsec;
- }
dofirst = random() & 1;
#endif
/*
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index c83011f9706d..bd58615573a4 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -91,10 +91,14 @@ extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *);
#define ATTR_CREATE 0x0010 /* pure create: fail if attr already exists */
#define ATTR_REPLACE 0x0020 /* pure set: fail if attr does not exist */
#define ATTR_SYSTEM 0x0100 /* use attrs in system (pseudo) namespace */
+
#define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */
#define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */
#define ATTR_KERNAMELS 0x4000 /* [kernel] list attr names (simple list) */
-#define ATTR_KERNFULLS 0x8000 /* [kernel] full attr list, ie. root+user */
+
+#define ATTR_KERNORMALS 0x0800 /* [kernel] normal attr list: user+secure */
+#define ATTR_KERNROOTLS 0x8000 /* [kernel] include root in the attr list */
+#define ATTR_KERNFULLS (ATTR_KERNORMALS|ATTR_KERNROOTLS)
/*
* The maximum size (into the kernel or returned from the kernel) of an
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 22f38db4ee9a..20a859457ef9 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -460,9 +460,15 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) {
attrnames_t *namesp;
+ if (((context->flags & ATTR_SECURE) != 0) !=
+ ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
+ !(context->flags & ATTR_KERNORMALS)) {
+ sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
+ continue;
+ }
if (((context->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0) &&
- !(context->flags & ATTR_KERNFULLS)) {
+ !(context->flags & ATTR_KERNROOTLS)) {
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
continue;
}
@@ -511,9 +517,15 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
kmem_free(sbuf, sbsize);
return XFS_ERROR(EFSCORRUPTED);
}
+ if (((context->flags & ATTR_SECURE) != 0) !=
+ ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
+ !(context->flags & ATTR_KERNORMALS)) {
+ sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
+ continue;
+ }
if (((context->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0) &&
- !(context->flags & ATTR_KERNFULLS)) {
+ !(context->flags & ATTR_KERNROOTLS)) {
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
continue;
}
@@ -2309,9 +2321,13 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
if (entry->flags & XFS_ATTR_INCOMPLETE)
continue; /* skip incomplete entries */
+ if (((context->flags & ATTR_SECURE) != 0) !=
+ ((entry->flags & XFS_ATTR_SECURE) != 0) &&
+ !(context->flags & ATTR_KERNORMALS))
+ continue; /* skip non-matching entries */
if (((context->flags & ATTR_ROOT) != 0) !=
((entry->flags & XFS_ATTR_ROOT) != 0) &&
- !(context->flags & ATTR_KERNFULLS))
+ !(context->flags & ATTR_KERNROOTLS))
continue; /* skip non-matching entries */
namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure :
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h
index 65a8785bf9a3..093236905d9e 100644
--- a/fs/xfs/xfs_clnt.h
+++ b/fs/xfs/xfs_clnt.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -57,10 +57,10 @@ struct xfs_mount_args {
int flags; /* flags -> see XFSMNT_... macros below */
int logbufs; /* Number of log buffers, -1 to default */
int logbufsize; /* Size of log buffers, -1 to default */
- char fsname[MAXNAMELEN]; /* data device name */
- char rtname[MAXNAMELEN]; /* realtime device filename */
- char logname[MAXNAMELEN]; /* journal device filename */
- char mtpt[MAXNAMELEN]; /* filesystem mount point */
+ char fsname[MAXNAMELEN+1]; /* data device name */
+ char rtname[MAXNAMELEN+1]; /* realtime device filename */
+ char logname[MAXNAMELEN+1]; /* journal device filename */
+ char mtpt[MAXNAMELEN+1]; /* filesystem mount point */
int sunit; /* stripe unit (BBs) */
int swidth; /* stripe width (BBs), multiple of sunit */
uchar_t iosizelog; /* log2 of the preferred I/O size */
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 344d4b34542e..53838b48b7d8 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -165,6 +165,27 @@ typedef enum {
#define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */
#define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */
+#define DM_FLAGS_ISEM 0x004 /* thread holds i_sem */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21)
+/* i_alloc_sem was added in 2.4.22-pre1 */
+#define DM_FLAGS_IALLOCSEM_RD 0x010 /* thread holds i_alloc_sem rd */
+#define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */
+#endif
+#endif
+
+/*
+ * Based on IO_ISDIRECT, decide which i_ flag is set.
+ */
+#ifdef DM_FLAGS_IALLOCSEM_RD
+#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
+ DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM)
+#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
+#else
+#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
+ 0 : DM_FLAGS_ISEM)
+#define DM_SEM_FLAG_WR (DM_FLAGS_ISEM)
+#endif
/*
* Macros to turn caller specified delay/block flags into
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
index f7ff546a3ac1..cec54ba800eb 100644
--- a/fs/xfs/xfs_dmops.c
+++ b/fs/xfs/xfs_dmops.c
@@ -43,7 +43,7 @@
#include "xfs_dmapi.h"
#include "xfs_mount.h"
-xfs_dmops_t xfs_dmcore_xfs = {
+xfs_dmops_t xfs_dmcore_stub = {
.xfs_send_data = (xfs_send_data_t)fs_nosys,
.xfs_send_mmap = (xfs_send_mmap_t)fs_noerr,
.xfs_send_destroy = (xfs_send_destroy_t)fs_nosys,
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 273e7384fa4f..1ed650e902d2 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -437,6 +437,12 @@ typedef struct xfs_handle {
#define FSHSIZE sizeof(fsid_t)
+/*
+ * Flags for going down operation
+ */
+#define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */
+#define XFS_FSOP_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */
+#define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */
/*
* ioctl commands that replace IRIX fcntl()'s
@@ -490,6 +496,7 @@ typedef struct xfs_handle {
#define XFS_IOC_ATTRLIST_BY_HANDLE _IOW ('X', 122, struct xfs_fsop_attrlist_handlereq)
#define XFS_IOC_ATTRMULTI_BY_HANDLE _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq)
#define XFS_IOC_FSGEOMETRY _IOR ('X', 124, struct xfs_fsop_geom)
+#define XFS_IOC_GOINGDOWN _IOR ('X', 125, __uint32_t)
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 468df046644e..d6a6d056c34e 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -626,3 +626,28 @@ xfs_fs_thaw(
xfs_finish_freeze(mp);
return 0;
}
+
+int
+xfs_fs_goingdown(
+ xfs_mount_t *mp,
+ __uint32_t inflags)
+{
+ switch (inflags)
+ {
+ case XFS_FSOP_GOING_FLAGS_DEFAULT:
+ xfs_fs_freeze(mp);
+ xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
+ xfs_fs_thaw(mp);
+ break;
+ case XFS_FSOP_GOING_FLAGS_LOGFLUSH:
+ xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
+ break;
+ case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH:
+ xfs_force_shutdown(mp, XFS_FORCE_UMOUNT|XFS_LOG_IO_ERROR);
+ break;
+ default:
+ return XFS_ERROR(EINVAL);
+ }
+
+ return 0;
+}
diff --git a/fs/xfs/xfs_fsops.h b/fs/xfs/xfs_fsops.h
index 76adb1e30bcb..70b0f125767b 100644
--- a/fs/xfs/xfs_fsops.h
+++ b/fs/xfs/xfs_fsops.h
@@ -67,4 +67,9 @@ int
xfs_fs_thaw(
xfs_mount_t *mp);
+int
+xfs_fs_goingdown(
+ xfs_mount_t *mp,
+ __uint32_t inflags);
+
#endif /* __XFS_FSOPS_H__ */
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index c8bc49d3deb4..0835763a83ea 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -69,6 +69,76 @@
#include "xfs_utils.h"
#include "xfs_iomap.h"
+#if defined(XFS_RW_TRACE)
+void
+xfs_iomap_enter_trace(
+ int tag,
+ xfs_iocore_t *io,
+ xfs_off_t offset,
+ ssize_t count)
+{
+ xfs_inode_t *ip = XFS_IO_INODE(io);
+
+ if (!ip->i_rwtrace)
+ return;
+
+ ktrace_enter(ip->i_rwtrace,
+ (void *)((unsigned long)tag),
+ (void *)ip,
+ (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)),
+ (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)),
+ (void *)((unsigned long)((offset >> 32) & 0xffffffff)),
+ (void *)((unsigned long)(offset & 0xffffffff)),
+ (void *)((unsigned long)count),
+ (void *)((unsigned long)((io->io_new_size >> 32) & 0xffffffff)),
+ (void *)((unsigned long)(io->io_new_size & 0xffffffff)),
+ (void *)NULL,
+ (void *)NULL,
+ (void *)NULL,
+ (void *)NULL,
+ (void *)NULL,
+ (void *)NULL,
+ (void *)NULL);
+}
+
+void
+xfs_iomap_map_trace(
+ int tag,
+ xfs_iocore_t *io,
+ xfs_off_t offset,
+ ssize_t count,
+ xfs_iomap_t *iomapp,
+ xfs_bmbt_irec_t *imapp,
+ int flags)
+{
+ xfs_inode_t *ip = XFS_IO_INODE(io);
+
+ if (!ip->i_rwtrace)
+ return;
+
+ ktrace_enter(ip->i_rwtrace,
+ (void *)((unsigned long)tag),
+ (void *)ip,
+ (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)),
+ (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)),
+ (void *)((unsigned long)((offset >> 32) & 0xffffffff)),
+ (void *)((unsigned long)(offset & 0xffffffff)),
+ (void *)((unsigned long)count),
+ (void *)((unsigned long)flags),
+ (void *)((unsigned long)((iomapp->iomap_offset >> 32) & 0xffffffff)),
+ (void *)((unsigned long)(iomapp->iomap_offset & 0xffffffff)),
+ (void *)((unsigned long)(iomapp->iomap_delta)),
+ (void *)((unsigned long)(iomapp->iomap_bsize)),
+ (void *)((unsigned long)(iomapp->iomap_bn)),
+ (void *)(__psint_t)(imapp->br_startoff),
+ (void *)((unsigned long)(imapp->br_blockcount)),
+ (void *)(__psint_t)(imapp->br_startblock));
+}
+#else
+#define xfs_iomap_enter_trace(tag, io, offset, count)
+#define xfs_iomap_map_trace(tag, io, offset, count, iomapp, imapp, flags)
+#endif
+
#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
<< mp->m_writeio_log)
#define XFS_STRAT_WRITE_IMAPS 2
@@ -149,17 +219,20 @@ xfs_iomap(
(BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE |
BMAPI_UNWRITTEN | BMAPI_DEVICE)) {
case BMAPI_READ:
+ xfs_iomap_enter_trace(XFS_IOMAP_READ_ENTER, io, offset, count);
lockmode = XFS_LCK_MAP_SHARED(mp, io);
bmapi_flags = XFS_BMAPI_ENTIRE;
if (flags & BMAPI_IGNSTATE)
bmapi_flags |= XFS_BMAPI_IGSTATE;
break;
case BMAPI_WRITE:
+ xfs_iomap_enter_trace(XFS_IOMAP_WRITE_ENTER, io, offset, count);
lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR;
bmapi_flags = 0;
XFS_ILOCK(mp, io, lockmode);
break;
case BMAPI_ALLOCATE:
+ xfs_iomap_enter_trace(XFS_IOMAP_ALLOC_ENTER, io, offset, count);
lockmode = XFS_ILOCK_SHARED|XFS_EXTSIZE_RD;
bmapi_flags = XFS_BMAPI_ENTIRE;
/* Attempt non-blocking lock */
@@ -201,8 +274,11 @@ phase2:
switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) {
case BMAPI_WRITE:
/* If we found an extent, return it */
- if (nimaps && (imap.br_startblock != HOLESTARTBLOCK))
+ if (nimaps && (imap.br_startblock != HOLESTARTBLOCK)) {
+ xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io,
+ offset, count, iomapp, &imap, flags);
break;
+ }
if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) {
error = XFS_IOMAP_WRITE_DIRECT(mp, io, offset,
@@ -211,6 +287,10 @@ phase2:
error = XFS_IOMAP_WRITE_DELAY(mp, io, offset, count,
flags, &imap, &nimaps);
}
+ if (!error) {
+ xfs_iomap_map_trace(XFS_IOMAP_ALLOC_MAP, io,
+ offset, count, iomapp, &imap, flags);
+ }
iomap_flags = IOMAP_NEW;
break;
case BMAPI_ALLOCATE:
@@ -218,8 +298,11 @@ phase2:
XFS_IUNLOCK(mp, io, lockmode);
lockmode = 0;
- if (nimaps && !ISNULLSTARTBLOCK(imap.br_startblock))
+ if (nimaps && !ISNULLSTARTBLOCK(imap.br_startblock)) {
+ xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io,
+ offset, count, iomapp, &imap, flags);
break;
+ }
error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps);
break;
@@ -309,7 +392,6 @@ xfs_iomap_write_direct(
* Make sure that the dquots are there. This doesn't hold
* the ilock across a disk read.
*/
-
error = XFS_QM_DQATTACH(ip->i_mount, ip, XFS_QMOPT_ILOCKED);
if (error)
return XFS_ERROR(error);
@@ -540,8 +622,9 @@ retry:
* If bmapi returned us nothing, and if we didn't get back EDQUOT,
* then we must have run out of space.
*/
-
if (nimaps == 0) {
+ xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE,
+ io, offset, count);
if (xfs_flush_space(ip, &fsynced, &ioflag))
return XFS_ERROR(ENOSPC);
@@ -584,7 +667,6 @@ xfs_iomap_write_allocate(
/*
* Make sure that the dquots are there.
*/
-
if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
return XFS_ERROR(error);
@@ -612,7 +694,6 @@ xfs_iomap_write_allocate(
XFS_WRITE_LOG_RES(mp),
0, XFS_TRANS_PERM_LOG_RES,
XFS_WRITE_LOG_COUNT);
-
if (error == ENOSPC) {
error = xfs_trans_reserve(tp, 0,
XFS_WRITE_LOG_RES(mp),
@@ -653,19 +734,16 @@ xfs_iomap_write_allocate(
error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb,
XFS_BMAPI_WRITE, &first_block, 1,
imap, &nimaps, &free_list);
-
if (error)
goto trans_cancel;
error = xfs_bmap_finish(&tp, &free_list,
first_block, &committed);
-
if (error)
goto trans_cancel;
error = xfs_trans_commit(tp,
XFS_TRANS_RELEASE_LOG_RES, NULL);
-
if (error)
goto error0;
@@ -725,6 +803,9 @@ xfs_iomap_write_unwritten(
xfs_fsblock_t firstfsb;
xfs_bmap_free_t free_list;
+ xfs_iomap_enter_trace(XFS_IOMAP_UNWRITTEN,
+ &ip->i_iocore, offset, count);
+
offset_fsb = XFS_B_TO_FSBT(mp, offset);
count_fsb = XFS_B_TO_FSB(mp, count);
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 22bbddd72d98..64ec764422dd 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -759,8 +759,9 @@ xfs_log_move_tail(xfs_mount_t *mp,
/* Also an invalid lsn. 1 implies that we aren't passing in a valid
* tail_lsn.
*/
- if (tail_lsn != 1)
+ if (tail_lsn != 1) {
log->l_tail_lsn = tail_lsn;
+ }
if ((tic = log->l_write_headq)) {
#ifdef DEBUG
@@ -866,10 +867,11 @@ xlog_assign_tail_lsn(xfs_mount_t *mp)
tail_lsn = xfs_trans_tail_ail(mp);
s = GRANT_LOCK(log);
- if (tail_lsn != 0)
+ if (tail_lsn != 0) {
log->l_tail_lsn = tail_lsn;
- else
+ } else {
tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn;
+ }
GRANT_UNLOCK(log, s);
return tail_lsn;
@@ -921,10 +923,8 @@ xlog_space_left(xlog_t *log, int cycle, int bytes)
* In this case we just want to return the size of the
* log as the amount of space left.
*/
-/* This assert does not take into account padding from striped log writes *
ASSERT((tail_cycle == (cycle + 1)) ||
((bytes + log->l_roundoff) >= tail_bytes));
-*/
free_bytes = log->l_logsize;
}
return free_bytes;
@@ -1183,14 +1183,6 @@ xlog_alloc_log(xfs_mount_t *mp,
log->l_grant_reserve_cycle = 1;
log->l_grant_write_cycle = 1;
- if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
- if (mp->m_sb.sb_logsunit <= 1) {
- log->l_stripemask = 1;
- } else {
- log->l_stripemask = 1 <<
- xfs_highbit32(mp->m_sb.sb_logsunit >> BBSHIFT);
- }
- }
if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) {
log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
ASSERT(log->l_sectbb_log <= mp->m_sectbb_log);
@@ -1401,45 +1393,35 @@ xlog_sync(xlog_t *log,
xfs_caddr_t dptr; /* pointer to byte sized element */
xfs_buf_t *bp;
int i, ops;
- uint roundup;
uint count; /* byte count of bwrite */
+ uint count_init; /* initial count before roundup */
int split = 0; /* split write into two regions */
int error;
XFS_STATS_INC(xs_log_writes);
ASSERT(iclog->ic_refcnt == 0);
- /* Round out the log write size */
- if (iclog->ic_offset & BBMASK) {
- /* count of 0 is already accounted for up in
- * xlog_state_sync_all(). Once in this routine,
- * operations on the iclog are single threaded.
- *
- * Difference between rounded up size and size
- */
- count = iclog->ic_offset & BBMASK;
- iclog->ic_roundoff += BBSIZE - count;
- }
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- unsigned sunit = BTOBB(log->l_mp->m_sb.sb_logsunit);
- if (!sunit)
- sunit = 1;
+ /* Add for LR header */
+ count_init = log->l_iclog_hsize + iclog->ic_offset;
- count = BTOBB(log->l_iclog_hsize + iclog->ic_offset);
- if (count & (sunit - 1)) {
- roundup = sunit - (count & (sunit - 1));
- } else {
- roundup = 0;
- }
- iclog->ic_offset += BBTOB(roundup);
+ /* Round out the log write size */
+ if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
+ log->l_mp->m_sb.sb_logsunit > 1) {
+ /* we have a v2 stripe unit to use */
+ count = XLOG_LSUNITTOB(log, XLOG_BTOLSUNIT(log, count_init));
+ } else {
+ count = BBTOB(BTOBB(count_init));
}
-
+ iclog->ic_roundoff = count - count_init;
log->l_roundoff += iclog->ic_roundoff;
xlog_pack_data(log, iclog); /* put cycle number in every block */
/* real byte length */
- INT_SET(iclog->ic_header.h_len, ARCH_CONVERT, iclog->ic_offset);
+ INT_SET(iclog->ic_header.h_len,
+ ARCH_CONVERT,
+ iclog->ic_offset + iclog->ic_roundoff);
+
/* put ops count in correct order */
ops = iclog->ic_header.h_num_logops;
INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops);
@@ -1449,12 +1431,6 @@ xlog_sync(xlog_t *log,
XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
XFS_BUF_SET_ADDR(bp, BLOCK_LSN(iclog->ic_header.h_lsn, ARCH_CONVERT));
- /* Count is already rounded up to a BBSIZE above */
- count = iclog->ic_offset + iclog->ic_roundoff;
- ASSERT((count & BBMASK) == 0);
-
- /* Add for LR header */
- count += log->l_iclog_hsize;
XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
/* Do we need to split this write into 2 parts? */
@@ -2783,8 +2759,6 @@ xlog_state_switch_iclogs(xlog_t *log,
xlog_in_core_t *iclog,
int eventual_size)
{
- uint roundup;
-
ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE);
if (!eventual_size)
eventual_size = iclog->ic_offset;
@@ -2797,14 +2771,10 @@ xlog_state_switch_iclogs(xlog_t *log,
log->l_curr_block += BTOBB(eventual_size)+BTOBB(log->l_iclog_hsize);
/* Round up to next log-sunit */
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- if (log->l_curr_block & (log->l_stripemask - 1)) {
- roundup = log->l_stripemask -
- (log->l_curr_block & (log->l_stripemask - 1));
- } else {
- roundup = 0;
- }
- log->l_curr_block += roundup;
+ if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
+ log->l_mp->m_sb.sb_logsunit > 1) {
+ __uint32_t sunit_bb = BTOBB(log->l_mp->m_sb.sb_logsunit);
+ log->l_curr_block = roundup(log->l_curr_block, sunit_bb);
}
if (log->l_curr_block >= log->l_logBBsize) {
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index c8b55ce4021a..02bddab09e14 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -63,6 +63,9 @@ int xlog_btolrbb(int b);
#else
#define XLOG_BTOLRBB(b) (((b)+XLOG_RECORD_BSIZE-1) >> XLOG_RECORD_BSHIFT)
#endif
+#define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \
+ (log)->l_mp->m_sb.sb_logsunit)
+#define XLOG_LSUNITTOB(log, su) ((su) * (log)->l_mp->m_sb.sb_logsunit)
#define XLOG_HEADER_SIZE 512
@@ -531,7 +534,6 @@ typedef struct log {
uint l_flags;
uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */
struct xfs_buf_cancel **l_buf_cancel_table;
- int l_stripemask; /* log stripe mask */
int l_iclog_hsize; /* size of iclog header */
int l_iclog_heads; /* # of iclog header sectors */
uint l_sectbb_log; /* log2 of sector size in BBs */
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index f028eac24642..88eba53d8889 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3416,6 +3416,7 @@ xlog_unpack_data_checksum(
{
uint *up = (uint *)dp;
uint chksum = 0;
+ int i;
/* divide length by 4 to get # words */
for (i=0; i < INT_GET(rhead->h_len, ARCH_CONVERT) >> 2; i++) {
@@ -3476,7 +3477,7 @@ xlog_valid_rec_header(
xlog_rec_header_t *rhead,
xfs_daddr_t blkno)
{
- int bblks;
+ int hlen;
if (unlikely(
(INT_GET(rhead->h_magicno, ARCH_CONVERT) !=
@@ -3495,8 +3496,8 @@ xlog_valid_rec_header(
}
/* LR body must have data or it wouldn't have been written */
- bblks = INT_GET(rhead->h_len, ARCH_CONVERT);
- if (unlikely( bblks <= 0 || bblks > INT_MAX )) {
+ hlen = INT_GET(rhead->h_len, ARCH_CONVERT);
+ if (unlikely( hlen <= 0 || hlen > INT_MAX )) {
XFS_ERROR_REPORT("xlog_valid_rec_header(2)",
XFS_ERRLEVEL_LOW, log->l_mp);
return XFS_ERROR(EFSCORRUPTED);
@@ -3658,7 +3659,7 @@ xlog_do_recovery_pass(
error = xlog_bread(log, 0, wrapped_hblks, hbp);
if (error)
goto bread_err2;
- XFS_BUF_SET_PTR(hbp, bufaddr, hblks);
+ XFS_BUF_SET_PTR(hbp, bufaddr, BBTOB(hblks));
if (!offset)
offset = xlog_align(log, 0,
wrapped_hblks, hbp);
@@ -3716,8 +3717,7 @@ xlog_do_recovery_pass(
if ((error = xlog_bread(log, wrapped_hblks,
bblks - split_bblks, dbp)))
goto bread_err2;
- XFS_BUF_SET_PTR(dbp, bufaddr,
- XLOG_BIG_RECORD_BSIZE);
+ XFS_BUF_SET_PTR(dbp, bufaddr, h_size);
if (!offset)
offset = xlog_align(log, wrapped_hblks,
bblks - split_bblks, dbp);
@@ -4042,7 +4042,7 @@ xlog_recover_check_summary(
XFS_FSS_TO_BB(mp, 1), 0);
if (XFS_BUF_ISERROR(agibp)) {
xfs_ioerror_alert("xlog_recover_check_summary(agi)",
- log->l_mp, agibp, agidaddr);
+ mp, agibp, agidaddr);
}
agip = XFS_BUF_TO_AGI(agibp);
ASSERT(XFS_AGI_MAGIC ==
@@ -4058,7 +4058,8 @@ xlog_recover_check_summary(
sbbp = xfs_getsb(mp, 0);
#ifdef XFS_LOUD_RECOVERY
- sbp = XFS_BUF_TO_SBP(sbbp);
+ sbp = &mp->m_sb;
+ xfs_xlatesb(XFS_BUF_TO_SBP(sbbp), sbp, 1, ARCH_CONVERT, XFS_SB_ALL_BITS);
cmn_err(CE_NOTE,
"xlog_recover_check_summary: sb_icount %Lu itotal %Lu",
sbp->sb_icount, itotal);
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 6fbf59781645..67d89b48148a 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -675,6 +675,7 @@ xfs_mountfs(
error = XFS_ERROR(EINVAL);
goto error1;
}
+ mp->m_dalign = mp->m_swidth = 0;
} else {
/*
* Convert the stripe unit and width to FSBs.
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 50501d09ddf5..ea86fbaffd40 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -571,8 +571,8 @@ extern void xfs_check_frozen(xfs_mount_t *, bhv_desc_t *, int);
extern struct vfsops xfs_vfsops;
extern struct vnodeops xfs_vnodeops;
-extern struct xfs_dmops xfs_dmcore_xfs;
-extern struct xfs_qmops xfs_qmcore_xfs;
+extern struct xfs_dmops xfs_dmcore_stub;
+extern struct xfs_qmops xfs_qmcore_stub;
extern struct xfs_ioops xfs_iocore_xfs;
extern int xfs_init(void);
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 1fea2e1d567f..4f40c92863d5 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -54,7 +54,7 @@ xfs_dqvopchown_default(
return NULL;
}
-xfs_qmops_t xfs_qmcore_xfs = {
+xfs_qmops_t xfs_qmcore_stub = {
.xfs_qminit = (xfs_qminit_t) fs_noerr,
.xfs_qmdone = (xfs_qmdone_t) fs_noerr,
.xfs_qmmount = (xfs_qmmount_t) fs_noerr,
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index d7041e5ac237..8cddc16397de 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -347,9 +347,6 @@ extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
extern struct bhv_vfsops xfs_qmops;
-extern void xfs_qm_init(void);
-extern void xfs_qm_exit(void);
-
#endif /* __KERNEL__ */
#endif /* __XFS_QUOTA_H__ */
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 2ecd9b3dc74d..d27b8765a936 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -451,9 +451,9 @@ xfs_mount(
* Setup xfs_mount function vectors from available behaviors
*/
p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM);
- mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_xfs;
+ mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub;
p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM);
- mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_xfs;
+ mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub;
p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
@@ -792,8 +792,9 @@ xfs_statvfs(
#if XFS_BIG_INUMS
if (!mp->m_inoadd)
#endif
- statp->f_files =
- min_t(sector_t, statp->f_files, mp->m_maxicount);
+ statp->f_files = min_t(typeof(statp->f_files),
+ statp->f_files,
+ mp->m_maxicount);
statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
XFS_SB_UNLOCK(mp, s);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 3e283bbf8a64..6440404fbca2 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -413,8 +413,9 @@ xfs_setattr(
} else {
if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) &&
!(flags & ATTR_DMI)) {
+ int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR;
code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp,
- vap->va_size, 0, AT_DELAY_FLAG(flags), NULL);
+ vap->va_size, 0, dmflags, NULL);
if (code) {
lock_flags = 0;
goto error_return;