[Ocfs2-commits] rev 27 - in trunk/src: . inc

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Feb 5 20:50:03 CST 2004


Author: manish
Date: 2004-02-05 20:50:01 -0600 (Thu, 05 Feb 2004)
New Revision: 27

Modified:
   trunk/src/dcache.c
   trunk/src/file.c
   trunk/src/inc/proto.h
   trunk/src/inode.c
   trunk/src/namei.c
   trunk/src/nm.c
   trunk/src/oin.c
Log:
fixes nasty deadlock with truncate_inode_pages while holding oin main_res, removes ofile for non-directories and thus fixes problem in file close where oin was
being taken from ofile


Modified: trunk/src/dcache.c
===================================================================
--- trunk/src/dcache.c	2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/dcache.c	2004-02-06 02:50:01 UTC (rev 27)
@@ -20,6 +20,7 @@
 	ocfs_find_inode_args args;
         struct qstr q;
 	struct buffer_head *fe_bh = NULL;
+	int needs_trunc;
 
         LOG_ENTRY_ARGS ("(0x%08x, %d, '%*s')\n", dentry, flags,
                         dentry->d_name.len, dentry->d_name.name);
@@ -53,10 +54,12 @@
                 /* TODO: optimize */
 		ocfs_down_sem (&(oin->main_res), true);
 		oin->needs_verification = true;
-		tmpstat = ocfs_verify_update_oin(osb, oin);
+		tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
 		if (tmpstat < 0)
 			LOG_ERROR_STATUS (tmpstat);
 		ocfs_up_sem (&(oin->main_res));
+		if (needs_trunc)
+			ocfs_truncate_inode_pages(inode, 0);
 		goto bail;
 	} 
         

Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c	2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/file.c	2004-02-06 02:50:01 UTC (rev 27)
@@ -28,7 +28,6 @@
 {
 	struct dentry *dentry = file->f_dentry;
 	struct inode *parent = dentry->d_parent->d_inode;
-	ocfs_file *ofile = NULL;
 	int ret =0, err = 0, status = 0;
 	int mode = file->f_flags;
 	ocfs_super *osb = NULL;
@@ -40,6 +39,7 @@
 	struct buffer_head *fe_bh = NULL;
 	__u64 parent_off;
 	ocfs_sem *oin_sem = NULL;
+	int truncate_pages = 0;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, '%*s')\n", inode, file, 
                         file->f_dentry->d_name.len, file->f_dentry->d_name.name);
@@ -154,7 +154,7 @@
 
 	/* only call ocfs_verify_update_oin if there's a good inode */
 	if (oin->inode == inode && OIN_NEEDS_VERIFICATION(oin)) {
-		status = ocfs_verify_update_oin (osb, oin);
+		status = ocfs_verify_update_oin (osb, oin, &truncate_pages);
 		if (status < 0) {
 			/*  disable VOLUME TODO */
 			LOG_ERROR_STATUS (status);
@@ -194,23 +194,11 @@
 			OCFS_SET_FLAG(oin->oin_flags, OCFS_OIN_OPEN_FOR_DIRECTIO);
 		else {
 			OCFS_CLEAR_FLAG(oin->oin_flags, OCFS_OIN_OPEN_FOR_DIRECTIO);
-			fsync_inode_buffers(inode);
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
-			fsync_inode_data_buffers(inode);
-#endif
-			if (inode->i_data.nrpages)
-				ocfs_truncate_inode_pages(inode, 0);
+			truncate_pages = 1;
 		}
 	}
 
-	ofile = ocfs_allocate_ofile (OCFS_ATTRIB_REG);
-	if (ofile == NULL) {
-		LOG_ERROR_STATUS (status = -ENOMEM);
-		goto leave;
-	}
-
 	oin->open_hndl_cnt++;
-	ofile->oin = oin;
 
 	/* We should clear the in use now as we are safe from the case */
 	/* where the voting thread can vote and we have an open in */
@@ -224,6 +212,16 @@
 		bAcquiredOIN = false;
 	}
 
+	if (truncate_pages) {
+		fsync_inode_buffers(inode);
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
+		fsync_inode_data_buffers(inode);
+#endif
+		if (inode->i_data.nrpages)
+			ocfs_truncate_inode_pages(inode, 0);
+	}
+
+
 	status = 0;
 
 leave:
@@ -258,7 +256,6 @@
 			ret = status;
 		atomic_dec (&parent->i_count);
 	} else {
-		file->private_data = (void *) ofile;
 		ret = 0;
 	}
 
