[Ocfs2-commits] mfasheh commits r2330 - trunk/fs/ocfs2

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu May 26 18:13:57 CDT 2005


Author: mfasheh
Signed-off-by: jlbec
Date: 2005-05-26 18:13:56 -0500 (Thu, 26 May 2005)
New Revision: 2330

Modified:
   trunk/fs/ocfs2/namei.c
   trunk/fs/ocfs2/vote.c
   trunk/fs/ocfs2/vote.h
Log:
* instead of decrementing nlink on unlink votes, we take a value passed from
  the node doing the unlink. This solves a problem we could see where voting
  rounds get restarted and nodes which vote multiple times might have
  incorrectly set i_nlink.

Signed-off-by: jlbec



Modified: trunk/fs/ocfs2/namei.c
===================================================================
--- trunk/fs/ocfs2/namei.c	2005-05-26 22:30:59 UTC (rev 2329)
+++ trunk/fs/ocfs2/namei.c	2005-05-26 23:13:56 UTC (rev 2330)
@@ -462,8 +462,6 @@
 
 	if (status == -ENOSPC)
 		mlog(0, "Disk is full\n");
-	else if (status < 0)
-		mlog_errno(status);
 
 	if (new_fe_bh) 
 		brelse(new_fe_bh);
@@ -756,6 +754,7 @@
 static int ocfs_unlink(struct inode *dir, struct dentry *dentry)
 {
 	int status;
+	unsigned int saved_nlink = 0;
 	struct inode *inode = dentry->d_inode;
 	ocfs_super *osb = OCFS2_SB(dir->i_sb);
 	u64 blkno;
@@ -804,8 +803,9 @@
 		goto leave;
 	}
 
-	if (blkno != OCFS2_I(inode)->ip_blkno)
-		BUG();
+	mlog_bug_on_msg(OCFS2_I(inode)->ip_blkno != blkno,
+			"ip_blkno (%"MLFu64") != dirent blkno (%"MLFu64")\n",
+			OCFS2_I(inode)->ip_blkno, blkno);
 
 	status = ocfs2_meta_lock(inode, handle, &fe_bh, 1);
 	if (status < 0) {
@@ -813,14 +813,6 @@
 		goto leave;
 	}
 
-	status = ocfs2_request_unlink_vote(inode);
-	if (status < 0) {
-		/* This vote should succeed under all normal
-		 * circumstances. */
-		mlog_errno(status);
-		goto leave;
-	}
-
 	if (S_ISDIR(inode->i_mode)) {
 	       	if (!ocfs_empty_dir(inode)) {
 			status = -ENOTEMPTY;
@@ -831,7 +823,26 @@
 		}
 	}
 
