[Ocfs2-commits] mfasheh commits r1151 - trunk/src

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Fri Jun 18 15:47:12 CDT 2004


Author: mfasheh
Date: 2004-06-18 14:47:10 -0500 (Fri, 18 Jun 2004)
New Revision: 1151

Modified:
   trunk/src/namei.c
Log:
* find the missing link(2)



Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c	2004-06-18 17:54:51 UTC (rev 1150)
+++ trunk/src/namei.c	2004-06-18 19:47:10 UTC (rev 1151)
@@ -515,16 +515,139 @@
  * ocfs_link()
  *
  */
-int ocfs_link (struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
+int ocfs_link (struct dentry * old_dentry,
+	       struct inode * dir, struct dentry *dentry)
 {
-	int status = -EPERM;
+	ocfs_journal_handle *handle = NULL;
+	struct inode *inode = old_dentry->d_inode;
+	int err;
+	int tmpstat;
+	struct buffer_head *fe_bh = NULL;
+	struct buffer_head *parent_fe_bh = NULL;
+	ocfs2_dinode *fe = NULL;
+	int cleanup_parent = 0;
+	int cleanup_fe = 0;
+	ocfs_super *osb = OCFS_SB(dir->i_sb);
+	u64 fe_blkno;
 
-	LOG_ENTRY_ARGS ("(0x%p, 0x%p, 0x%p, old='%*s' new='%*s')\n", old_dentry, dir, dentry,
-			old_dentry->d_name.len, old_dentry->d_name.name,
-			dentry->d_name.len, dentry->d_name.name);
+	LOG_ENTRY_ARGS ("(inode=%lu, old='%*s' new='%*s')\n", 
+			inode->i_ino, old_dentry->d_name.len, 
+			old_dentry->d_name.name, dentry->d_name.len, 
+			dentry->d_name.name);
 
-	LOG_EXIT_INT (status);
-	return status;
+	if (S_ISDIR(inode->i_mode)) {
+		err = -EPERM;
+		goto bail;
+	}
+
+	if (inode->i_nlink >= OCFS2_LINK_MAX) {
+		err = -EMLINK;
+		goto bail;
+	}
+
+	/* mknod credits is a bit heavy, but we can tune this later. */
+	handle = ocfs_start_trans(osb, OCFS_MKNOD_CREDITS);
+	if (handle == NULL) {
+		err = -ENOMEM;
+		goto bail;
+	}
+
+	down_write(&OCFS_I(dir)->ip_io_sem);
+
+	/* lock the parent directory */
+	err = ocfs_acquire_lock (osb, OCFS_DLM_ENABLE_CACHE_LOCK,
+				    FLAG_FILE_CREATE | FLAG_DIR, 
+				    &parent_fe_bh, dir);
+	if (err < 0) {
+		up_write(&OCFS_I(dir)->ip_io_sem);
+		if (err != -EINTR)
+			LOG_ERROR_STATUS (err);
+		goto bail;
+	}
+	cleanup_parent = 1;
+
+	down_write(&OCFS_I(inode)->ip_io_sem);
+
+	err = ocfs_acquire_lock (osb, OCFS_DLM_ENABLE_CACHE_LOCK,
+				    FLAG_FILE_CREATE, 
+				    &fe_bh, inode);
+	if (err < 0) {
+		up_write(&OCFS_I(inode)->ip_io_sem);
+		if (err != -EINTR)
+			LOG_ERROR_STATUS (err);
+		goto bail;
+	}
+	cleanup_fe = 1;
+
+	err = ocfs_journal_access(handle, fe_bh, OCFS_JOURNAL_ACCESS_WRITE);
+	if (err < 0) {
+		LOG_ERROR_STATUS(err);
+		goto bail;
+	}
+
+	fe = (ocfs2_dinode *) fe_bh->b_data;
+
+	if (fe->i_links_count >= OCFS2_LINK_MAX) {
+		err = -EMLINK;
+		goto bail;
+	}
+
+	fe->i_links_count++;
+	inode->i_nlink = fe->i_links_count;
+	inode->i_ctime = CURRENT_TIME;
+
+	err = ocfs_journal_dirty(handle, fe_bh);
+	if (err < 0) {
+		inode->i_nlink--;
+		LOG_ERROR_STATUS(err);
+		goto bail;
+	}
+
+	fe_blkno = GET_INODE_FEOFF(inode) >> osb->sb->s_blocksize_bits;
+	err = ocfs_add_entry(handle, dentry, inode, fe_blkno, parent_fe_bh);
+	if (err) {
+		inode->i_nlink--;
+		LOG_ERROR_STATUS(err);
+		goto bail;
+	}
+
+	atomic_inc(&inode->i_count);
+	d_instantiate(dentry, inode);
+bail:
+	if (handle && (err < 0))
+		ocfs_abort_trans(handle);
+	else if (handle)
+		ocfs_commit_trans(handle);
+
+	if (cleanup_parent) {
+		tmpstat = ocfs_release_lock (osb, OCFS_DLM_ENABLE_CACHE_LOCK,
+					     FLAG_FILE_CREATE | FLAG_DIR, 
+					     parent_fe_bh, dir);
+		if (tmpstat < 0)
+			LOG_ERROR_STATUS (tmpstat);
+		up_write(&OCFS_I(dir)->ip_io_sem);
+
+	}
+
+	if (cleanup_fe) {
+		tmpstat = ocfs_release_lock(osb, OCFS_DLM_ENABLE_CACHE_LOCK,
+					    FLAG_FILE_CREATE 
+					    | FLAG_FILE_UPDATE_OIN, 
+					    fe_bh, 
+					    inode);
+		if (tmpstat < 0)
+			LOG_ERROR_STATUS (tmpstat);
+		up_write(&OCFS_I(inode)->ip_io_sem);
+
+	}
+
+	if (fe_bh)
+		brelse(fe_bh);
+	if (parent_fe_bh)
+		brelse(parent_fe_bh);
+
+	LOG_EXIT_STATUS(err);
+	return err;
 }				/* ocfs_link */
 
 /*
@@ -1864,107 +1987,3 @@
 
 	return status;
 }
-
-#if 0
-static int ocfs_link (struct dentry * old_dentry,
-		struct inode * dir, struct dentry *dentry)
-{
-	ocfs_journal_handle *handle = NULL;
-	struct inode *inode = old_dentry->d_inode;
-	int err;
-	__u64 parent_off=0ULL, fe_off=0ULL;
-	int tmpstat;
-	struct buffer_head *bh = NULL;
-	struct buffer_head *parent_fe_bh = NULL;
-	ocfs2_dinode *fe = NULL;
-
-	if (S_ISDIR(inode->i_mode))
-		return -EPERM;
-
-	if (inode->i_nlink >= OCFS2_LINK_MAX)
-		return -EMLINK;
-
-#define OCFS_DATA_TRANS_BLOCKS          (3 * 8 - 2)
-	handle = ocfs_start_trans(osb, OCFS_DATA_TRANS_BLOCKS);
-	if (handle == NULL) {
-		return -ENOMEM;
-	}
-	
-	/* lock the parent directory */
-	parent_off = GET_INODE_FEOFF(dir);
-	err = ocfs_acquire_lock (osb, OCFS_DLM_ENABLE_CACHE_LOCK,
-				    FLAG_FILE_CREATE | FLAG_DIR, 
-				    &parent_fe_bh, dir);
-	if (err < 0) {
-		parent_off = 0ULL;
-		if (err != -EINTR)
-			LOG_ERROR_STATUS (err);
-		goto bail;
-	}
-
-	/* lock the file entry */
-	fe_off = GET_INODE_FEOFF(inode);
-	err = ocfs_acquire_lock (osb, OCFS_DLM_ENABLE_CACHE_LOCK,
-				    FLAG_FILE_CREATE, 
-				    &bh, inode);
-	if (err < 0) {
-		fe_off = 0ULL;
-		if (err != -EINTR)
-			LOG_ERROR_STATUS (err);
-		goto bail;
-	}
-
-	err = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
-	if (err < 0)
-		goto bail;
-
-	fe = (ocfs2_dinode *) bh->b_data;
-	fe->i_links_count++;
-	inode->i_nlink = fe->i_links_count;
-	inode->i_ctime = CURRENT_TIME;
-	atomic_inc(&inode->i_count);
-
-	err = ocfs_journal_dirty(handle, bh);
-	if (err < 0) {
-		inode->i_nlink--;
-		goto bail;
-	}
-
-	err = ocfs_add_entry(handle, dentry, inode, parent_fe_bh);
-	if (err)
-		inode->i_nlink--;
-	else 	
-		d_instantiate(dentry, inode);
-bail:
-	if (err < 0)
-		ocfs_abort_trans(handle);
-	else
-		ocfs_commit_trans(handle);
-
-	if (parent_off) {
-		tmpstat = ocfs_release_lock (osb, OCFS_DLM_ENABLE_CACHE_LOCK,
-					     FLAG_FILE_CREATE | FLAG_DIR, 
-					     parent_fe_bh, dir);
-		if (tmpstat < 0)
-			LOG_ERROR_STATUS (tmpstat);
-	}
-	if (fe_off) {
-		tmpstat = ocfs_release_lock (osb, OCFS_DLM_ENABLE_CACHE_LOCK,
-					     FLAG_FILE_CREATE, 
-					     bh, inode);
-		if (tmpstat < 0)
-			LOG_ERROR_STATUS (tmpstat);
-	}
-
-	if (bh)
-		brelse(bh);
-	if (parent_fe_bh)
-		brelse(parent_fe_bh);
-
-	// is this right?!
-	if (err)
-		iput(inode);
-
-	return err;
-}
-#endif



More information about the Ocfs2-commits mailing list