[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