-	if (S_ISDIR(inode->i_mode) || (inode->i_nlink == 1)) {
+	/* There are still a few steps left until we can consider the
+	 * unlink to have succeeded. Save off nlink here before
+	 * modification so we can set it back in case we hit an issue
+	 * before commit. */
+	saved_nlink = inode->i_nlink;
+	if (S_ISDIR(inode->i_mode))
+		inode->i_nlink = 0;
+	else
+		inode->i_nlink--;
+
+	status = ocfs2_request_unlink_vote(inode,
+					   (unsigned int) inode->i_nlink);
+	if (status < 0) {
+		/* This vote should succeed under all normal
+		 * circumstances. */
+		mlog_errno(status);
+		goto leave;
+	}
+
+	if (!inode->i_nlink) {
 		status = ocfs_prepare_orphan_dir(osb, handle, inode, 
 						 orphan_name, 
 						 &orphan_entry_bh);
@@ -856,14 +867,8 @@
 	}
 
 	fe = (ocfs2_dinode *) fe_bh->b_data;
-	if (fe->i_links_count != inode->i_nlink) {
-		mlog(ML_NOTICE, "inode has nlink = %u, fe has link_cnt = %u. "
-		     "Setting inode from fe.\n", inode->i_nlink,
-		     fe->i_links_count);
-		inode->i_nlink = fe->i_links_count;
-	}
 
-	if (S_ISDIR(inode->i_mode) || (fe->i_links_count == 1)) {
+	if (!inode->i_nlink) {
 		status = ocfs_orphan_add(osb, handle, inode, fe, orphan_name,
 					 orphan_entry_bh);
 		if (status < 0) {
@@ -879,13 +884,10 @@
 		goto leave;
 	}
 
-	if (S_ISDIR(inode->i_mode)) {
-		fe->i_links_count = 0;
-		inode->i_nlink = 0;
-	} else {
-		fe->i_links_count--;
-		inode->i_nlink--;
-	}
+	/* We can set nlink on the dinode now. clear the saved version
+	 * so that it doesn't get set later. */
+	fe->i_links_count = inode->i_nlink;
+	saved_nlink = 0;
 
 	status = ocfs_journal_dirty(handle, fe_bh);
 	if (status < 0) {
@@ -904,6 +906,9 @@
 	}
 
 leave:
+	if (status < 0 && saved_nlink)
+		inode->i_nlink = saved_nlink;
+
 	if (handle)
 		ocfs_commit_trans(handle);
 
@@ -1015,6 +1020,7 @@
 	struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
 						    // this is the 1st dirent bh
 	nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink;
+	unsigned int links_count;
 
 	/* At some point it might be nice to break this function up a
 	 * bit. */
@@ -1145,11 +1151,12 @@
 	/* In case we need to overwrite an existing file, we blow it
 	 * away first */
 	if (new_de) {
-		if (!new_inode)
-			BUG();
+		BUG_ON(!new_inode);
 
-		if (newfe_blkno != OCFS2_I(new_inode)->ip_blkno)
-			BUG();
+		mlog_bug_on_msg(OCFS2_I(new_inode)->ip_blkno != newfe_blkno,
+				"Inode blkno (%"MLFu64") and dir (%"MLFu64") "
+				"disagree!\n", OCFS2_I(new_inode)->ip_blkno,
+				newfe_blkno);
 
 		status = ocfs2_meta_lock(new_inode, handle, &newfe_bh, 1);
 		if (status < 0) {
@@ -1157,7 +1164,12 @@
 			goto bail;
 		}
 
-		status = ocfs2_request_unlink_vote(new_inode);
+		if (S_ISDIR(new_inode->i_mode))
+			links_count = 0;
+		else
+			links_count = (unsigned int) (new_inode->i_nlink - 1);
+
+		status = ocfs2_request_unlink_vote(new_inode, links_count);
 		if (status < 0) {
 			mlog_errno(status);
 			goto bail;

Modified: trunk/fs/ocfs2/vote.c
===================================================================
--- trunk/fs/ocfs2/vote.c	2005-05-26 22:30:59 UTC (rev 2329)
+++ trunk/fs/ocfs2/vote.c	2005-05-26 23:13:56 UTC (rev 2330)
@@ -67,7 +67,11 @@
 typedef struct _ocfs2_vote_msg
 {
 	ocfs2_msg_hdr v_hdr;
-	s32 v_orphaned_slot;	/* Used during delete votes */
+	union {
+		u32 v_generic1;
+		s32 v_orphaned_slot;	/* Used during delete votes */
+		u32 v_nlink;		/* Used during unlink votes */
+	} md1;				/* Message type dependant 1 */
 } ocfs2_vote_msg;
 
 /* Responses are given these values to maintain backwards
@@ -239,25 +243,25 @@
 }
 
 static void ocfs2_process_dentry_request(struct inode *inode,
-					 int rename)
+					 int rename,
+					 unsigned int new_nlink)
 {
 	d_prune_aliases(inode);
 
-	/* for rename, we don't drop link counts */
+	/* for rename, we don't change link counts */
 	if (!rename) {
-		if (S_ISDIR(inode->i_mode))
-			inode->i_nlink = 0;
-		else
-			inode->i_nlink--;
+		mlog(0, "new_nlink = %u\n", new_nlink);
+		inode->i_nlink = new_nlink;
 	}
 }
 
 static void ocfs2_process_vote(ocfs_super *osb,
 			       ocfs2_vote_msg *msg)
 {
-	int net_status, vote_response, orphaned_slot;
+	int net_status, vote_response;
+	int orphaned_slot = 0;
 	int rename = 0;
-	unsigned int node_num, generation;
+	unsigned int node_num, generation, new_nlink;
 	u64 blkno;
 	enum ocfs2_vote_request request;
 	struct inode *inode = NULL;
@@ -269,11 +273,12 @@
 	blkno = be64_to_cpu(hdr->h_blkno);
 	generation = ntohl(hdr->h_generation);
 	node_num = ntohl(hdr->h_node_num);
-	orphaned_slot = ntohl(msg->v_orphaned_slot);
+	if (request == OCFS2_VOTE_REQ_DELETE)
+		orphaned_slot = ntohl(msg->md1.v_orphaned_slot);
 
 	mlog(0, "processing vote: request = %u, blkno = %"MLFu64", "
-	     "generation = %u, node_num = %u, orphaned_slot = %d\n", request,
-	     blkno, generation, node_num, orphaned_slot);
+	     "generation = %u, node_num = %u, priv1 = %u\n", request,
+	     blkno, generation, node_num, ntohl(msg->md1.v_generic1));
 
 	if (!ocfs2_is_valid_vote_request(request)) {
 		mlog(ML_ERROR, "Invalid vote request %d from node %u\n",
@@ -325,7 +330,9 @@
 		rename = 1;
 		/* fall through */
 	case OCFS2_VOTE_REQ_UNLINK:
-		ocfs2_process_dentry_request(inode, rename);
+		/* new_nlink will be ignored in case of a rename vote */
+		new_nlink = ntohl(msg->md1.v_nlink);
+		ocfs2_process_dentry_request(inode, rename, new_nlink);
 		break;
 	default:
 		mlog(ML_ERROR, "node %u, invalid request: %u\n",
@@ -621,7 +628,7 @@
 				 u64 blkno,
 				 unsigned int generation,
 				 enum ocfs2_vote_request type,
-				 int orphaned_slot,
+				 u32 priv,
 				 struct ocfs2_net_response_cb *callback)
 {
 	int status, response;
@@ -647,7 +654,7 @@
 	hdr->h_blkno = cpu_to_be64(blkno);
 	hdr->h_generation = htonl(generation);
 	hdr->h_node_num = htonl((unsigned int) osb->node_num);
-	request->v_orphaned_slot = htonl(orphaned_slot);
+	request->md1.v_generic1 = htonl(priv);
 
 	status = ocfs2_broadcast_vote(osb, request, response_id, &response,
 				      callback);
@@ -666,7 +673,7 @@
 
 static int ocfs2_request_vote(struct inode *inode,
 			      enum ocfs2_vote_request type,
-			      int orphaned_slot,
+			      u32 priv,
 			      struct ocfs2_net_response_cb *callback)
 {
 	int status;
@@ -693,7 +700,7 @@
 						       OCFS2_I(inode)->ip_blkno,
 						       inode->i_generation,
 						       type,
-						       orphaned_slot,
+						       priv,
 						       callback);
 
 		ocfs2_super_unlock(osb, 0);
@@ -754,11 +761,12 @@
 				  &delete_cb);
 }
 
-int ocfs2_request_unlink_vote(struct inode *inode)
+int ocfs2_request_unlink_vote(struct inode *inode,
+			      unsigned int nlink)
 {
 	return ocfs2_request_vote(inode,
 				  OCFS2_VOTE_REQ_UNLINK,
-				  OCFS2_INVALID_SLOT,
+				  nlink,
 				  NULL);
 }
 
@@ -766,7 +774,7 @@
 {
 	return ocfs2_request_vote(inode,
 				  OCFS2_VOTE_REQ_RENAME,
-				  OCFS2_INVALID_SLOT,
+				  0,
 				  NULL);
 }
 
@@ -785,7 +793,7 @@
 
 		status = ocfs2_do_request_vote(osb, 0ULL, 0,
 					       OCFS2_VOTE_REQ_MOUNT,
-					       OCFS2_INVALID_SLOT, NULL);
+					       0, NULL);
 	}
 	return status;
 }
@@ -805,7 +813,7 @@
 
 		status = ocfs2_do_request_vote(osb, 0ULL, 0,
 					       OCFS2_VOTE_REQ_UMOUNT,
-					       OCFS2_INVALID_SLOT, NULL);
+					       0, NULL);
 	}
 	return status;
 }