@@ -276,10 +273,9 @@
  */
 int ocfs_file_release (struct inode *inode, struct file *file)
 {
-	//int nbhs = KIO_MAX_SECTORS;
 	ocfs_file *ofile = NULL;
         ocfs_super * osb;
-        ocfs_inode *oin;
+        ocfs_inode *oin = NULL;
         struct dentry *dentry;
         struct inode *parent;
 
@@ -312,24 +308,15 @@
 			        ocfs_safefree (ofile->curr_dir_buf);
 			        ofile->curr_dir_buf = NULL;
 		        }
-		        // hmm
-		        // if (ofile->f_iobuf)
-		        //        free_kiovec_sz(1, &ofile->f_iobuf, &nbhs);
 		        ocfs_release_ofile (ofile);
                 }
                 goto bail;
         }
 
         /* file */
-        oin = NULL;
-                
-        if (ofile == NULL) {
-		if (inode_data_is_oin(inode))
-			oin = GET_INODE_OIN(inode);
-	} else {
-        	oin = ofile->oin;
-	        ocfs_release_ofile (ofile);
-	}
+	if (inode_data_is_oin(inode))
+		oin = GET_INODE_OIN(inode);
+
 	if (oin == NULL)
 		goto do_parent_dec;
 	  
@@ -338,8 +325,8 @@
 	    oin->main_res.magic != OCFS_SEM_MAGIC) {
 		int i;
 		
-		LOG_ERROR_ARGS("oin appears to have been freed!  oin=%p, ofile=%p, inode->oin=%p\n",
-			       oin, ofile, GET_INODE_OIN(inode));
+		LOG_ERROR_ARGS("oin appears to have been freed!  oin=%p, inode->oin=%p\n",
+			       oin, GET_INODE_OIN(inode));
 		for (i=0; i<sizeof (ocfs_inode); i++) {
 			printk("%03x ", ((char *)oin)[i]);
 		}
@@ -364,13 +351,6 @@
         /* for the inode, but here I just check this one becuz I'm lz */
         /* no hard links yet so who cares */
         if (!atomic_read(&dentry->d_count)) { 
-		fsync_inode_buffers(inode);
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
-		fsync_inode_data_buffers(inode);
-#endif
-		if (inode->i_data.nrpages)
-			ocfs_truncate_inode_pages(inode, 0);
-
 		if (oin->oin_flags & OCFS_OIN_OPEN_FOR_DIRECTIO) {
 			OCFS_CLEAR_FLAG(oin->oin_flags, OCFS_OIN_OPEN_FOR_DIRECTIO);
 		}
@@ -382,16 +362,23 @@
 		
                 ocfs_up_sem (&(oin->main_res));
                 ocfs_release_oin (oin, true);
-        } else {
 		fsync_inode_buffers(inode);
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
 		fsync_inode_data_buffers(inode);
 #endif
 		if (inode->i_data.nrpages)
 			ocfs_truncate_inode_pages(inode, 0);
-
+        } else {
                 ocfs_up_sem (&(oin->main_res));
                 ocfs_release_cached_oin (osb, oin);
+		fsync_inode_buffers(inode);
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
+		fsync_inode_data_buffers(inode);
+#endif
+		if (inode->i_data.nrpages)
+			ocfs_truncate_inode_pages(inode, 0);
+
+
         }
         
 do_parent_dec:
@@ -597,6 +584,7 @@
 	__u64 newsize;
 	ocfs_lock_res *lockres = NULL;
 	struct super_block *sb = inode->i_sb;
+	int needs_trunc = 0;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, %d, '%*s')\n", filp, buf, count,
                         filp->f_dentry->d_name.len, filp->f_dentry->d_name.name);
@@ -672,8 +660,10 @@
 	if (OIN_NEEDS_VERIFICATION (oin)) {
 		LOG_TRACE_STR ("OIN_NEEDS_VERIFICATION");
 		ocfs_down_sem (&(oin->main_res), true);
-		status = ocfs_verify_update_oin (osb, oin);
+		status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
 		ocfs_up_sem (&(oin->main_res));
+		if (needs_trunc)
+			ocfs_truncate_inode_pages(inode, 0);
 		if (status < 0) {
 			LOG_TRACE_STR ("ocfs_verify_update_oin failed");
 			LOG_TRACE_STR ("TODO: disable volume");
@@ -772,7 +762,7 @@
 	ocfs_inode *oin = NULL;
 	ocfs_super *osb = NULL;
 	struct inode *inode = filp->f_dentry->d_inode;
-	int status;
+	int status = 0, needs_trunc = 0;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, %d, '%*s')\n", filp, buf, count,
                         filp->f_dentry->d_name.len, filp->f_dentry->d_name.name);
