From 71bce256bf2e2aaddf54a2f4ac216329c74be3ad Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 5 May 2005 13:23:27 -0700 Subject: [XFS] Move the XFS inode to the front of its hash list on a cache hit SGI Modid: xfs-linux:xfs-kern:21915a Signed-off-by: Nathan Scott Signed-off-by: Christoph Hellwig --- fs/xfs/xfs_iget.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 3a0ba1dfd0e8..d3da00045f26 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -135,6 +135,40 @@ xfs_chash_free(xfs_mount_t *mp) mp->m_chash = NULL; } +/* + * Try to move an inode to the front of its hash list if possible + * (and if its not there already). Called right after obtaining + * the list version number and then dropping the read_lock on the + * hash list in question (which is done right after looking up the + * inode in question...). + */ +STATIC void +xfs_ihash_promote( + xfs_ihash_t *ih, + xfs_inode_t *ip, + ulong version) +{ + xfs_inode_t *iq; + + if ((ip->i_prevp != &ih->ih_next) && write_trylock(&ih->ih_lock)) { + if (likely(version == ih->ih_version)) { + /* remove from list */ + if ((iq = ip->i_next)) { + iq->i_prevp = ip->i_prevp; + } + *ip->i_prevp = iq; + + /* insert at list head */ + iq = ih->ih_next; + iq->i_prevp = &ip->i_next; + ip->i_next = iq; + ip->i_prevp = &ih->ih_next; + ih->ih_next = ip; + } + write_unlock(&ih->ih_lock); + } +} + /* * Look up an inode by number in the given file system. * The inode is looked up in the hash table for the file system @@ -229,7 +263,9 @@ again: XFS_STATS_INC(xs_ig_found); ip->i_flags &= ~XFS_IRECLAIMABLE; + version = ih->ih_version; read_unlock(&ih->ih_lock); + xfs_ihash_promote(ih, ip, version); XFS_MOUNT_ILOCK(mp); list_del_init(&ip->i_reclaim); @@ -259,8 +295,15 @@ again: inode_vp, vp); } + /* + * Inode cache hit: if ip is not at the front of + * its hash chain, move it there now. + * Do this with the lock held for update, but + * do statistics after releasing the lock. + */ + version = ih->ih_version; read_unlock(&ih->ih_lock); - + xfs_ihash_promote(ih, ip, version); XFS_STATS_INC(xs_ig_found); finish_inode: @@ -547,6 +590,7 @@ xfs_inode_incore(xfs_mount_t *mp, { xfs_ihash_t *ih; xfs_inode_t *ip; + ulong version; ih = XFS_IHASH(mp, ino); read_lock(&ih->ih_lock); @@ -554,11 +598,15 @@ xfs_inode_incore(xfs_mount_t *mp, if (ip->i_ino == ino) { /* * If we find it and tp matches, return it. + * Also move it to the front of the hash list + * if we find it and it is not already there. * Otherwise break from the loop and return * NULL. */ if (ip->i_transp == tp) { + version = ih->ih_version; read_unlock(&ih->ih_lock); + xfs_ihash_promote(ih, ip, version); return (ip); } break; @@ -685,6 +733,7 @@ xfs_iextract( iq->i_prevp = ip->i_prevp; } *ip->i_prevp = iq; + ih->ih_version++; write_unlock(&ih->ih_lock); /* -- cgit v1.2.3-59-g8ed1b From de20614b351e4d4d23af0a105baa8fd2d7cd4f26 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 5 May 2005 13:24:13 -0700 Subject: [XFS] Block mount attempts for filesystems with version 1 directories. SGI Modid: xfs-linux:xfs-kern:21937a Signed-off-by: Nathan Scott Signed-off-by: Christoph Hellwig --- fs/xfs/xfs_mount.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index b57423caef9b..2ec967d93e5a 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -300,6 +300,15 @@ xfs_mount_validate_sb( return XFS_ERROR(EFSCORRUPTED); } + /* + * Version 1 directory format has never worked on Linux. + */ + if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) { + cmn_err(CE_WARN, + "XFS: Attempted to mount file system using version 1 directory format"); + return XFS_ERROR(ENOSYS); + } + /* * Until this is fixed only page-sized or smaller data blocks work. */ -- cgit v1.2.3-59-g8ed1b From 31b084aef3f088962f56c100b31bb8479c5dd769 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 5 May 2005 13:25:00 -0700 Subject: [XFS] Fix up uses of nlink_t incorrectly restricting us to 2^16 links for some platforms SGI Modid: xfs-linux:xfs-kern:22032a Signed-off-by: Nathan Scott Signed-off-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_vnode.h | 2 +- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_inode.h | 6 +++--- fs/xfs/xfs_types.h | 1 + fs/xfs/xfs_utils.c | 2 +- fs/xfs/xfs_utils.h | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index da76c1f1e11c..7cff0f3e9bc3 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -409,7 +409,7 @@ typedef struct vattr { int va_mask; /* bit-mask of attributes present */ enum vtype va_type; /* vnode type (for create) */ mode_t va_mode; /* file access mode and type */ - nlink_t va_nlink; /* number of references to file */ + xfs_nlink_t va_nlink; /* number of references to file */ uid_t va_uid; /* owner user id */ gid_t va_gid; /* owner group id */ xfs_ino_t va_nodeid; /* file id */ diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 43c632ab86ad..bc8c8c7f9039 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1130,7 +1130,7 @@ xfs_ialloc( xfs_trans_t *tp, xfs_inode_t *pip, mode_t mode, - nlink_t nlink, + xfs_nlink_t nlink, xfs_dev_t rdev, cred_t *cr, xfs_prid_t prid, diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index a53b1ccf6070..37e1c316f3b6 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -495,9 +495,9 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *, int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, xfs_inode_t **, xfs_daddr_t); int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); -int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, nlink_t, - xfs_dev_t, struct cred *, xfs_prid_t, int, - struct xfs_buf **, boolean_t *, xfs_inode_t **); +int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, + xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, + int, struct xfs_buf **, boolean_t *, xfs_inode_t **); void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *, int); uint xfs_ip2xflags(struct xfs_inode *); diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index 04609d27ea51..e4bf711e48ff 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h @@ -63,6 +63,7 @@ typedef __u64 xfs_ino_t; /* type */ typedef __s64 xfs_daddr_t; /* type */ typedef char * xfs_caddr_t; /* type */ typedef __u32 xfs_dev_t; +typedef __u32 xfs_nlink_t; /* __psint_t is the same size as a pointer */ #if (BITS_PER_LONG == 32) diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 816b945fa0ea..d1f8146a06ea 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c @@ -147,7 +147,7 @@ xfs_dir_ialloc( xfs_inode_t *dp, /* directory within whose allocate the inode. */ mode_t mode, - nlink_t nlink, + xfs_nlink_t nlink, xfs_dev_t rdev, cred_t *credp, prid_t prid, /* project id */ diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h index e1ed6a588000..01d98b4b7af7 100644 --- a/fs/xfs/xfs_utils.h +++ b/fs/xfs/xfs_utils.h @@ -42,7 +42,7 @@ extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **); extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *, xfs_inode_t **); extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); -extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, nlink_t, +extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, xfs_dev_t, cred_t *, prid_t, int, xfs_inode_t **, int *); extern int xfs_droplink (xfs_trans_t *, xfs_inode_t *); -- cgit v1.2.3-59-g8ed1b From 9effd8e62570c6e47b91734770e6122002c33ed5 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 5 May 2005 13:26:18 -0700 Subject: [XFS] Enable XFS_VNODE_TRACE SGI Modid: xfs-linux:xfs-kern:190725a Signed-off-by: Eric Sandeen Signed-off-by: Christoph Hellwig . --- fs/xfs/Makefile | 2 +- fs/xfs/linux-2.6/xfs_vnode.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 554e4a18c152..d3ff78354638 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -49,7 +49,7 @@ ifeq ($(CONFIG_XFS_TRACE),y) EXTRA_CFLAGS += -DXFS_LOG_TRACE EXTRA_CFLAGS += -DXFS_RW_TRACE EXTRA_CFLAGS += -DPAGEBUF_TRACE - # EXTRA_CFLAGS += -DXFS_VNODE_TRACE + EXTRA_CFLAGS += -DXFS_VNODE_TRACE endif obj-$(CONFIG_XFS_FS) += xfs.o diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 7cff0f3e9bc3..3b40c929544e 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -86,10 +86,11 @@ typedef struct vnode { vnumber_t v_number; /* in-core vnode number */ vn_bhv_head_t v_bh; /* behavior head */ spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ - struct inode v_inode; /* Linux inode */ #ifdef XFS_VNODE_TRACE struct ktrace *v_trace; /* trace header structure */ #endif + struct inode v_inode; /* Linux inode */ + /* inode MUST be last */ } vnode_t; #define v_fbhv v_bh.bh_first /* first behavior */ -- cgit v1.2.3-59-g8ed1b From 5fcbab355e1528545671a5221666ef640b8250c8 Mon Sep 17 00:00:00 2001 From: Dean Roehrich Date: Thu, 5 May 2005 13:27:19 -0700 Subject: [XFS] Add ATTR_NOLOCK for xfs_setattr to indicate that XFS_IOLOCK is held SGI Modid: xfs-linux:xfs-kern:190711a Signed-off-by: Dean Roehrich Signed-off-by: Christoph Hellwig . --- fs/xfs/linux-2.6/xfs_vnode.h | 1 + fs/xfs/xfs_vnodeops.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 3b40c929544e..4ee229301241 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -626,6 +626,7 @@ static inline int VN_BAD(struct vnode *vp) #define ATTR_DMI 0x08 /* invocation from a DMI function */ #define ATTR_LAZY 0x80 /* set/get attributes lazily */ #define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */ +#define ATTR_NOLOCK 0x200 /* Don't grab any conflicting locks */ /* * Flags to VOP_FSYNC and VOP_RECLAIM. diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 70092963ca9e..25a526629b12 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -305,7 +305,7 @@ xfs_setattr( int mandlock_before, mandlock_after; struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; int file_owner; - int need_iolock = (flags & ATTR_DMI) == 0; + int need_iolock = 1; vp = BHV_TO_VNODE(bdp); vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); @@ -384,6 +384,9 @@ xfs_setattr( */ tp = NULL; lock_flags = XFS_ILOCK_EXCL; + ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1); + if (flags & ATTR_NOLOCK) + need_iolock = 0; if (!(mask & XFS_AT_SIZE)) { if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) || (mp->m_flags & XFS_MOUNT_WSYNC)) { @@ -4320,7 +4323,7 @@ xfs_free_file_space( int rt; xfs_fileoff_t startoffset_fsb; xfs_trans_t *tp; - int need_iolock = (attr_flags & ATTR_DMI) == 0; + int need_iolock = 1; vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); mp = ip->i_mount; @@ -4348,8 +4351,12 @@ xfs_free_file_space( return(error); } + ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1); + if (attr_flags & ATTR_NOLOCK) + need_iolock = 0; if (need_iolock) xfs_ilock(ip, XFS_IOLOCK_EXCL); + rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog), (__uint8_t)NBPP); ilen = len + (offset & (rounding - 1)); -- cgit v1.2.3-59-g8ed1b From 1f443ad70d3afa6bc74019ade2d664eadd7d505a Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 5 May 2005 13:28:29 -0700 Subject: [XFS] Allow initial XFS delayed allocation size to be increased beyond 64KB. SGI Modid: xfs-linux:xfs-kern:22261a Signed-off-by: Nathan Scott Signed-off-by: Christoph Hellwig --- fs/xfs/xfs_mount.h | 6 ++--- fs/xfs/xfs_vfsops.c | 67 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 48 insertions(+), 25 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 5fc6201dd8e2..1b968471ec8b 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -428,10 +428,10 @@ typedef struct xfs_mount { #define XFS_WRITEIO_LOG_LARGE 16 /* - * Max and min values for UIO and mount-option defined I/O sizes; - * min value can't be less than a page. Currently unused. + * Max and min values for mount-option defined I/O + * preallocation sizes. */ -#define XFS_MAX_IO_LOG 16 /* 64K */ +#define XFS_MAX_IO_LOG 30 /* 1G */ #define XFS_MIN_IO_LOG PAGE_SHIFT /* diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 00aae9c6a904..b53736650100 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -1649,6 +1649,7 @@ xfs_vget( #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ +#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ #define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */ #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ #define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */ @@ -1657,6 +1658,28 @@ xfs_vget( #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ +STATIC unsigned long +suffix_strtoul(const char *cp, char **endp, unsigned int base) +{ + int last, shift_left_factor = 0; + char *value = (char *)cp; + + last = strlen(value) - 1; + if (value[last] == 'K' || value[last] == 'k') { + shift_left_factor = 10; + value[last] = '\0'; + } + if (value[last] == 'M' || value[last] == 'm') { + shift_left_factor = 20; + value[last] = '\0'; + } + if (value[last] == 'G' || value[last] == 'g') { + shift_left_factor = 30; + value[last] = '\0'; + } + + return simple_strtoul(cp, endp, base) << shift_left_factor; +} int xfs_parseargs( @@ -1688,60 +1711,60 @@ xfs_parseargs( if (!strcmp(this_char, MNTOPT_LOGBUFS)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_LOGBUFS); + this_char); return EINVAL; } args->logbufs = simple_strtoul(value, &eov, 10); } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { - int last, in_kilobytes = 0; - if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_LOGBSIZE); + this_char); return EINVAL; } - last = strlen(value) - 1; - if (value[last] == 'K' || value[last] == 'k') { - in_kilobytes = 1; - value[last] = '\0'; - } - args->logbufsize = simple_strtoul(value, &eov, 10); - if (in_kilobytes) - args->logbufsize <<= 10; + args->logbufsize = suffix_strtoul(value, &eov, 10); } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_LOGDEV); + this_char); return EINVAL; } strncpy(args->logname, value, MAXNAMELEN); } else if (!strcmp(this_char, MNTOPT_MTPT)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_MTPT); + this_char); return EINVAL; } strncpy(args->mtpt, value, MAXNAMELEN); } else if (!strcmp(this_char, MNTOPT_RTDEV)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_RTDEV); + this_char); return EINVAL; } strncpy(args->rtname, value, MAXNAMELEN); } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_BIOSIZE); + this_char); return EINVAL; } iosize = simple_strtoul(value, &eov, 10); args->flags |= XFSMNT_IOSIZE; args->iosizelog = (uint8_t) iosize; + } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { + if (!value || !*value) { + printk("XFS: %s option requires an argument\n", + this_char); + return EINVAL; + } + iosize = suffix_strtoul(value, &eov, 10); + args->flags |= XFSMNT_IOSIZE; + args->iosizelog = ffs(iosize) - 1; } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - this_char); + this_char); return EINVAL; } args->flags |= XFSMNT_IHASHSIZE; @@ -1756,7 +1779,7 @@ xfs_parseargs( args->flags |= XFSMNT_INO64; #if !XFS_BIG_INUMS printk("XFS: %s option not allowed on this system\n", - MNTOPT_INO64); + this_char); return EINVAL; #endif } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { @@ -1766,14 +1789,14 @@ xfs_parseargs( } else if (!strcmp(this_char, MNTOPT_SUNIT)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_SUNIT); + this_char); return EINVAL; } dsunit = simple_strtoul(value, &eov, 10); } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", - MNTOPT_SWIDTH); + this_char); return EINVAL; } dswidth = simple_strtoul(value, &eov, 10); @@ -1781,7 +1804,7 @@ xfs_parseargs( args->flags &= ~XFSMNT_32BITINODES; #if !XFS_BIG_INUMS printk("XFS: %s option not allowed on this system\n", - MNTOPT_64BITINODE); + this_char); return EINVAL; #endif } else if (!strcmp(this_char, MNTOPT_NOUUID)) { @@ -1877,7 +1900,7 @@ xfs_showargs( seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize); if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) - seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log); + seq_printf(m, "," MNTOPT_ALLOCSIZE "=%d", 1<m_writeio_log); if (mp->m_logbufs > 0) seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); -- cgit v1.2.3-59-g8ed1b From 764433b7f1cf5d7b5e27ceb4f5546042e1f4acc7 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 5 May 2005 13:29:17 -0700 Subject: [XFS] Fix up warnings SGI Modid: xfs-linux:xfs-kern:191411a Signed-off-by: Eric Sandeen Signed-off-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_vnode.c | 4 ++-- fs/xfs/linux-2.6/xfs_vnode.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c index 849c61c74f3c..4b1b1bcdb6b3 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.c +++ b/fs/xfs/linux-2.6/xfs_vnode.c @@ -424,13 +424,13 @@ vn_remove( * Vnode tracing code. */ void -vn_trace_entry(vnode_t *vp, char *func, inst_t *ra) +vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra) { KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); } void -vn_trace_exit(vnode_t *vp, char *func, inst_t *ra) +vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra) { KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); } diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 4ee229301241..00466c3194ac 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -648,8 +648,8 @@ static inline int VN_BAD(struct vnode *vp) #define VNODE_KTRACE_REF 4 #define VNODE_KTRACE_RELE 5 -extern void vn_trace_entry(struct vnode *, char *, inst_t *); -extern void vn_trace_exit(struct vnode *, char *, inst_t *); +extern void vn_trace_entry(struct vnode *, const char *, inst_t *); +extern void vn_trace_exit(struct vnode *, const char *, inst_t *); extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); -- cgit v1.2.3-59-g8ed1b From abd0cf7aeaaf8a15d9777e65606b6076868b6186 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 5 May 2005 13:30:13 -0700 Subject: [XFS] Resolve an issue with xfsbufd not getting along with swsusp. SGI Modid: xfs-linux:xfs-kern:22342a Signed-off-by: Nathan Scott Signed-off-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_buf.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 23e0eb67fc25..997963e53622 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1746,13 +1746,15 @@ STATIC DECLARE_COMPLETION(pagebuf_daemon_done); STATIC struct task_struct *pagebuf_daemon_task; STATIC int pagebuf_daemon_active; STATIC int force_flush; - +STATIC int force_sleep; STATIC int pagebuf_daemon_wakeup( int priority, unsigned int mask) { + if (force_sleep) + return 0; force_flush = 1; barrier(); wake_up_process(pagebuf_daemon_task); @@ -1778,7 +1780,12 @@ pagebuf_daemon( INIT_LIST_HEAD(&tmp); do { - try_to_freeze(PF_FREEZE); + if (unlikely(current->flags & PF_FREEZE)) { + force_sleep = 1; + refrigerator(PF_FREEZE); + } else { + force_sleep = 0; + } set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((xfs_buf_timer_centisecs * HZ) / 100); -- cgit v1.2.3-59-g8ed1b From 3f243766660da3df4a75ea1892c310d6080646c8 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 5 May 2005 13:30:34 -0700 Subject: [XFS] Disable the combination of XFS direct IO and AIO until the IO completion handling for unwritten extents can be moved out of interrupt context. SGI Modid: xfs-linux:xfs-kern:22343a Signed-off-by: Nathan Scott Signed-off-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_file.c | 43 +++++++++++++++++++++++++++++++++++++++++-- fs/xfs/linux-2.6/xfs_lrw.c | 3 +++ 2 files changed, 44 insertions(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 9f057a4a5b06..d0d412afd261 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -515,10 +515,49 @@ open_exec_out: } #endif /* HAVE_FOP_OPEN_EXEC */ +/* + * Temporary workaround to the AIO direct IO write problem. + * This code can go and we can revert to do_sync_write once + * the writepage(s) rework is merged. + */ +STATIC ssize_t +linvfs_write( + struct file *filp, + const char __user *buf, + size_t len, + loff_t *ppos) +{ + struct kiocb kiocb; + ssize_t ret; + + init_sync_kiocb(&kiocb, filp); + kiocb.ki_pos = *ppos; + ret = __linvfs_write(&kiocb, buf, 0, len, kiocb.ki_pos); + *ppos = kiocb.ki_pos; + return ret; +} +STATIC ssize_t +linvfs_write_invis( + struct file *filp, + const char __user *buf, + size_t len, + loff_t *ppos) +{ + struct kiocb kiocb; + ssize_t ret; + + init_sync_kiocb(&kiocb, filp); + kiocb.ki_pos = *ppos; + ret = __linvfs_write(&kiocb, buf, IO_INVIS, len, kiocb.ki_pos); + *ppos = kiocb.ki_pos; + return ret; +} + + struct file_operations linvfs_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, - .write = do_sync_write, + .write = linvfs_write, .readv = linvfs_readv, .writev = linvfs_writev, .aio_read = linvfs_aio_read, @@ -540,7 +579,7 @@ struct file_operations linvfs_file_operations = { struct file_operations linvfs_invis_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, - .write = do_sync_write, + .write = linvfs_write_invis, .readv = linvfs_readv_invis, .writev = linvfs_writev_invis, .aio_read = linvfs_aio_read_invis, diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index ff145fd0d1a4..aa9daaea6c34 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -683,6 +683,9 @@ xfs_write( (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? mp->m_rtdev_targp : mp->m_ddev_targp; + if (ioflags & IO_ISAIO) + return XFS_ERROR(-ENOSYS); + if ((pos & target->pbr_smask) || (count & target->pbr_smask)) return XFS_ERROR(-EINVAL); -- cgit v1.2.3-59-g8ed1b From 3ba0815a4b0709ef5e7b481067573d10806bbe2c Mon Sep 17 00:00:00 2001 From: Daniel Moore Date: Thu, 5 May 2005 13:31:34 -0700 Subject: [XFS] stop background sync from waiting for in-use inodes SGI Modid: xfs-linux:xfs-kern:191586a Signed-off-by: Daniel Moore Signed-off-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_aops.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 76a84758073a..1e71a9633d8f 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -725,9 +725,12 @@ xfs_page_state_convert( __uint64_t end_offset; pgoff_t end_index, last_index, tlast; int len, err, i, cnt = 0, uptodate = 1; - int flags = startio ? 0 : BMAPI_TRYLOCK; + int flags; int page_dirty, delalloc = 0; + /* wait for other IO threads? */ + flags = (startio && wbc->sync_mode != WB_SYNC_NONE) ? 0 : BMAPI_TRYLOCK; + /* Is this page beyond the end of the file? */ offset = i_size_read(inode); end_index = offset >> PAGE_CACHE_SHIFT; -- cgit v1.2.3-59-g8ed1b From 18e0a926ad7c5ab4ef05334230671c6975dac26b Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 5 May 2005 13:32:18 -0700 Subject: [XFS] remove noisy printk at vnode trace allocation SGI Modid: xfs-linux:xfs-kern:191625a Signed-off-by: Eric Sandeen Signed-off-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_vnode.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c index 4b1b1bcdb6b3..a832d165f24f 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.c +++ b/fs/xfs/linux-2.6/xfs_vnode.c @@ -156,7 +156,6 @@ vn_initialize( #ifdef XFS_VNODE_TRACE vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); - printk("Allocated VNODE_TRACE at 0x%p\n", vp->v_trace); #endif /* XFS_VNODE_TRACE */ vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address); -- cgit v1.2.3-59-g8ed1b From 775bf6c99a4ebde13bdb8dfa528ed241483b49ef Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 5 May 2005 13:33:01 -0700 Subject: [XFS] Do not do delalloc conversion on pages beyond EOF ever, not just sometimes SGI Modid: xfs-linux:xfs-kern:22376a Signed-off-by: Nathan Scott Signed-off-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_aops.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 1e71a9633d8f..1edd3b694332 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -726,7 +726,7 @@ xfs_page_state_convert( pgoff_t end_index, last_index, tlast; int len, err, i, cnt = 0, uptodate = 1; int flags; - int page_dirty, delalloc = 0; + int page_dirty; /* wait for other IO threads? */ flags = (startio && wbc->sync_mode != WB_SYNC_NONE) ? 0 : BMAPI_TRYLOCK; @@ -807,7 +807,6 @@ xfs_page_state_convert( */ } else if (buffer_delay(bh)) { if (!iomp) { - delalloc = 1; err = xfs_map_blocks(inode, offset, len, &iomap, BMAPI_ALLOCATE | flags); if (err) { @@ -882,10 +881,9 @@ xfs_page_state_convert( xfs_submit_page(page, wbc, bh_arr, cnt, 0, 1); if (iomp) { - tlast = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> + offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> PAGE_CACHE_SHIFT; - if (delalloc && (tlast > last_index)) - tlast = last_index; + tlast = min_t(pgoff_t, offset, last_index); xfs_cluster_write(inode, page->index + 1, iomp, wbc, startio, unmapped, tlast); } -- cgit v1.2.3-59-g8ed1b From 24e17b5fb99d4d1b47fe0847a3a801e36d431ff6 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 5 May 2005 13:33:20 -0700 Subject: [XFS] Use the right offset when ensuring a delayed allocate conversion has covered the offset originally requested. Can cause data corruption when multiple processes are performing writeout on different areas of the same file. Quite difficult to hit though. SGI Modid: xfs-linux:xfs-kern:22377a Signed-off-by: Nathan Scott Signed-off-by: Christoph Hellwig . --- fs/xfs/linux-2.6/xfs_aops.c | 68 ++++++++++++++++++++++++++------------------- fs/xfs/xfs_iomap.c | 20 +++++++------ fs/xfs/xfs_iomap.h | 7 ++--- fs/xfs/xfs_mount.h | 7 +++-- 4 files changed, 56 insertions(+), 46 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 1edd3b694332..9278e9aba9ba 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -558,7 +558,8 @@ xfs_submit_page( int i; BUG_ON(PageWriteback(page)); - set_page_writeback(page); + if (bh_count) + set_page_writeback(page); if (clear_dirty) clear_page_dirty(page); unlock_page(page); @@ -578,9 +579,6 @@ xfs_submit_page( if (probed_page && clear_dirty) wbc->nr_to_write--; /* Wrote an "extra" page */ - } else { - end_page_writeback(page); - wbc->pages_skipped++; /* We didn't write this page */ } } @@ -602,21 +600,26 @@ xfs_convert_page( { struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head; xfs_iomap_t *mp = iomapp, *tmp; - unsigned long end, offset; - pgoff_t end_index; - int i = 0, index = 0; + unsigned long offset, end_offset; + int index = 0; int bbits = inode->i_blkbits; + int len, page_dirty; - end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT; - if (page->index < end_index) { - end = PAGE_CACHE_SIZE; - } else { - end = i_size_read(inode) & (PAGE_CACHE_SIZE-1); - } + end_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1)); + + /* + * page_dirty is initially a count of buffers on the page before + * EOF and is decrememted as we move each into a cleanable state. + */ + len = 1 << inode->i_blkbits; + end_offset = max(end_offset, PAGE_CACHE_SIZE); + end_offset = roundup(end_offset, len); + page_dirty = end_offset / len; + + offset = 0; bh = head = page_buffers(page); do { - offset = i << bbits; - if (offset >= end) + if (offset >= end_offset) break; if (!(PageUptodate(page) || buffer_uptodate(bh))) continue; @@ -625,6 +628,7 @@ xfs_convert_page( if (startio) { lock_buffer(bh); bh_arr[index++] = bh; + page_dirty--; } continue; } @@ -657,10 +661,11 @@ xfs_convert_page( unlock_buffer(bh); mark_buffer_dirty(bh); } - } while (i++, (bh = bh->b_this_page) != head); + page_dirty--; + } while (offset += len, (bh = bh->b_this_page) != head); - if (startio) { - xfs_submit_page(page, wbc, bh_arr, index, 1, index == i); + if (startio && index) { + xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty); } else { unlock_page(page); } @@ -743,19 +748,22 @@ xfs_page_state_convert( } } - offset = (loff_t)page->index << PAGE_CACHE_SHIFT; end_offset = min_t(unsigned long long, - offset + PAGE_CACHE_SIZE, i_size_read(inode)); - - bh = head = page_buffers(page); - iomp = NULL; + (loff_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset); + offset = (loff_t)page->index << PAGE_CACHE_SHIFT; /* - * page_dirty is initially a count of buffers on the page and - * is decrememted as we move each into a cleanable state. + * page_dirty is initially a count of buffers on the page before + * EOF and is decrememted as we move each into a cleanable state. */ - len = bh->b_size; - page_dirty = PAGE_CACHE_SIZE / len; + len = 1 << inode->i_blkbits; + p_offset = max(p_offset, PAGE_CACHE_SIZE); + p_offset = roundup(p_offset, len); + page_dirty = p_offset / len; + + iomp = NULL; + p_offset = 0; + bh = head = page_buffers(page); do { if (offset >= end_offset) @@ -877,8 +885,10 @@ xfs_page_state_convert( if (uptodate && bh == head) SetPageUptodate(page); - if (startio) - xfs_submit_page(page, wbc, bh_arr, cnt, 0, 1); + if (startio) { + WARN_ON(page_dirty); + xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty); + } if (iomp) { offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 3826e8f0e28a..b291a2b53579 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -308,7 +308,8 @@ phase2: break; } - error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps); + error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, + &imap, &nimaps); break; case BMAPI_UNWRITTEN: lockmode = 0; @@ -746,6 +747,8 @@ write_map: int xfs_iomap_write_allocate( xfs_inode_t *ip, + loff_t offset, + size_t count, xfs_bmbt_irec_t *map, int *retmap) { @@ -770,9 +773,9 @@ xfs_iomap_write_allocate( if ((error = XFS_QM_DQATTACH(mp, ip, 0))) return XFS_ERROR(error); - offset_fsb = map->br_startoff; + offset_fsb = XFS_B_TO_FSBT(mp, offset); count_fsb = map->br_blockcount; - map_start_fsb = offset_fsb; + map_start_fsb = map->br_startoff; XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); @@ -868,9 +871,9 @@ xfs_iomap_write_allocate( imap[i].br_startoff, imap[i].br_blockcount,imap[i].br_state); } - if ((map->br_startoff >= imap[i].br_startoff) && - (map->br_startoff < (imap[i].br_startoff + - imap[i].br_blockcount))) { + if ((offset_fsb >= imap[i].br_startoff) && + (offset_fsb < (imap[i].br_startoff + + imap[i].br_blockcount))) { *map = imap[i]; *retmap = 1; XFS_STATS_INC(xs_xstrat_quick); @@ -883,9 +886,8 @@ xfs_iomap_write_allocate( * file, just surrounding data, try again. */ nimaps--; - offset_fsb = imap[nimaps].br_startoff + - imap[nimaps].br_blockcount; - map_start_fsb = offset_fsb; + map_start_fsb = imap[nimaps].br_startoff + + imap[nimaps].br_blockcount; } trans_cancel: diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index 31c91087cb33..287895a3adc1 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h @@ -29,9 +29,6 @@ * * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ - - - #ifndef __XFS_IOMAP_H__ #define __XFS_IOMAP_H__ @@ -56,7 +53,7 @@ typedef enum { BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */ /* modifiers */ BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ - BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ + BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */ @@ -100,7 +97,7 @@ extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t, int, struct xfs_bmbt_irec *, int *, int); extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t, int, struct xfs_bmbt_irec *, int *); -extern int xfs_iomap_write_allocate(struct xfs_inode *, +extern int xfs_iomap_write_allocate(struct xfs_inode *, loff_t, size_t, struct xfs_bmbt_irec *, int *); extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 1b968471ec8b..8ffb65dc110d 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -216,7 +216,8 @@ typedef int (*xfs_iomap_write_delay_t)( void *, loff_t, size_t, int, struct xfs_bmbt_irec *, int *); typedef int (*xfs_iomap_write_allocate_t)( - void *, struct xfs_bmbt_irec *, int *); + void *, loff_t, size_t, + struct xfs_bmbt_irec *, int *); typedef int (*xfs_iomap_write_unwritten_t)( void *, loff_t, size_t); typedef uint (*xfs_lck_map_shared_t)(void *); @@ -258,9 +259,9 @@ typedef struct xfs_ioops { #define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \ (*(mp)->m_io_ops.xfs_iomap_write_delay) \ ((io)->io_obj, offset, count, flags, mval, nmap) -#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, mval, nmap) \ +#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, mval, nmap) \ (*(mp)->m_io_ops.xfs_iomap_write_allocate) \ - ((io)->io_obj, mval, nmap) + ((io)->io_obj, offset, count, mval, nmap) #define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \ (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \ ((io)->io_obj, offset, count) -- cgit v1.2.3-59-g8ed1b From f403b7f452e4347f6af14c1f3c47bce758eb6337 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 5 May 2005 13:33:40 -0700 Subject: [XFS] Cleanup use of loff_t vs xfs_off_t in the core code. SGI Modid: xfs-linux:xfs-kern:22378a Signed-off-by: Nathan Scott Signed-off-by: Christoph Hellwig --- fs/xfs/xfs_dfrag.c | 2 +- fs/xfs/xfs_iomap.c | 8 ++++---- fs/xfs/xfs_iomap.h | 20 ++++++++++---------- fs/xfs/xfs_mount.h | 8 ++++---- 4 files changed, 19 insertions(+), 19 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 08d551a17347..63abdc2ac7f4 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -182,7 +182,7 @@ xfs_swapext( if (VN_CACHED(tvp) != 0) xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore), - (loff_t)0, 0, 0); + (xfs_off_t)0, 0, 0); /* Verify O_DIRECT for ftmp */ if (VN_CACHED(tvp) != 0) { diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index b291a2b53579..991f8a61f7c4 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -366,7 +366,7 @@ xfs_flush_space( int xfs_iomap_write_direct( xfs_inode_t *ip, - loff_t offset, + xfs_off_t offset, size_t count, int flags, xfs_bmbt_irec_t *ret_imap, @@ -542,7 +542,7 @@ error_out: int xfs_iomap_write_delay( xfs_inode_t *ip, - loff_t offset, + xfs_off_t offset, size_t count, int ioflag, xfs_bmbt_irec_t *ret_imap, @@ -747,7 +747,7 @@ write_map: int xfs_iomap_write_allocate( xfs_inode_t *ip, - loff_t offset, + xfs_off_t offset, size_t count, xfs_bmbt_irec_t *map, int *retmap) @@ -901,7 +901,7 @@ error0: int xfs_iomap_write_unwritten( xfs_inode_t *ip, - loff_t offset, + xfs_off_t offset, size_t count) { xfs_mount_t *mp = ip->i_mount; diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index 287895a3adc1..4daaa5212102 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003,2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -64,13 +64,13 @@ typedef enum { /* * xfs_iomap_t: File system I/O map * - * The iomap_bn field is expressed in 512-byte blocks, and is where the + * The iomap_bn field is expressed in 512-byte blocks, and is where the * mapping starts on disk. * * The iomap_offset, iomap_bsize and iomap_delta fields are in bytes. * iomap_offset is the offset of the mapping in the file itself. - * iomap_bsize is the size of the mapping, iomap_delta is the - * desired data's offset into the mapping, given the offset supplied + * iomap_bsize is the size of the mapping, iomap_delta is the + * desired data's offset into the mapping, given the offset supplied * to the file I/O map routine. * * When a request is made to read beyond the logical end of the object, @@ -81,8 +81,8 @@ typedef enum { typedef struct xfs_iomap { xfs_daddr_t iomap_bn; /* first 512b blk of mapping */ xfs_buftarg_t *iomap_target; - loff_t iomap_offset; /* offset of mapping, bytes */ - loff_t iomap_bsize; /* size of mapping, bytes */ + xfs_off_t iomap_offset; /* offset of mapping, bytes */ + xfs_off_t iomap_bsize; /* size of mapping, bytes */ size_t iomap_delta; /* offset into mapping, bytes */ iomap_flags_t iomap_flags; } xfs_iomap_t; @@ -93,12 +93,12 @@ struct xfs_bmbt_irec; extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int, struct xfs_iomap *, int *); -extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t, +extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, int, struct xfs_bmbt_irec *, int *, int); -extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t, int, +extern int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, int, struct xfs_bmbt_irec *, int *); -extern int xfs_iomap_write_allocate(struct xfs_inode *, loff_t, size_t, +extern int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t, struct xfs_bmbt_irec *, int *); -extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t); +extern int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, size_t); #endif /* __XFS_IOMAP_H__*/ diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 8ffb65dc110d..30dd08fb9f57 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -210,16 +210,16 @@ typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, struct xfs_bmap_free *); typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); typedef int (*xfs_iomap_write_direct_t)( - void *, loff_t, size_t, int, + void *, xfs_off_t, size_t, int, struct xfs_bmbt_irec *, int *, int); typedef int (*xfs_iomap_write_delay_t)( - void *, loff_t, size_t, int, + void *, xfs_off_t, size_t, int, struct xfs_bmbt_irec *, int *); typedef int (*xfs_iomap_write_allocate_t)( - void *, loff_t, size_t, + void *, xfs_off_t, size_t, struct xfs_bmbt_irec *, int *); typedef int (*xfs_iomap_write_unwritten_t)( - void *, loff_t, size_t); + void *, xfs_off_t, size_t); typedef uint (*xfs_lck_map_shared_t)(void *); typedef void (*xfs_lock_t)(void *, uint); typedef void (*xfs_lock_demote_t)(void *, uint); -- cgit v1.2.3-59-g8ed1b From 68d1498c3a7e5223b587ad067111fbed12df52a1 Mon Sep 17 00:00:00 2001 From: Russell Cattelan Date: Fri, 6 May 2005 06:42:22 -0700 Subject: [XFS] Fix a bug in xfs_iomap for extent handling of write cases This may be the cause of several open PV's of incorrect delay flags being set and then tripping asserts. Do not return a delay alloc extent when the caller is asking to do a write. SGI Modid: xfs-linux:xfs-kern:189616a Signed-off-by: Russell Cattelan Signed-off-by: Christoph Hellwig --- fs/xfs/xfs_iomap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 991f8a61f7c4..469e1a7939d4 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -278,7 +278,9 @@ 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) && + (imap.br_startblock != DELAYSTARTBLOCK)) { xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io, offset, count, iomapp, &imap, flags); break; -- cgit v1.2.3-59-g8ed1b From d3870398fafd4911bd84573b78be4b6b762f32b0 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Fri, 6 May 2005 06:44:46 -0700 Subject: [XFS] Fix directory inodes ioctl compat code, minor code consistency cleanups SGI Modid: xfs-linux:xfs-kern:21810a Signed-off-by: Nathan Scott Signed-off-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_file.c | 7 +++++-- fs/xfs/linux-2.6/xfs_ioctl32.c | 29 +++++++++++++++++++---------- fs/xfs/linux-2.6/xfs_ioctl32.h | 6 +++--- fs/xfs/linux-2.6/xfs_super.c | 3 +-- 4 files changed, 28 insertions(+), 17 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index d0d412afd261..24fa3b101b93 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -565,7 +565,7 @@ struct file_operations linvfs_file_operations = { .sendfile = linvfs_sendfile, .unlocked_ioctl = linvfs_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = xfs_compat_ioctl, + .compat_ioctl = linvfs_compat_ioctl, #endif .mmap = linvfs_file_mmap, .open = linvfs_open, @@ -587,7 +587,7 @@ struct file_operations linvfs_invis_file_operations = { .sendfile = linvfs_sendfile, .unlocked_ioctl = linvfs_ioctl_invis, #ifdef CONFIG_COMPAT - .compat_ioctl = xfs_compat_invis_ioctl, + .compat_ioctl = linvfs_compat_invis_ioctl, #endif .mmap = linvfs_file_mmap, .open = linvfs_open, @@ -600,6 +600,9 @@ struct file_operations linvfs_dir_operations = { .read = generic_read_dir, .readdir = linvfs_readdir, .unlocked_ioctl = linvfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = linvfs_compat_ioctl, +#endif .fsync = linvfs_fsync, }; diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index 7a12c83184f5..0f8f1384eb36 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -58,8 +58,9 @@ typedef struct xfs_fsop_bulkreq32 { __s32 ocount; /* output count pointer */ } xfs_fsop_bulkreq32_t; -static unsigned long -xfs_ioctl32_bulkstat(unsigned long arg) +STATIC unsigned long +xfs_ioctl32_bulkstat( + unsigned long arg) { xfs_fsop_bulkreq32_t __user *p32 = (void __user *)arg; xfs_fsop_bulkreq_t __user *p = compat_alloc_user_space(sizeof(*p)); @@ -78,11 +79,11 @@ xfs_ioctl32_bulkstat(unsigned long arg) } #endif -static long -__xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) +STATIC long +__linvfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) { int error; - struct inode *inode = f->f_dentry->d_inode; + struct inode *inode = f->f_dentry->d_inode; vnode_t *vp = LINVFS_GET_VP(inode); switch (cmd) { @@ -152,12 +153,20 @@ __xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) return error; } -long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) +long +linvfs_compat_ioctl( + struct file *f, + unsigned cmd, + unsigned long arg) { - return __xfs_compat_ioctl(0, f, cmd, arg); + return __linvfs_compat_ioctl(0, f, cmd, arg); } -long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg) +long +linvfs_compat_invis_ioctl( + struct file *f, + unsigned cmd, + unsigned long arg) { - return __xfs_compat_ioctl(IO_INVIS, f, cmd, arg); + return __linvfs_compat_ioctl(IO_INVIS, f, cmd, arg); } diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.h b/fs/xfs/linux-2.6/xfs_ioctl32.h index 779f69a48116..c874793a1dc9 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.h +++ b/fs/xfs/linux-2.6/xfs_ioctl32.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -30,5 +30,5 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); -long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg); +long linvfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); +long linvfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg); diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 53dc658cafa6..455e2b2fb964 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -66,7 +66,6 @@ #include "xfs_buf_item.h" #include "xfs_utils.h" #include "xfs_version.h" -#include "xfs_ioctl32.h" #include #include -- cgit v1.2.3-59-g8ed1b From 66f5507133f97088e553b1c8f8d341a0efd438f9 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 27 May 2005 01:17:08 -0700 Subject: [XFS] remove an over-zealous WARN_ON --- fs/xfs/linux-2.6/xfs_aops.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 9278e9aba9ba..93ce257cd149 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -886,7 +886,6 @@ xfs_page_state_convert( SetPageUptodate(page); if (startio) { - WARN_ON(page_dirty); xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty); } -- cgit v1.2.3-59-g8ed1b