@@ -928,7 +936,7 @@
 	     be64_to_cpu(work->w_msg.v_hdr.h_blkno));
 	mlog(0, "h_generation = %u\n", ntohl(work->w_msg.v_hdr.h_generation));
 	mlog(0, "h_node_num = %u\n", ntohl(work->w_msg.v_hdr.h_node_num));
-	mlog(0, "v_orphaned_slot = %d\n", ntohl(work->w_msg.v_orphaned_slot));
+	mlog(0, "v_generic1 = %u\n", ntohl(work->w_msg.md1.v_generic1));
 
 	spin_lock(&osb->vote_task_lock);
 	list_add_tail(&work->w_list, &osb->vote_list);

Modified: trunk/fs/ocfs2/vote.h
===================================================================
--- trunk/fs/ocfs2/vote.h	2005-05-26 22:30:59 UTC (rev 2329)
+++ trunk/fs/ocfs2/vote.h	2005-05-26 23:13:56 UTC (rev 2330)
@@ -39,7 +39,8 @@
 }
 
 int ocfs2_request_delete_vote(struct inode *inode);
-int ocfs2_request_unlink_vote(struct inode *inode);
+int ocfs2_request_unlink_vote(struct inode *inode,
+			      unsigned int nlink);
 int ocfs2_request_rename_vote(struct inode *inode);
 int ocfs2_request_mount_vote(ocfs_super *osb);
 int ocfs2_request_umount_vote(ocfs_super *osb);



More information about the Ocfs2-commits mailing list