Skip to content

Commit

Permalink
Merge git://oss.sgi.com:8090/xfs/xfs-2.6
Browse files Browse the repository at this point in the history
* git://oss.sgi.com:8090/xfs/xfs-2.6:
  [XFS] Remove KERNEL_VERSION macros from xfs_dmapi.h
  [XFS] Prevent a deadlock when xfslogd unpins inodes.
  [XFS] Clean up i_flags and i_flags_lock handling.
  [XFS] 956664: dm_read_invis() changes i_atime
  [XFS] rename uio_read() to xfs_uio_read()
  [XFS] Keep lockdep happy.
  [XFS] 956618: Linux crashes on boot with XFS-DMAPI filesystem when
  • Loading branch information
Linus Torvalds committed Nov 13, 2006
2 parents ea991f0 + 050e714 commit eea2078
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 113 deletions.
17 changes: 1 addition & 16 deletions fs/xfs/Makefile-linux-2.6
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,7 @@ EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char
XFS_LINUX := linux-2.6

ifeq ($(CONFIG_XFS_DEBUG),y)
EXTRA_CFLAGS += -g -DSTATIC="" -DDEBUG
EXTRA_CFLAGS += -DXFS_BUF_LOCK_TRACKING
endif
ifeq ($(CONFIG_XFS_TRACE),y)
EXTRA_CFLAGS += -DXFS_ALLOC_TRACE
EXTRA_CFLAGS += -DXFS_ATTR_TRACE
EXTRA_CFLAGS += -DXFS_BLI_TRACE
EXTRA_CFLAGS += -DXFS_BMAP_TRACE
EXTRA_CFLAGS += -DXFS_BMBT_TRACE
EXTRA_CFLAGS += -DXFS_DIR2_TRACE
EXTRA_CFLAGS += -DXFS_DQUOT_TRACE
EXTRA_CFLAGS += -DXFS_ILOCK_TRACE
EXTRA_CFLAGS += -DXFS_LOG_TRACE
EXTRA_CFLAGS += -DXFS_RW_TRACE
EXTRA_CFLAGS += -DXFS_BUF_TRACE
EXTRA_CFLAGS += -DXFS_VNODE_TRACE
EXTRA_CFLAGS += -g
endif

obj-$(CONFIG_XFS_FS) += xfs.o
Expand Down
4 changes: 2 additions & 2 deletions fs/xfs/linux-2.6/xfs_buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
#include <linux/stddef.h>
#include <linux/errno.h>
#include <linux/slab.h>
Expand All @@ -31,7 +32,6 @@
#include <linux/kthread.h>
#include <linux/migrate.h>
#include <linux/backing-dev.h>
#include "xfs_linux.h"

STATIC kmem_zone_t *xfs_buf_zone;
STATIC kmem_shaker_t xfs_buf_shake;
Expand Down Expand Up @@ -1406,7 +1406,7 @@ xfs_alloc_bufhash(
btp->bt_hashshift = external ? 3 : 8; /* 8 or 256 buckets */
btp->bt_hashmask = (1 << btp->bt_hashshift) - 1;
btp->bt_hash = kmem_zalloc((1 << btp->bt_hashshift) *
sizeof(xfs_bufhash_t), KM_SLEEP);
sizeof(xfs_bufhash_t), KM_SLEEP | KM_LARGE);
for (i = 0; i < (1 << btp->bt_hashshift); i++) {
spin_lock_init(&btp->bt_hash[i].bh_lock);
INIT_LIST_HEAD(&btp->bt_hash[i].bh_list);
Expand Down
28 changes: 28 additions & 0 deletions fs/xfs/linux-2.6/xfs_dmapi_priv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DMAPI_PRIV_H__
#define __XFS_DMAPI_PRIV_H__

/*
* Based on IO_ISDIRECT, decide which i_ flag is set.
*/
#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
DM_FLAGS_IMUX : 0)
#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)