@@ -798,8 +788,10 @@
 
 	if (OIN_NEEDS_VERIFICATION (oin)) {
 		ocfs_down_sem (&(oin->main_res), true);
-		status = ocfs_verify_update_oin (osb, oin);
+		status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
 		ocfs_up_sem (&(oin->main_res));
+		if (needs_trunc)
+			ocfs_truncate_inode_pages(inode, 0);
 		if (status < 0) {
 			LOG_TRACE_STR ("ocfs_verify_update_oin failed");
 			LOG_TRACE_STR ("TODO: disable volume");
@@ -1305,6 +1297,7 @@
 	__u64 parentOff, fileOff;
 	struct super_block *sb = inode->i_sb;
 	bool extended = false;
+	int needs_trunc = 0;
 
 	LOG_ENTRY_ARGS ("(0x%08x, '%*s')\n", dentry,
                         dentry->d_name.len, dentry->d_name.name);
@@ -1358,7 +1351,7 @@
 			ocfs_down_sem (&(oin->main_res), true);
 			if (OIN_NEEDS_VERIFICATION (oin)) {
 				LOG_TRACE_STR ("OIN_NEEDS_VERIFICATION");
-				status = ocfs_verify_update_oin (osb, oin);
+				status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
 				if (status < 0) {
 					LOG_ERROR_STATUS (status);
 					LOG_TRACE_STR ("TODO: disable volume");
@@ -1368,6 +1361,8 @@
 				}
 			}
 			ocfs_up_sem (&(oin->main_res));
+			if (needs_trunc)
+				ocfs_truncate_inode_pages(inode, 0);
 		}
 
                 if (inode->i_size > newsize)
@@ -1478,7 +1473,7 @@
 	ocfs_inode *oin;
 	struct inode *inode;
 	struct super_block *sb = dentry->d_inode->i_sb;
-	int status;
+	int status, needs_trunc = 0;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, '%*s')\n", dentry, attr,
                         dentry->d_name.len, dentry->d_name.name);
@@ -1491,8 +1486,10 @@
 		goto bail;
 	if (oin != NULL) {
 		ocfs_down_sem (&(oin->main_res), true);
-		status = ocfs_verify_update_oin (oin->osb, oin);
+		status = ocfs_verify_update_oin (oin->osb, oin, &needs_trunc);
 		ocfs_up_sem (&(oin->main_res));
+		if (needs_trunc)
+			ocfs_truncate_inode_pages(inode, 0);
 		if (status < 0)
 			LOG_ERROR_STATUS (status);
 	}

Modified: trunk/src/inc/proto.h
===================================================================
--- trunk/src/inc/proto.h	2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/inc/proto.h	2004-02-06 02:50:01 UTC (rev 27)
@@ -113,7 +113,7 @@
 void ocfs_linux_dbg_free (const void *Buffer);
 
 
-int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin);
+int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin, int *needs_trunc);
 int ocfs_create_oin_from_entry (ocfs_super * osb, struct buffer_head * fe_bh, ocfs_inode ** new_oin, __u64 parent_dir_off, struct inode *inode);
 int ocfs_initialize_oin (ocfs_inode * oin, ocfs_super * osb, __u32 flags, __u64 file_off, __u64 lock_id, bool new_file, struct inode *inode);
 int ocfs_create_new_oin (ocfs_inode ** Returnedoin, __u64 alloc_size, ocfs_super * osb);

Modified: trunk/src/inode.c
===================================================================
--- trunk/src/inode.c	2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/inode.c	2004-02-06 02:50:01 UTC (rev 27)
@@ -1193,6 +1193,7 @@
 	int set_new = 0; /* flag */
 	u32 new_size; /* In sectors, the size of the contiguous block */
 	unsigned char blocksize_bits;
+	int needs_trunc = 0;
 
 	if (!inode || !bh_result) {
 		LOG_ERROR_STR("ocfs_direct_IO_get_blocks: inode or bh_result is null");
@@ -1209,7 +1210,9 @@
 	/* make sure we're up to date... */
 	if (OIN_NEEDS_VERIFICATION (oin)) {
 		LOG_TRACE_STR ("ocfs_direct_IO_get_blocks: verify oin.");
-		status = ocfs_verify_update_oin (osb, oin);
+		status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
+		if (needs_trunc) 
+			ocfs_truncate_inode_pages(inode, 0);
 		if (status < 0) {
 			LOG_TRACE_STR ("ocfs_verify_update_oin failed");
 			ret = -EIO;

Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c	2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/namei.c	2004-02-06 02:50:01 UTC (rev 27)
@@ -867,6 +867,7 @@
 	__u32 oldfe_lockid = 0;
 	__u32 newfe_flags = 0;
 	__u32 newfe_lockid = 0;
+	int needs_trunc = 0;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, 0x%08x, 0x%08x, from='%*s' to='%*s')\n",
 			old_dir, old_dentry, new_dir, new_dentry,
@@ -933,9 +934,11 @@
 			/* OIN exists and it's not marked for deletion! */
 			ocfs_down_sem (&(newOIN->main_res), true);
 			OCFS_SET_FLAG (newOIN->oin_flags, OCFS_OIN_IN_USE);
+			status = ocfs_verify_update_oin (osb, newOIN, &needs_trunc);
 			ocfs_up_sem (&(newOIN->main_res));
-			status = ocfs_verify_update_oin (osb, newOIN);
 			delete_target_oin = true;
+			if (needs_trunc)
+				ocfs_truncate_inode_pages(new_inode, 0);
 		}
 	}
 

