[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: XFS NFS server Oops
On Mon, 2002-02-04 at 07:30, Ian D. Hardy wrote:
> Hi,
>
> Anyone any ideas on the following Oops (processed with ksymoops 2.4.3). It is
> from a NFS server (Dual 1Ghz Supermicro LE, 1Gbyte RAM, 40Gbyte Maxtor IDE
> system disk, Zero-D/GForce RI Fibrechannel to IDE hardware RAID-5 500Gbyte
> disk unit). It is running the Linux 2.4.17-xfs kernel taken as a CVS image
> on 27th January. The main area of disk it is serving is on the HW RAID unit,
> which is the only XFS filesystem on the system. The system had been up
> for just over 3 days when it crashed.
>
> I reported a very similar failure a few weeks ago, at that time running a
> 2.4.9 based kernel, Steve Lord suggested that we tried the latest CVS image
> as this had fixed some memory alloacation problems.
>
> The machine is essentially an NFS fileserver to a computational cluster. Though
> of possible interest is the 'save' process that was running on one of the
> processes, this is the Legato Networker backup client process (which was
> performing a full backup of the XFS filesystem at the time). I don't think
> this is significant as I was seeing these crashes (at ~4 to 12 day intervals)
> with the 2.4.9 kernel not dependant upon a 'save' session running.
>
>
Ian, can you try the attached patch against a current cvs kernel and see
if it helps at all.
Steve
--
Steve Lord voice: +1-651-683-3511
Principal Engineer, Filesystem Software email: lord@sgi.com
===========================================================================
Index: linux/fs/xfs/linux/xfs_super.c
===========================================================================
--- /usr/tmp/TmpDir.7400-0/linux/fs/xfs/linux/xfs_super.c_1.161 Wed Mar 6 13:11:35 2002
+++ linux/fs/xfs/linux/xfs_super.c Tue Mar 5 04:54:59 2002
@@ -606,6 +606,7 @@
vnode_t *vp = LINVFS_GET_VP(inode);
if (vp) {
+ vn_rele(vp);
vn_trace_entry(vp, "linvfs_delete_inode",
(inst_t *)__return_address);
/*
@@ -626,6 +627,7 @@
vnode_t *vp = LINVFS_GET_VP(inode);
if (vp) {
+ vn_rele(vp);
vn_trace_entry(vp, "linvfs_clear_inode",
(inst_t *)__return_address);
/*
@@ -638,11 +640,13 @@
void
linvfs_put_inode(
- struct inode *inode)
+ struct inode *ip)
{
- vnode_t *vp = LINVFS_GET_VP(inode);
+ vnode_t *vp = LINVFS_GET_VP(ip);
+ int error;
- if (vp) vn_put(vp);
+ if (vp && (atomic_read(&ip->i_count) == 1))
+ VOP_RELEASE(vp, error);
}
void
===========================================================================
Index: linux/fs/xfs/linux/xfs_vnode.c
===========================================================================
--- /usr/tmp/TmpDir.7400-0/linux/fs/xfs/linux/xfs_vnode.c_1.69 Wed Mar 6 13:11:35 2002
+++ linux/fs/xfs/linux/xfs_vnode.c Tue Mar 5 04:42:15 2002
@@ -224,29 +224,6 @@
}
/*
- * Free an isolated vnode.
- * The vnode must not have any other references.
- */
-void
-vn_free(struct vnode *vp)
-{
- struct inode *inode;
-
- XFS_STATS_INC(xfsstats.vn_free);
-
- vn_trace_entry(vp, "vn_free", (inst_t *)__return_address);
-
- ASSERT(vn_count(vp) == 1);
-
- ASSERT((vp->v_flag & VPURGE) == 0);
- vp->v_fbhv = NULL;
- inode = LINVFS_GET_IP(vp);
- inode->i_sb = NULL;
- iput(inode);
-}
-
-
-/*
* Get a reference on a vnode.
*/
vnode_t *
@@ -276,25 +253,6 @@
return vp;
}
-
-/*
- * "Temporary" routine to return the linux inode
- * hold count, after everybody else can directly
- * reference the inode (header magic!), this
- * routine is dead meat..
- */
-int
-vn_count(struct vnode *vp)
-{
- struct inode *inode;
-
- inode = LINVFS_GET_IP(vp);
-
- ASSERT(inode);
-
- return atomic_read(&inode->i_count);
-}
-
/*
* "revalidate" the linux inode.
*/
@@ -439,19 +397,10 @@
}
/*
- * Release a vnode.
- */
-void
-vn_rele(struct vnode *vp)
-{
- iput(LINVFS_GET_IP(vp));
-}
-
-/*
* Call VOP_INACTIVE on last reference.
*/
void
-vn_put(struct vnode *vp)
+vn_rele(struct vnode *vp)
{
int s;
int vcnt;
@@ -473,7 +422,7 @@
* that i_count won't be decremented after we
* return.
*/
- if (vcnt == 1) {
+ if (vcnt == 0) {
/*
* It is absolutely, positively the case that
* the lock manager will not be releasing vnodes
===========================================================================
Index: linux/fs/xfs/linux/xfs_vnode.h
===========================================================================
--- /usr/tmp/TmpDir.7400-0/linux/fs/xfs/linux/xfs_vnode.h_1.26 Wed Mar 6 13:11:35 2002
+++ linux/fs/xfs/linux/xfs_vnode.h Sun Mar 3 18:04:15 2002
@@ -719,7 +719,6 @@
* incremented to define a new vnode epoch.
*/
extern void vn_init(void);
-extern void vn_free(struct vnode *);
extern int vn_wait(struct vnode *);
extern vnode_t *vn_address(struct inode *);
extern vnode_t *vn_initialize(struct vfs *, struct inode *, int);
@@ -750,12 +749,18 @@
#define VMAP(vp, ip, vmap) {(vmap).v_vfsp = (vp)->v_vfsp, \
(vmap).v_number = (vp)->v_number, \
(vmap).v_ino = (ip)->i_ino; }
-extern int vn_count(struct vnode *);
extern void vn_purge(struct vnode *, vmap_t *);
extern vnode_t *vn_get(struct vnode *, vmap_t *, uint);
extern int vn_revalidate(struct vnode *, int);
extern void vn_remove(struct vnode *);
+static inline int vn_count(struct vnode *vp)
+{
+ struct inode *ip = LINVFS_GET_IP(vp);
+
+ return atomic_read(&ip->i_count);
+}
+
/*
* Flags for vn_get().
*/
@@ -766,7 +771,6 @@
*/
extern vnode_t *vn_hold(struct vnode *);
extern void vn_rele(struct vnode *);
-extern void vn_put(struct vnode *);
#if defined(CONFIG_XFS_VNODE_TRACING)
@@ -775,12 +779,12 @@
vn_trace_hold(vp, __FILE__, __LINE__, (inst_t *)__return_address))
#define VN_RELE(vp) \
(vn_trace_rele(vp, __FILE__, __LINE__, (inst_t *)__return_address), \
- vn_rele(vp))
+ iput(LINVFS_GET_IP(vp)))
#else /* ! (defined(CONFIG_XFS_VNODE_TRACING)) */
#define VN_HOLD(vp) ((void)vn_hold(vp))
-#define VN_RELE(vp) (vn_rele(vp))
+#define VN_RELE(vp) (iput(LINVFS_GET_IP(vp)))
#endif /* ! (defined(CONFIG_XFS_VNODE_TRACING) */