#endif /*__XFS_DMAPI_PRIV_H__*/
5 changes: 4 additions & 1 deletion fs/xfs/linux-2.6/xfs_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,11 @@ xfs_open_by_handle(
put_unused_fd(new_fd);
return -XFS_ERROR(-PTR_ERR(filp));
}
if (inode->i_mode & S_IFREG)
if (inode->i_mode & S_IFREG) {
/* invisible operation should not change atime */
filp->f_flags |= O_NOATIME;
filp->f_op = &xfs_invis_file_operations;
}

fd_install(new_fd, filp);
return new_fd;
Expand Down
4 changes: 1 addition & 3 deletions fs/xfs/linux-2.6/xfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,7 @@ xfs_initialize_vnode(
xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
xfs_set_inodeops(inode);

spin_lock(&ip->i_flags_lock);
ip->i_flags &= ~XFS_INEW;
spin_unlock(&ip->i_flags_lock);
xfs_iflags_clear(ip, XFS_INEW);
barrier();

unlock_new_inode(inode);
Expand Down
4 changes: 1 addition & 3 deletions fs/xfs/support/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <xfs.h>
#include "debug.h"
#include "spin.h"
#include <asm/page.h>
#include <linux/sched.h>
#include <linux/kernel.h>

static char message[256]; /* keep it off the stack */
static DEFINE_SPINLOCK(xfs_err_lock);
Expand Down
2 changes: 1 addition & 1 deletion fs/xfs/support/move.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* as we go.
*/
int
uio_read(caddr_t src, size_t len, struct uio *uio)
xfs_uio_read(caddr_t src, size_t len, struct uio *uio)
{
size_t count;

Expand Down
2 changes: 1 addition & 1 deletion fs/xfs/support/move.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ struct uio {
typedef struct uio uio_t;
typedef struct iovec iovec_t;

extern int uio_read (caddr_t, size_t, uio_t *);
extern int xfs_uio_read (caddr_t, size_t, uio_t *);

#endif /* __XFS_SUPPORT_MOVE_H__ */
23 changes: 23 additions & 0 deletions fs/xfs/xfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,28 @@
*/
#ifndef __XFS_H__
#define __XFS_H__

#ifdef CONFIG_XFS_DEBUG
#define STATIC
#define DEBUG 1
#define XFS_BUF_LOCK_TRACKING 1
/* #define QUOTADEBUG 1 */
#endif

#ifdef CONFIG_XFS_TRACE
#define XFS_ALLOC_TRACE 1
#define XFS_ATTR_TRACE 1
#define XFS_BLI_TRACE 1
#define XFS_BMAP_TRACE 1
#define XFS_BMBT_TRACE 1
#define XFS_DIR2_TRACE 1
#define XFS_DQUOT_TRACE 1
#define XFS_ILOCK_TRACE 1
#define XFS_LOG_TRACE 1
#define XFS_RW_TRACE 1
#define XFS_BUF_TRACE 1
#define XFS_VNODE_TRACE 1
#endif

#include <linux-2.6/xfs_linux.h>
#endif /* __XFS_H__ */
2 changes: 1 addition & 1 deletion fs/xfs/xfs_dir2.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ xfs_dir2_put_dirent64_uio(
idbp->d_off = pa->cook;
idbp->d_name[namelen] = '\0';
memcpy(idbp->d_name, pa->name, namelen);
rval = uio_read((caddr_t)idbp, reclen, uio);
rval = xfs_uio_read((caddr_t)idbp, reclen, uio);
pa->done = (rval == 0);
return rval;
}
Expand Down
22 changes: 2 additions & 20 deletions fs/xfs/xfs_dmapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,27 +157,9 @@ typedef enum {
#define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */

/*
* Based on IO_ISDIRECT, decide which i_ flag is set.
* Pull in platform specific event flags defines
*/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
DM_FLAGS_IMUX : 0)
#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)
#endif

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \
(LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22))
#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_IMUX)
#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)
#endif

#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21)
#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
0 : DM_FLAGS_IMUX)
#define DM_SEM_FLAG_WR (DM_FLAGS_IMUX)
#endif

#include "xfs_dmapi_priv.h"

/*
* Macros to turn caller specified delay/block flags into
Expand Down
51 changes: 37 additions & 14 deletions fs/xfs/xfs_iget.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ xfs_iget_core(
* If INEW is set this inode is being set up
* we need to pause and try again.
*/
if (ip->i_flags & XFS_INEW) {
if (xfs_iflags_test(ip, XFS_INEW)) {
read_unlock(&ih->ih_lock);
delay(1);
XFS_STATS_INC(xs_ig_frecycle);
Expand All @@ -230,22 +230,50 @@ xfs_iget_core(
* on its way out of the system,
* we need to pause and try again.
*/
if (ip->i_flags & XFS_IRECLAIM) {
if (xfs_iflags_test(ip, XFS_IRECLAIM)) {
read_unlock(&ih->ih_lock);
delay(1);
XFS_STATS_INC(xs_ig_frecycle);

goto again;
}
ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE));

/*
* If lookup is racing with unlink, then we
* should return an error immediately so we
* don't remove it from the reclaim list and
* potentially leak the inode.
*/
if ((ip->i_d.di_mode == 0) &&
!(flags & XFS_IGET_CREATE)) {
read_unlock(&ih->ih_lock);
return ENOENT;
}

/*
* There may be transactions sitting in the
* incore log buffers or being flushed to disk
* at this time. We can't clear the
* XFS_IRECLAIMABLE flag until these
* transactions have hit the disk, otherwise we
* will void the guarantee the flag provides
* xfs_iunpin()
*/
if (xfs_ipincount(ip)) {
read_unlock(&ih->ih_lock);
xfs_log_force(mp, 0,
XFS_LOG_FORCE|XFS_LOG_SYNC);
XFS_STATS_INC(xs_ig_frecycle);
goto again;
}

vn_trace_exit(vp, "xfs_iget.alloc",
(inst_t *)__return_address);

XFS_STATS_INC(xs_ig_found);

spin_lock(&ip->i_flags_lock);
ip->i_flags &= ~XFS_IRECLAIMABLE;
spin_unlock(&ip->i_flags_lock);
xfs_iflags_clear(ip, XFS_IRECLAIMABLE);
version = ih->ih_version;
read_unlock(&ih->ih_lock);
xfs_ihash_promote(ih, ip, version);
Expand Down Expand Up @@ -299,10 +327,7 @@ xfs_iget_core(
if (lock_flags != 0)
xfs_ilock(ip, lock_flags);

spin_lock(&ip->i_flags_lock);
ip->i_flags &= ~XFS_ISTALE;
spin_unlock(&ip->i_flags_lock);

xfs_iflags_clear(ip, XFS_ISTALE);
vn_trace_exit(vp, "xfs_iget.found",
(inst_t *)__return_address);
goto return_ip;
Expand Down Expand Up @@ -371,10 +396,7 @@ xfs_iget_core(
ih->ih_next = ip;
ip->i_udquot = ip->i_gdquot = NULL;
ih->ih_version++;
spin_lock(&ip->i_flags_lock);
ip->i_flags |= XFS_INEW;
spin_unlock(&ip->i_flags_lock);

xfs_iflags_set(ip, XFS_INEW);
write_unlock(&ih->ih_lock);

/*
Expand Down Expand Up @@ -625,7 +647,7 @@ xfs_iput_new(xfs_inode_t *ip,
vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);

if ((ip->i_d.di_mode == 0)) {
ASSERT(!(ip->i_flags & XFS_IRECLAIMABLE));
ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
vn_mark_bad(vp);
}
if (inode->i_state & I_NEW)
Expand Down Expand Up @@ -683,6 +705,7 @@ xfs_ireclaim(xfs_inode_t *ip)
/*
* Free all memory associated with the inode.
*/
xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_idestroy(ip);
}

Expand Down
Loading

0 comments on commit eea2078

Please sign in to comment.