Modified: trunk/src/nm.c
===================================================================
--- trunk/src/nm.c	2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/nm.c	2004-02-06 02:50:01 UTC (rev 27)
@@ -713,6 +713,7 @@
 	ocfs_dlm_msg *dlm_msg = (comm_vote ? ctxt->u.dlm_msg : NULL);
 	__u32 node_num = ctxt->node_num;
 	__u64 lock_id, seq_num;
+	int needs_trunc = 0;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x)\n", osb, ctxt);
 
@@ -802,10 +803,16 @@
 			LOG_TRACE_STR("UPDATE_OIN_INODE");
 			ocfs_down_sem (&(oin->main_res), true);
 			oin->needs_verification = true;
-			tmpstat = ocfs_verify_update_oin(osb, oin);
+			tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
 			if (tmpstat < 0)
 				LOG_ERROR_STATUS (tmpstat);
 			ocfs_up_sem (&(oin->main_res));
+			if (needs_trunc) {
+				if (inode)
+					ocfs_truncate_inode_pages(inode, 0);
+				else
+					LOG_ERROR_STR("cannot truncate inode pages, inode NULL!");
+			}
 			vote_response = FLAG_VOTE_OIN_UPDATED;
 			break;
 		
@@ -820,13 +827,17 @@
 				oin_sem = &(oin->main_res);
 				ocfs_down_sem (oin_sem, true);
 				oin->needs_verification = true;
-				tmpstat = ocfs_verify_update_oin(osb, oin);
+				tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
 				if (tmpstat < 0)
 					LOG_ERROR_STATUS (tmpstat);
 		
 				/* If OIN_IN_USE is set we should go back and retry */
 				for (i=0; i<5 && oin->oin_flags & OCFS_OIN_IN_USE; i++) {
 					ocfs_up_sem (oin_sem);
+					if (needs_trunc) {
+						ocfs_truncate_inode_pages(inode, 0);
+						needs_trunc = 0;
+					}
 					ocfs_sleep (20);
 					ocfs_down_sem (oin_sem, true);
 				}
@@ -844,6 +855,10 @@
 					ocfs_release_lockres (lockres);
 					lockres = NULL;
 					oin_sem = NULL;
+					if (needs_trunc) {
+						ocfs_truncate_inode_pages(inode, 0);
+						needs_trunc = 0;
+					}
 				}
 			}
 			if (inode && (flags & FLAG_ACQUIRE_LOCK)) {
@@ -893,6 +908,11 @@
 			if (oin_sem)
 				ocfs_up_sem (oin_sem);
 
+			if (needs_trunc) {
+				ocfs_truncate_inode_pages(inode, 0);
+				needs_trunc = 0;
+			}
+
 			break;
 
 		case RELEASE_CACHE:

Modified: trunk/src/oin.c
===================================================================
--- trunk/src/oin.c	2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/oin.c	2004-02-06 02:50:01 UTC (rev 27)
@@ -11,7 +11,7 @@
  * filename. We currently cache all the oin's. We should hash this list.
  *
  */ 
-int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin)
+int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin, int *needs_trunc)
 {
 	int status = 0;
 	struct buffer_head *fe_bh = NULL;
@@ -27,6 +27,8 @@
 
 	OCFS_ASSERT (oin);
 
+	*needs_trunc = 0;
+
 	status = ocfs_read_bh(osb, oin->file_disk_off, &fe_bh, OCFS_BH_COND_CACHED, oin->inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
@@ -102,8 +104,11 @@
 			OCFS_SET_INODE_TIME(inode, i_ctime, fe->create_time);
 			OCFS_SET_INODE_TIME(inode, i_atime, fe->modify_time);
 			OCFS_SET_INODE_TIME(inode, i_mtime, fe->modify_time);
-			if (!S_ISDIR (inode->i_mode)) {
-				ocfs_truncate_inode_pages(inode, 0);
+			if (!S_ISDIR (inode->i_mode) &&
+			    (oin->alloc_size != (__s64) fe->alloc_size ||
+			     inode->i_size != (__s64) fe->file_size ||
+			     oin->chng_seq_num != DISK_LOCK_SEQNUM (fe))) {
+				*needs_trunc = 1;
 			}
 
 			switch (fe->attribs) {



More information about the Ocfs2-commits mailing list