Commit 9004fd8a authored by Nathan Scott's avatar Nathan Scott

Merge nathans@xfs.org:/export/hose/bkroot/xfs-linux-2.6

into sgi.com:/source2/xfs-linux-2.6
parents 961c380c 2a6d76e4
...@@ -130,7 +130,6 @@ xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o ...@@ -130,7 +130,6 @@ xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o
# Objects in linux/ # Objects in linux/
xfs-y += $(addprefix linux/, \ xfs-y += $(addprefix linux/, \
mrlock.o \
xfs_aops.o \ xfs_aops.o \
xfs_buf.o \ xfs_buf.o \
xfs_file.o \ xfs_file.o \
......
/*
* 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);
}
/* /*
* 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 * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -32,56 +32,73 @@ ...@@ -32,56 +32,73 @@
#ifndef __XFS_SUPPORT_MRLOCK_H__ #ifndef __XFS_SUPPORT_MRLOCK_H__
#define __XFS_SUPPORT_MRLOCK_H__ #define __XFS_SUPPORT_MRLOCK_H__
#include <linux/time.h> #include <linux/rwsem.h>
#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/semaphore.h>
/* enum { MR_NONE, MR_ACCESS, MR_UPDATE };
* 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.
*/
typedef struct mrlock_s { typedef struct {
int mr_count; struct rw_semaphore mr_lock;
unsigned short mr_reads_waiting; int mr_writer;
unsigned short mr_writes_waiting;
wait_queue_head_t mr_readerq;
wait_queue_head_t mr_writerq;
spinlock_t mr_lock;
} mrlock_t; } mrlock_t;
#define MR_ACCESS 1 #define mrinit(mrp, name) \
#define MR_UPDATE 2 ( (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 static inline void mraccessf(mrlock_t *mrp, int flags)
#define MRLOCK_ALLOW_EQUAL_PRI 0x8 {
down_read(&mrp->mr_lock);
}
/* static inline void mrupdatef(mrlock_t *mrp, int flags)
* mraccessf/mrupdatef take flags to be passed in while sleeping; {
* only PLTWAIT is currently supported. down_write(&mrp->mr_lock);
*/ mrp->mr_writer = 1;
}
extern void mraccessf(mrlock_t *, int); static inline int mrtryaccess(mrlock_t *mrp)
extern void mrupdatef(mrlock_t *, int); {
extern void mrlock(mrlock_t *, int, int); return down_read_trylock(&mrp->mr_lock);
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 *);
extern int ismrlocked(mrlock_t *, int); static inline int mrtryupdate(mrlock_t *mrp)
extern void mrlock_init(mrlock_t *, int type, char *name, long sequence); {
extern void mrfree(mrlock_t *); 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) static inline void mrunlock(mrlock_t *mrp)
#define mraccess(mrp) mraccessf(mrp, 0) /* grab for READ/ACCESS */ {
#define mrupdate(mrp) mrupdatef(mrp, 0) /* grab for WRITE/UPDATE */ if (mrp->mr_writer) {
#define mrislocked_access(mrp) ((mrp)->mr_count > 0) mrp->mr_writer = 0;
#define mrislocked_update(mrp) ((mrp)->mr_count < 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__ */ #endif /* __XFS_SUPPORT_MRLOCK_H__ */
This diff is collapsed.
This diff is collapsed.
/* /*
* 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 * 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 * 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 */ ...@@ -76,7 +76,6 @@ typedef enum page_buf_flags_e { /* pb_flags values */
PBF_ASYNC = (1 << 4), /* initiator will not wait for completion */ PBF_ASYNC = (1 << 4), /* initiator will not wait for completion */
PBF_NONE = (1 << 5), /* buffer not read at all */ PBF_NONE = (1 << 5), /* buffer not read at all */
PBF_DELWRI = (1 << 6), /* buffer has dirty pages */ 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_STALE = (1 << 10), /* buffer has been staled, do not find it */
PBF_FS_MANAGED = (1 << 11), /* filesystem controls freeing memory */ PBF_FS_MANAGED = (1 << 11), /* filesystem controls freeing memory */
PBF_FS_DATAIOD = (1 << 12), /* schedule IO completion on fs datad */ PBF_FS_DATAIOD = (1 << 12), /* schedule IO completion on fs datad */
...@@ -87,6 +86,7 @@ typedef enum page_buf_flags_e { /* pb_flags values */ ...@@ -87,6 +86,7 @@ typedef enum page_buf_flags_e { /* pb_flags values */
PBF_DONT_BLOCK = (1 << 15), /* do not block in current thread */ PBF_DONT_BLOCK = (1 << 15), /* do not block in current thread */
/* flags used only internally */ /* flags used only internally */
_PBF_PAGECACHE = (1 << 16), /* backed by pagecache */
_PBF_ALL_PAGES_MAPPED = (1 << 18), /* all pages in range mapped */ _PBF_ALL_PAGES_MAPPED = (1 << 18), /* all pages in range mapped */
_PBF_ADDR_ALLOCATED = (1 << 19), /* pb_addr space was allocated */ _PBF_ADDR_ALLOCATED = (1 << 19), /* pb_addr space was allocated */
_PBF_MEM_ALLOCATED = (1 << 20), /* underlying pages are allocated */ _PBF_MEM_ALLOCATED = (1 << 20), /* underlying pages are allocated */
...@@ -260,7 +260,7 @@ extern int pagebuf_iostart( /* start I/O on a buffer */ ...@@ -260,7 +260,7 @@ extern int pagebuf_iostart( /* start I/O on a buffer */
page_buf_t *, /* buffer to start */ page_buf_t *, /* buffer to start */
page_buf_flags_t); /* PBF_LOCK, PBF_ASYNC, */ page_buf_flags_t); /* PBF_LOCK, PBF_ASYNC, */
/* PBF_READ, PBF_WRITE, */ /* PBF_READ, PBF_WRITE, */
/* PBF_DELWRI, PBF_SYNC */ /* PBF_DELWRI */
extern int pagebuf_iorequest( /* start real I/O */ extern int pagebuf_iorequest( /* start real I/O */
page_buf_t *); /* buffer to convey to device */ page_buf_t *); /* buffer to convey to device */
...@@ -355,7 +355,7 @@ extern void pagebuf_trace( ...@@ -355,7 +355,7 @@ extern void pagebuf_trace(
#define XFS_BUF_BFLAGS(x) ((x)->pb_flags) #define XFS_BUF_BFLAGS(x) ((x)->pb_flags)
#define XFS_BUF_ZEROFLAGS(x) \ #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_STALE(x) ((x)->pb_flags |= XFS_B_STALE)
#define XFS_BUF_UNSTALE(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) ...@@ -558,7 +558,6 @@ static inline int XFS_bwrite(page_buf_t *pb)
int iowait = (pb->pb_flags & PBF_ASYNC) == 0; int iowait = (pb->pb_flags & PBF_ASYNC) == 0;
int error = 0; int error = 0;
pb->pb_flags |= PBF_SYNC;
if (!iowait) if (!iowait)
pb->pb_flags |= PBF_RUN_QUEUES; pb->pb_flags |= PBF_RUN_QUEUES;
......
...@@ -61,6 +61,8 @@ xfs_param_t xfs_params = { ...@@ -61,6 +61,8 @@ xfs_param_t xfs_params = {
.inherit_sync = { 0, 1, 1 }, .inherit_sync = { 0, 1, 1 },
.inherit_nodump = { 0, 1, 1 }, .inherit_nodump = { 0, 1, 1 },
.inherit_noatim = { 0, 1, 1 }, .inherit_noatim = { 0, 1, 1 },
.flush_interval = { HZ/2, HZ, 30*HZ },
.age_buffer = { 1*HZ, 15*HZ, 300*HZ },
}; };
/* /*
......
...@@ -699,9 +699,7 @@ xfs_ioctl( ...@@ -699,9 +699,7 @@ xfs_ioctl(
error = xfs_set_dmattrs(bdp, dmi.fsd_dmevmask, dmi.fsd_dmstate, error = xfs_set_dmattrs(bdp, dmi.fsd_dmevmask, dmi.fsd_dmstate,
NULL); NULL);
if (error)
return -error; return -error;
return 0;
} }
case XFS_IOC_GETBMAP: case XFS_IOC_GETBMAP:
...@@ -733,9 +731,7 @@ xfs_ioctl( ...@@ -733,9 +731,7 @@ xfs_ioctl(
case XFS_IOC_SWAPEXT: { case XFS_IOC_SWAPEXT: {
error = xfs_swapext((struct xfs_swapext *)arg); error = xfs_swapext((struct xfs_swapext *)arg);
if (error)
return -error; return -error;
return 0;
} }
case XFS_IOC_FSCOUNTS: { case XFS_IOC_FSCOUNTS: {
...@@ -763,6 +759,8 @@ xfs_ioctl( ...@@ -763,6 +759,8 @@ xfs_ioctl(
/* input parameter is passed in resblks field of structure */ /* input parameter is passed in resblks field of structure */
in = inout.resblks; in = inout.resblks;
error = xfs_reserve_blocks(mp, &in, &inout); error = xfs_reserve_blocks(mp, &in, &inout);
if (error)
return -error;
if (copy_to_user((char *)arg, &inout, sizeof(inout))) if (copy_to_user((char *)arg, &inout, sizeof(inout)))
return -XFS_ERROR(EFAULT); return -XFS_ERROR(EFAULT);
...@@ -795,9 +793,7 @@ xfs_ioctl( ...@@ -795,9 +793,7 @@ xfs_ioctl(
return -XFS_ERROR(EFAULT); return -XFS_ERROR(EFAULT);
error = xfs_growfs_data(mp, &in); error = xfs_growfs_data(mp, &in);
if (error)
return -error; return -error;
return 0;
} }
case XFS_IOC_FSGROWFSLOG: { case XFS_IOC_FSGROWFSLOG: {
...@@ -810,9 +806,7 @@ xfs_ioctl( ...@@ -810,9 +806,7 @@ xfs_ioctl(
return -XFS_ERROR(EFAULT); return -XFS_ERROR(EFAULT);
error = xfs_growfs_log(mp, &in); error = xfs_growfs_log(mp, &in);
if (error)
return -error; return -error;
return 0;
} }
case XFS_IOC_FSGROWFSRT: { case XFS_IOC_FSGROWFSRT: {
...@@ -825,9 +819,7 @@ xfs_ioctl( ...@@ -825,9 +819,7 @@ xfs_ioctl(
return -XFS_ERROR(EFAULT); return -XFS_ERROR(EFAULT);
error = xfs_growfs_rt(mp, &in); error = xfs_growfs_rt(mp, &in);
if (error)
return -error; return -error;
return 0;
} }
case XFS_IOC_FREEZE: case XFS_IOC_FREEZE:
...@@ -842,6 +834,19 @@ xfs_ioctl( ...@@ -842,6 +834,19 @@ xfs_ioctl(
xfs_fs_thaw(mp); xfs_fs_thaw(mp);
return 0; 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: { case XFS_IOC_ERROR_INJECTION: {
xfs_error_injection_t in; xfs_error_injection_t in;
...@@ -849,9 +854,7 @@ xfs_ioctl( ...@@ -849,9 +854,7 @@ xfs_ioctl(
return -XFS_ERROR(EFAULT); return -XFS_ERROR(EFAULT);
error = xfs_errortag_add(in.errtag, mp); error = xfs_errortag_add(in.errtag, mp);
if (error)
return -error; return -error;
return 0;
} }
case XFS_IOC_ERROR_CLEARALL: case XFS_IOC_ERROR_CLEARALL:
......
...@@ -541,7 +541,6 @@ linvfs_setattr( ...@@ -541,7 +541,6 @@ linvfs_setattr(
if (error) if (error)
return(-error); /* Positive error up from XFS */ return(-error); /* Positive error up from XFS */
if (ia_valid & ATTR_SIZE) { if (ia_valid & ATTR_SIZE) {
i_size_write(inode, vattr.va_size);
error = vmtruncate(inode, attr->ia_size); error = vmtruncate(inode, attr->ia_size);
} }
...@@ -631,8 +630,7 @@ linvfs_listxattr( ...@@ -631,8 +630,7 @@ linvfs_listxattr(
if (!size) if (!size)
xflags |= ATTR_KERNOVAL; xflags |= ATTR_KERNOVAL;
if (capable(CAP_SYS_ADMIN)) xflags |= capable(CAP_SYS_ADMIN) ? ATTR_KERNFULLS : ATTR_KERNORMALS;
xflags |= ATTR_KERNFULLS;
error = attr_generic_list(vp, data, size, xflags, &result); error = attr_generic_list(vp, data, size, xflags, &result);
if (error < 0) if (error < 0)
......
...@@ -138,6 +138,8 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh) ...@@ -138,6 +138,8 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
#define xfs_inherit_sync xfs_params.inherit_sync.val #define xfs_inherit_sync xfs_params.inherit_sync.val
#define xfs_inherit_nodump xfs_params.inherit_nodump.val #define xfs_inherit_nodump xfs_params.inherit_nodump.val
#define xfs_inherit_noatime xfs_params.inherit_noatim.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_cpu() smp_processor_id()
#define current_pid() (current->pid) #define current_pid() (current->pid)
......
...@@ -283,7 +283,6 @@ xfs_read( ...@@ -283,7 +283,6 @@ xfs_read(
ip = XFS_BHVTOI(bdp); ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp); vp = BHV_TO_VNODE(bdp);
mp = ip->i_mount; mp = ip->i_mount;
vn_trace_entry(vp, "xfs_read", (inst_t *)__return_address);
XFS_STATS_INC(xs_read_calls); XFS_STATS_INC(xs_read_calls);
...@@ -345,6 +344,8 @@ xfs_read( ...@@ -345,6 +344,8 @@ xfs_read(
} }
} }
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
iovp, segs, *offset, ioflags);
ret = __generic_file_aio_read(iocb, iovp, segs, offset); ret = __generic_file_aio_read(iocb, iovp, segs, offset);
xfs_iunlock(ip, XFS_IOLOCK_SHARED); xfs_iunlock(ip, XFS_IOLOCK_SHARED);
...@@ -377,7 +378,6 @@ xfs_sendfile( ...@@ -377,7 +378,6 @@ xfs_sendfile(
ip = XFS_BHVTOI(bdp); ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp); vp = BHV_TO_VNODE(bdp);
mp = ip->i_mount; mp = ip->i_mount;
vn_trace_entry(vp, "xfs_sendfile", (inst_t *)__return_address);
XFS_STATS_INC(xs_read_calls); XFS_STATS_INC(xs_read_calls);
...@@ -405,6 +405,8 @@ xfs_sendfile( ...@@ -405,6 +405,8 @@ xfs_sendfile(
return -error; 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); ret = generic_file_sendfile(filp, offset, count, actor, target);
xfs_iunlock(ip, XFS_IOLOCK_SHARED); xfs_iunlock(ip, XFS_IOLOCK_SHARED);
...@@ -658,7 +660,6 @@ xfs_write( ...@@ -658,7 +660,6 @@ xfs_write(
XFS_STATS_INC(xs_write_calls); XFS_STATS_INC(xs_write_calls);
vp = BHV_TO_VNODE(bdp); vp = BHV_TO_VNODE(bdp);
vn_trace_entry(vp, "xfs_write", (inst_t *)__return_address);
xip = XFS_BHVTOI(bdp); xip = XFS_BHVTOI(bdp);
/* START copy & waste from filemap.c */ /* START copy & waste from filemap.c */
...@@ -678,7 +679,7 @@ xfs_write( ...@@ -678,7 +679,7 @@ xfs_write(
if (size == 0) if (size == 0)
return 0; return 0;
io = &(xip->i_iocore); io = &xip->i_iocore;
mp = io->io_mount; mp = io->io_mount;
xfs_check_frozen(mp, bdp, XFS_FREEZE_WRITE); xfs_check_frozen(mp, bdp, XFS_FREEZE_WRITE);
...@@ -729,11 +730,12 @@ xfs_write( ...@@ -729,11 +730,12 @@ xfs_write(
if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) && if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
!(ioflags & IO_INVIS) && !eventsent)) { !(ioflags & IO_INVIS) && !eventsent)) {
loff_t savedsize = *offset; loff_t savedsize = *offset;
int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
xfs_iunlock(xip, XFS_ILOCK_EXCL); xfs_iunlock(xip, XFS_ILOCK_EXCL);
error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, vp, error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, vp,
*offset, size, *offset, size,
FILP_DELAY_FLAG(file), &locktype); dmflags, &locktype);
if (error) { if (error) {
xfs_iunlock(xip, iolock); xfs_iunlock(xip, iolock);
return -error; return -error;
......
...@@ -45,9 +45,7 @@ struct xfs_iomap; ...@@ -45,9 +45,7 @@ struct xfs_iomap;
/* /*
* Defines for the trace mechanisms in xfs_lrw.c. * Defines for the trace mechanisms in xfs_lrw.c.
*/ */
#define XFS_RW_KTRACE_SIZE 64 #define XFS_RW_KTRACE_SIZE 128
#define XFS_STRAT_KTRACE_SIZE 64
#define XFS_STRAT_GTRACE_SIZE 512
#define XFS_READ_ENTER 1 #define XFS_READ_ENTER 1
#define XFS_WRITE_ENTER 2 #define XFS_WRITE_ENTER 2
...@@ -69,6 +67,12 @@ struct xfs_iomap; ...@@ -69,6 +67,12 @@ struct xfs_iomap;
#define XFS_INVAL_CACHED 18 #define XFS_INVAL_CACHED 18
#define XFS_DIORD_ENTER 19 #define XFS_DIORD_ENTER 19
#define XFS_DIOWR_ENTER 20 #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 *, extern void xfs_rw_enter_trace(int, struct xfs_iocore *,
const struct iovec *, size_t, loff_t, int); const struct iovec *, size_t, loff_t, int);
extern void xfs_inval_cached_trace(struct xfs_iocore *, extern void xfs_inval_cached_trace(struct xfs_iocore *,
......
...@@ -67,6 +67,7 @@ xfs_read_xfsstats( ...@@ -67,6 +67,7 @@ xfs_read_xfsstats(
{ "attr", XFSSTAT_END_ATTRIBUTE_OPS }, { "attr", XFSSTAT_END_ATTRIBUTE_OPS },
{ "icluster", XFSSTAT_END_INODE_CLUSTER }, { "icluster", XFSSTAT_END_INODE_CLUSTER },
{ "vnodes", XFSSTAT_END_VNODE_OPS }, { "vnodes", XFSSTAT_END_VNODE_OPS },
{ "buf", XFSSTAT_END_BUF },
}; };
/* Loop over all stats groups */ /* Loop over all stats groups */
......
...@@ -122,6 +122,16 @@ struct xfsstats { ...@@ -122,6 +122,16 @@ struct xfsstats {
__uint32_t vn_reclaim; /* # times vn_reclaim called */ __uint32_t vn_reclaim; /* # times vn_reclaim called */
__uint32_t vn_remove; /* # times vn_remove called */ __uint32_t vn_remove; /* # times vn_remove called */
__uint32_t vn_free; /* # times vn_free 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 */ /* Extra precision counters */
__uint64_t xs_xstrat_bytes; __uint64_t xs_xstrat_bytes;
__uint64_t xs_write_bytes; __uint64_t xs_write_bytes;
......
...@@ -453,7 +453,7 @@ syncd(void *arg) ...@@ -453,7 +453,7 @@ syncd(void *arg)
vfs_t *vfsp = (vfs_t *) arg; vfs_t *vfsp = (vfs_t *) arg;
int error; int error;
daemonize("xfs_syncd"); daemonize("xfssyncd");
vfsp->vfs_sync_task = current; vfsp->vfs_sync_task = current;
wmb(); wmb();
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
#endif #endif
#ifdef CONFIG_XFS_SECURITY #ifdef CONFIG_XFS_SECURITY
# define XFS_SECURITY_STRING "security attrs, " # define XFS_SECURITY_STRING "security attributes, "
# define ENOSECURITY 0 # define ENOSECURITY 0
#else #else
# define XFS_SECURITY_STRING # define XFS_SECURITY_STRING
......
...@@ -118,6 +118,16 @@ STATIC ctl_table xfs_table[] = { ...@@ -118,6 +118,16 @@ STATIC ctl_table xfs_table[] = {
&sysctl_intvec, NULL, &sysctl_intvec, NULL,
&xfs_params.inherit_noatim.min, &xfs_params.inherit_noatim.max}, &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 */ /* please keep this the last entry */
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
{XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val, {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
......
...@@ -58,6 +58,10 @@ typedef struct xfs_param { ...@@ -58,6 +58,10 @@ typedef struct xfs_param {
xfs_sysctl_val_t inherit_sync; /* Inherit the "sync" inode flag. */ 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_nodump;/* Inherit the "nodump" inode flag. */
xfs_sysctl_val_t inherit_noatim;/* Inherit the "noatime" 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; } xfs_param_t;
/* /*
...@@ -86,6 +90,8 @@ enum { ...@@ -86,6 +90,8 @@ enum {
XFS_INHERIT_SYNC = 13, XFS_INHERIT_SYNC = 13,
XFS_INHERIT_NODUMP = 14, XFS_INHERIT_NODUMP = 14,
XFS_INHERIT_NOATIME = 15, XFS_INHERIT_NOATIME = 15,
XFS_FLUSH_INTERVAL = 16,
XFS_AGE_BUFFER = 17,
}; };
extern xfs_param_t xfs_params; extern xfs_param_t xfs_params;
......
...@@ -780,14 +780,8 @@ xfs_alloc_ag_vextent_near( ...@@ -780,14 +780,8 @@ xfs_alloc_ag_vextent_near(
/* /*
* Randomly don't execute the first algorithm. * Randomly don't execute the first algorithm.
*/ */
static int seed; /* randomizing seed value */
int dofirst; /* set to do first algorithm */ 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; dofirst = random() & 1;
#endif #endif
/* /*
......
...@@ -91,10 +91,14 @@ extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); ...@@ -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_CREATE 0x0010 /* pure create: fail if attr already exists */
#define ATTR_REPLACE 0x0020 /* pure set: fail if attr does not exist */ #define ATTR_REPLACE 0x0020 /* pure set: fail if attr does not exist */
#define ATTR_SYSTEM 0x0100 /* use attrs in system (pseudo) namespace */ #define ATTR_SYSTEM 0x0100 /* use attrs in system (pseudo) namespace */
#define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */ #define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */
#define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */ #define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */
#define ATTR_KERNAMELS 0x4000 /* [kernel] list attr names (simple list) */ #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 * The maximum size (into the kernel or returned from the kernel) of an
......
...@@ -460,9 +460,15 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -460,9 +460,15 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) { i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) {
attrnames_t *namesp; 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) != if (((context->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0) && ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
!(context->flags & ATTR_KERNFULLS)) { !(context->flags & ATTR_KERNROOTLS)) {
sfe = XFS_ATTR_SF_NEXTENTRY(sfe); sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
continue; continue;
} }
...@@ -511,9 +517,15 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -511,9 +517,15 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
kmem_free(sbuf, sbsize); kmem_free(sbuf, sbsize);
return XFS_ERROR(EFSCORRUPTED); 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) != if (((context->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0) && ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
!(context->flags & ATTR_KERNFULLS)) { !(context->flags & ATTR_KERNROOTLS)) {
sfe = XFS_ATTR_SF_NEXTENTRY(sfe); sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
continue; continue;
} }
...@@ -2309,9 +2321,13 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) ...@@ -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) if (entry->flags & XFS_ATTR_INCOMPLETE)
continue; /* skip incomplete entries */ 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) != if (((context->flags & ATTR_ROOT) != 0) !=
((entry->flags & XFS_ATTR_ROOT) != 0) && ((entry->flags & XFS_ATTR_ROOT) != 0) &&
!(context->flags & ATTR_KERNFULLS)) !(context->flags & ATTR_KERNROOTLS))
continue; /* skip non-matching entries */ continue; /* skip non-matching entries */
namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure : namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure :
......
/* /*
* 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 * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -57,10 +57,10 @@ struct xfs_mount_args { ...@@ -57,10 +57,10 @@ struct xfs_mount_args {
int flags; /* flags -> see XFSMNT_... macros below */ int flags; /* flags -> see XFSMNT_... macros below */
int logbufs; /* Number of log buffers, -1 to default */ int logbufs; /* Number of log buffers, -1 to default */
int logbufsize; /* Size of log buffers, -1 to default */ int logbufsize; /* Size of log buffers, -1 to default */
char fsname[MAXNAMELEN]; /* data device name */ char fsname[MAXNAMELEN+1]; /* data device name */
char rtname[MAXNAMELEN]; /* realtime device filename */ char rtname[MAXNAMELEN+1]; /* realtime device filename */
char logname[MAXNAMELEN]; /* journal device filename */ char logname[MAXNAMELEN+1]; /* journal device filename */
char mtpt[MAXNAMELEN]; /* filesystem mount point */ char mtpt[MAXNAMELEN+1]; /* filesystem mount point */
int sunit; /* stripe unit (BBs) */ int sunit; /* stripe unit (BBs) */
int swidth; /* stripe width (BBs), multiple of sunit */ int swidth; /* stripe width (BBs), multiple of sunit */
uchar_t iosizelog; /* log2 of the preferred I/O size */ uchar_t iosizelog; /* log2 of the preferred I/O size */
......
...@@ -165,6 +165,27 @@ typedef enum { ...@@ -165,6 +165,27 @@ typedef enum {
#define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */ #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_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 * Macros to turn caller specified delay/block flags into
......
...@@ -437,6 +437,12 @@ typedef struct xfs_handle { ...@@ -437,6 +437,12 @@ typedef struct xfs_handle {
#define FSHSIZE sizeof(fsid_t) #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 * ioctl commands that replace IRIX fcntl()'s
...@@ -490,6 +496,7 @@ typedef struct xfs_handle { ...@@ -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_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_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_FSGEOMETRY _IOR ('X', 124, struct xfs_fsop_geom)
#define XFS_IOC_GOINGDOWN _IOR ('X', 125, __uint32_t)
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */ /* XFS_IOC_GETFSUUID ---------- deprecated 140 */
......
...@@ -626,3 +626,28 @@ xfs_fs_thaw( ...@@ -626,3 +626,28 @@ xfs_fs_thaw(
xfs_finish_freeze(mp); xfs_finish_freeze(mp);
return 0; 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;
}
...@@ -67,4 +67,9 @@ int ...@@ -67,4 +67,9 @@ int
xfs_fs_thaw( xfs_fs_thaw(
xfs_mount_t *mp); xfs_mount_t *mp);
int
xfs_fs_goingdown(
xfs_mount_t *mp,
__uint32_t inflags);
#endif /* __XFS_FSOPS_H__ */ #endif /* __XFS_FSOPS_H__ */
/* /*
* 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 * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -69,6 +69,76 @@ ...@@ -69,6 +69,76 @@
#include "xfs_utils.h" #include "xfs_utils.h"
#include "xfs_iomap.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) \ #define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
<< mp->m_writeio_log) << mp->m_writeio_log)
#define XFS_STRAT_WRITE_IMAPS 2 #define XFS_STRAT_WRITE_IMAPS 2
...@@ -149,17 +219,20 @@ xfs_iomap( ...@@ -149,17 +219,20 @@ xfs_iomap(
(BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE | (BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE |
BMAPI_UNWRITTEN | BMAPI_DEVICE)) { BMAPI_UNWRITTEN | BMAPI_DEVICE)) {
case BMAPI_READ: case BMAPI_READ:
xfs_iomap_enter_trace(XFS_IOMAP_READ_ENTER, io, offset, count);
lockmode = XFS_LCK_MAP_SHARED(mp, io); lockmode = XFS_LCK_MAP_SHARED(mp, io);
bmapi_flags = XFS_BMAPI_ENTIRE; bmapi_flags = XFS_BMAPI_ENTIRE;
if (flags & BMAPI_IGNSTATE) if (flags & BMAPI_IGNSTATE)
bmapi_flags |= XFS_BMAPI_IGSTATE; bmapi_flags |= XFS_BMAPI_IGSTATE;
break; break;
case BMAPI_WRITE: case BMAPI_WRITE:
xfs_iomap_enter_trace(XFS_IOMAP_WRITE_ENTER, io, offset, count);
lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR; lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR;
bmapi_flags = 0; bmapi_flags = 0;
XFS_ILOCK(mp, io, lockmode); XFS_ILOCK(mp, io, lockmode);
break; break;
case BMAPI_ALLOCATE: case BMAPI_ALLOCATE:
xfs_iomap_enter_trace(XFS_IOMAP_ALLOC_ENTER, io, offset, count);
lockmode = XFS_ILOCK_SHARED|XFS_EXTSIZE_RD; lockmode = XFS_ILOCK_SHARED|XFS_EXTSIZE_RD;
bmapi_flags = XFS_BMAPI_ENTIRE; bmapi_flags = XFS_BMAPI_ENTIRE;
/* Attempt non-blocking lock */ /* Attempt non-blocking lock */
...@@ -201,8 +274,11 @@ xfs_iomap( ...@@ -201,8 +274,11 @@ xfs_iomap(
switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) { switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) {
case BMAPI_WRITE: case BMAPI_WRITE:
/* If we found an extent, return it */ /* 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; break;
}
if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) { if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) {
error = XFS_IOMAP_WRITE_DIRECT(mp, io, offset, error = XFS_IOMAP_WRITE_DIRECT(mp, io, offset,
...@@ -211,6 +287,10 @@ xfs_iomap( ...@@ -211,6 +287,10 @@ xfs_iomap(
error = XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, error = XFS_IOMAP_WRITE_DELAY(mp, io, offset, count,
flags, &imap, &nimaps); flags, &imap, &nimaps);
} }
if (!error) {
xfs_iomap_map_trace(XFS_IOMAP_ALLOC_MAP, io,
offset, count, iomapp, &imap, flags);
}
iomap_flags = IOMAP_NEW; iomap_flags = IOMAP_NEW;
break; break;
case BMAPI_ALLOCATE: case BMAPI_ALLOCATE:
...@@ -218,8 +298,11 @@ xfs_iomap( ...@@ -218,8 +298,11 @@ xfs_iomap(
XFS_IUNLOCK(mp, io, lockmode); XFS_IUNLOCK(mp, io, lockmode);
lockmode = 0; 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; break;
}
error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps); error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps);
break; break;
...@@ -309,7 +392,6 @@ xfs_iomap_write_direct( ...@@ -309,7 +392,6 @@ xfs_iomap_write_direct(
* Make sure that the dquots are there. This doesn't hold * Make sure that the dquots are there. This doesn't hold
* the ilock across a disk read. * the ilock across a disk read.
*/ */
error = XFS_QM_DQATTACH(ip->i_mount, ip, XFS_QMOPT_ILOCKED); error = XFS_QM_DQATTACH(ip->i_mount, ip, XFS_QMOPT_ILOCKED);
if (error) if (error)
return XFS_ERROR(error); return XFS_ERROR(error);
...@@ -540,8 +622,9 @@ xfs_iomap_write_delay( ...@@ -540,8 +622,9 @@ xfs_iomap_write_delay(
* If bmapi returned us nothing, and if we didn't get back EDQUOT, * If bmapi returned us nothing, and if we didn't get back EDQUOT,
* then we must have run out of space. * then we must have run out of space.
*/ */
if (nimaps == 0) { if (nimaps == 0) {
xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE,
io, offset, count);
if (xfs_flush_space(ip, &fsynced, &ioflag)) if (xfs_flush_space(ip, &fsynced, &ioflag))
return XFS_ERROR(ENOSPC); return XFS_ERROR(ENOSPC);
...@@ -584,7 +667,6 @@ xfs_iomap_write_allocate( ...@@ -584,7 +667,6 @@ xfs_iomap_write_allocate(
/* /*
* Make sure that the dquots are there. * Make sure that the dquots are there.
*/ */
if ((error = XFS_QM_DQATTACH(mp, ip, 0))) if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
return XFS_ERROR(error); return XFS_ERROR(error);
...@@ -612,7 +694,6 @@ xfs_iomap_write_allocate( ...@@ -612,7 +694,6 @@ xfs_iomap_write_allocate(
XFS_WRITE_LOG_RES(mp), XFS_WRITE_LOG_RES(mp),
0, XFS_TRANS_PERM_LOG_RES, 0, XFS_TRANS_PERM_LOG_RES,
XFS_WRITE_LOG_COUNT); XFS_WRITE_LOG_COUNT);
if (error == ENOSPC) { if (error == ENOSPC) {
error = xfs_trans_reserve(tp, 0, error = xfs_trans_reserve(tp, 0,
XFS_WRITE_LOG_RES(mp), XFS_WRITE_LOG_RES(mp),
...@@ -653,19 +734,16 @@ xfs_iomap_write_allocate( ...@@ -653,19 +734,16 @@ xfs_iomap_write_allocate(
error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb,
XFS_BMAPI_WRITE, &first_block, 1, XFS_BMAPI_WRITE, &first_block, 1,
imap, &nimaps, &free_list); imap, &nimaps, &free_list);
if (error) if (error)
goto trans_cancel; goto trans_cancel;
error = xfs_bmap_finish(&tp, &free_list, error = xfs_bmap_finish(&tp, &free_list,
first_block, &committed); first_block, &committed);
if (error) if (error)
goto trans_cancel; goto trans_cancel;
error = xfs_trans_commit(tp, error = xfs_trans_commit(tp,
XFS_TRANS_RELEASE_LOG_RES, NULL); XFS_TRANS_RELEASE_LOG_RES, NULL);
if (error) if (error)
goto error0; goto error0;
...@@ -725,6 +803,9 @@ xfs_iomap_write_unwritten( ...@@ -725,6 +803,9 @@ xfs_iomap_write_unwritten(
xfs_fsblock_t firstfsb; xfs_fsblock_t firstfsb;
xfs_bmap_free_t free_list; 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); offset_fsb = XFS_B_TO_FSBT(mp, offset);
count_fsb = XFS_B_TO_FSB(mp, count); count_fsb = XFS_B_TO_FSB(mp, count);
......
...@@ -759,8 +759,9 @@ xfs_log_move_tail(xfs_mount_t *mp, ...@@ -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 /* Also an invalid lsn. 1 implies that we aren't passing in a valid
* tail_lsn. * tail_lsn.
*/ */
if (tail_lsn != 1) if (tail_lsn != 1) {
log->l_tail_lsn = tail_lsn; log->l_tail_lsn = tail_lsn;
}
if ((tic = log->l_write_headq)) { if ((tic = log->l_write_headq)) {
#ifdef DEBUG #ifdef DEBUG
...@@ -866,10 +867,11 @@ xlog_assign_tail_lsn(xfs_mount_t *mp) ...@@ -866,10 +867,11 @@ xlog_assign_tail_lsn(xfs_mount_t *mp)
tail_lsn = xfs_trans_tail_ail(mp); tail_lsn = xfs_trans_tail_ail(mp);
s = GRANT_LOCK(log); s = GRANT_LOCK(log);
if (tail_lsn != 0) if (tail_lsn != 0) {
log->l_tail_lsn = tail_lsn; log->l_tail_lsn = tail_lsn;
else } else {
tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn; tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn;
}
GRANT_UNLOCK(log, s); GRANT_UNLOCK(log, s);
return tail_lsn; return tail_lsn;
...@@ -921,10 +923,8 @@ xlog_space_left(xlog_t *log, int cycle, int bytes) ...@@ -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 * In this case we just want to return the size of the
* log as the amount of space left. * log as the amount of space left.
*/ */
/* This assert does not take into account padding from striped log writes *
ASSERT((tail_cycle == (cycle + 1)) || ASSERT((tail_cycle == (cycle + 1)) ||
((bytes + log->l_roundoff) >= tail_bytes)); ((bytes + log->l_roundoff) >= tail_bytes));
*/
free_bytes = log->l_logsize; free_bytes = log->l_logsize;
} }
return free_bytes; return free_bytes;
...@@ -1183,14 +1183,6 @@ xlog_alloc_log(xfs_mount_t *mp, ...@@ -1183,14 +1183,6 @@ xlog_alloc_log(xfs_mount_t *mp,
log->l_grant_reserve_cycle = 1; log->l_grant_reserve_cycle = 1;
log->l_grant_write_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)) { if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) {
log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
ASSERT(log->l_sectbb_log <= mp->m_sectbb_log); ASSERT(log->l_sectbb_log <= mp->m_sectbb_log);
...@@ -1401,45 +1393,35 @@ xlog_sync(xlog_t *log, ...@@ -1401,45 +1393,35 @@ xlog_sync(xlog_t *log,
xfs_caddr_t dptr; /* pointer to byte sized element */ xfs_caddr_t dptr; /* pointer to byte sized element */
xfs_buf_t *bp; xfs_buf_t *bp;
int i, ops; int i, ops;
uint roundup;
uint count; /* byte count of bwrite */ uint count; /* byte count of bwrite */
uint count_init; /* initial count before roundup */
int split = 0; /* split write into two regions */ int split = 0; /* split write into two regions */
int error; int error;
XFS_STATS_INC(xs_log_writes); XFS_STATS_INC(xs_log_writes);
ASSERT(iclog->ic_refcnt == 0); ASSERT(iclog->ic_refcnt == 0);
/* Round out the log write size */ /* Add for LR header */
if (iclog->ic_offset & BBMASK) { count_init = log->l_iclog_hsize + iclog->ic_offset;
/* 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;
count = BTOBB(log->l_iclog_hsize + iclog->ic_offset); /* Round out the log write size */
if (count & (sunit - 1)) { if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
roundup = sunit - (count & (sunit - 1)); 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 { } else {
roundup = 0; count = BBTOB(BTOBB(count_init));
} }
iclog->ic_offset += BBTOB(roundup); iclog->ic_roundoff = count - count_init;
}
log->l_roundoff += iclog->ic_roundoff; log->l_roundoff += iclog->ic_roundoff;
xlog_pack_data(log, iclog); /* put cycle number in every block */ xlog_pack_data(log, iclog); /* put cycle number in every block */
/* real byte length */ /* 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 */ /* put ops count in correct order */
ops = iclog->ic_header.h_num_logops; ops = iclog->ic_header.h_num_logops;
INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops); INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops);
...@@ -1449,12 +1431,6 @@ xlog_sync(xlog_t *log, ...@@ -1449,12 +1431,6 @@ xlog_sync(xlog_t *log,
XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2); XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
XFS_BUF_SET_ADDR(bp, BLOCK_LSN(iclog->ic_header.h_lsn, ARCH_CONVERT)); 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)); XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
/* Do we need to split this write into 2 parts? */ /* Do we need to split this write into 2 parts? */
...@@ -2783,8 +2759,6 @@ xlog_state_switch_iclogs(xlog_t *log, ...@@ -2783,8 +2759,6 @@ xlog_state_switch_iclogs(xlog_t *log,
xlog_in_core_t *iclog, xlog_in_core_t *iclog,
int eventual_size) int eventual_size)
{ {
uint roundup;
ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE); ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE);
if (!eventual_size) if (!eventual_size)
eventual_size = iclog->ic_offset; eventual_size = iclog->ic_offset;
...@@ -2797,14 +2771,10 @@ xlog_state_switch_iclogs(xlog_t *log, ...@@ -2797,14 +2771,10 @@ xlog_state_switch_iclogs(xlog_t *log,
log->l_curr_block += BTOBB(eventual_size)+BTOBB(log->l_iclog_hsize); log->l_curr_block += BTOBB(eventual_size)+BTOBB(log->l_iclog_hsize);
/* Round up to next log-sunit */ /* Round up to next log-sunit */
if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
if (log->l_curr_block & (log->l_stripemask - 1)) { log->l_mp->m_sb.sb_logsunit > 1) {
roundup = log->l_stripemask - __uint32_t sunit_bb = BTOBB(log->l_mp->m_sb.sb_logsunit);
(log->l_curr_block & (log->l_stripemask - 1)); log->l_curr_block = roundup(log->l_curr_block, sunit_bb);
} else {
roundup = 0;
}
log->l_curr_block += roundup;
} }
if (log->l_curr_block >= log->l_logBBsize) { if (log->l_curr_block >= log->l_logBBsize) {
......
...@@ -63,6 +63,9 @@ int xlog_btolrbb(int b); ...@@ -63,6 +63,9 @@ int xlog_btolrbb(int b);
#else #else
#define XLOG_BTOLRBB(b) (((b)+XLOG_RECORD_BSIZE-1) >> XLOG_RECORD_BSHIFT) #define XLOG_BTOLRBB(b) (((b)+XLOG_RECORD_BSIZE-1) >> XLOG_RECORD_BSHIFT)
#endif #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 #define XLOG_HEADER_SIZE 512
...@@ -531,7 +534,6 @@ typedef struct log { ...@@ -531,7 +534,6 @@ typedef struct log {
uint l_flags; uint l_flags;
uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */
struct xfs_buf_cancel **l_buf_cancel_table; 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_hsize; /* size of iclog header */
int l_iclog_heads; /* # of iclog header sectors */ int l_iclog_heads; /* # of iclog header sectors */
uint l_sectbb_log; /* log2 of sector size in BBs */ uint l_sectbb_log; /* log2 of sector size in BBs */
......
...@@ -3416,6 +3416,7 @@ xlog_unpack_data_checksum( ...@@ -3416,6 +3416,7 @@ xlog_unpack_data_checksum(
{ {
uint *up = (uint *)dp; uint *up = (uint *)dp;
uint chksum = 0; uint chksum = 0;
int i;
/* divide length by 4 to get # words */ /* divide length by 4 to get # words */
for (i=0; i < INT_GET(rhead->h_len, ARCH_CONVERT) >> 2; i++) { for (i=0; i < INT_GET(rhead->h_len, ARCH_CONVERT) >> 2; i++) {
...@@ -3476,7 +3477,7 @@ xlog_valid_rec_header( ...@@ -3476,7 +3477,7 @@ xlog_valid_rec_header(
xlog_rec_header_t *rhead, xlog_rec_header_t *rhead,
xfs_daddr_t blkno) xfs_daddr_t blkno)
{ {
int bblks; int hlen;
if (unlikely( if (unlikely(
(INT_GET(rhead->h_magicno, ARCH_CONVERT) != (INT_GET(rhead->h_magicno, ARCH_CONVERT) !=
...@@ -3495,8 +3496,8 @@ xlog_valid_rec_header( ...@@ -3495,8 +3496,8 @@ xlog_valid_rec_header(
} }
/* LR body must have data or it wouldn't have been written */ /* LR body must have data or it wouldn't have been written */
bblks = INT_GET(rhead->h_len, ARCH_CONVERT); hlen = INT_GET(rhead->h_len, ARCH_CONVERT);
if (unlikely( bblks <= 0 || bblks > INT_MAX )) { if (unlikely( hlen <= 0 || hlen > INT_MAX )) {
XFS_ERROR_REPORT("xlog_valid_rec_header(2)", XFS_ERROR_REPORT("xlog_valid_rec_header(2)",
XFS_ERRLEVEL_LOW, log->l_mp); XFS_ERRLEVEL_LOW, log->l_mp);
return XFS_ERROR(EFSCORRUPTED); return XFS_ERROR(EFSCORRUPTED);
...@@ -3658,7 +3659,7 @@ xlog_do_recovery_pass( ...@@ -3658,7 +3659,7 @@ xlog_do_recovery_pass(
error = xlog_bread(log, 0, wrapped_hblks, hbp); error = xlog_bread(log, 0, wrapped_hblks, hbp);
if (error) if (error)
goto bread_err2; goto bread_err2;
XFS_BUF_SET_PTR(hbp, bufaddr, hblks); XFS_BUF_SET_PTR(hbp, bufaddr, BBTOB(hblks));
if (!offset) if (!offset)
offset = xlog_align(log, 0, offset = xlog_align(log, 0,
wrapped_hblks, hbp); wrapped_hblks, hbp);
...@@ -3716,8 +3717,7 @@ xlog_do_recovery_pass( ...@@ -3716,8 +3717,7 @@ xlog_do_recovery_pass(
if ((error = xlog_bread(log, wrapped_hblks, if ((error = xlog_bread(log, wrapped_hblks,
bblks - split_bblks, dbp))) bblks - split_bblks, dbp)))
goto bread_err2; goto bread_err2;
XFS_BUF_SET_PTR(dbp, bufaddr, XFS_BUF_SET_PTR(dbp, bufaddr, h_size);
XLOG_BIG_RECORD_BSIZE);
if (!offset) if (!offset)
offset = xlog_align(log, wrapped_hblks, offset = xlog_align(log, wrapped_hblks,
bblks - split_bblks, dbp); bblks - split_bblks, dbp);
...@@ -4042,7 +4042,7 @@ xlog_recover_check_summary( ...@@ -4042,7 +4042,7 @@ xlog_recover_check_summary(
XFS_FSS_TO_BB(mp, 1), 0); XFS_FSS_TO_BB(mp, 1), 0);
if (XFS_BUF_ISERROR(agibp)) { if (XFS_BUF_ISERROR(agibp)) {
xfs_ioerror_alert("xlog_recover_check_summary(agi)", xfs_ioerror_alert("xlog_recover_check_summary(agi)",
log->l_mp, agibp, agidaddr); mp, agibp, agidaddr);
} }
agip = XFS_BUF_TO_AGI(agibp); agip = XFS_BUF_TO_AGI(agibp);
ASSERT(XFS_AGI_MAGIC == ASSERT(XFS_AGI_MAGIC ==
...@@ -4058,7 +4058,8 @@ xlog_recover_check_summary( ...@@ -4058,7 +4058,8 @@ xlog_recover_check_summary(
sbbp = xfs_getsb(mp, 0); sbbp = xfs_getsb(mp, 0);
#ifdef XFS_LOUD_RECOVERY #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, cmn_err(CE_NOTE,
"xlog_recover_check_summary: sb_icount %Lu itotal %Lu", "xlog_recover_check_summary: sb_icount %Lu itotal %Lu",
sbp->sb_icount, itotal); sbp->sb_icount, itotal);
......
...@@ -675,6 +675,7 @@ xfs_mountfs( ...@@ -675,6 +675,7 @@ xfs_mountfs(
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error1; goto error1;
} }
mp->m_dalign = mp->m_swidth = 0;
} else { } else {
/* /*
* Convert the stripe unit and width to FSBs. * Convert the stripe unit and width to FSBs.
......
...@@ -413,8 +413,9 @@ xfs_setattr( ...@@ -413,8 +413,9 @@ xfs_setattr(
} else { } else {
if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) && if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) &&
!(flags & ATTR_DMI)) { !(flags & ATTR_DMI)) {
int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR;
code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp, 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) { if (code) {
lock_flags = 0; lock_flags = 0;
goto error_return; goto error_return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment