[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) */