[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