aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.com>2010-04-23 14:42:22 -0400
committerMark Fasheh <mfasheh@suse.com>2010-04-23 14:42:22 -0400
commita9743fcdc0eb43d028b71267438076e1b0112ba0 (patch)
treec893396ac248e5f570a774b5b375d94b2858ae34
parent062d340384dcf77dfd8de0a082b5da571de3925a (diff)
ocfs2: Add directory entry later in ocfs2_symlink() and ocfs2_mknod()
If we get a failure during creation of an inode we'll allow the orphan code to remove the inode, which is correct. However, we need to ensure that we don't get any errors after the call to ocfs2_add_entry(), otherwise we could leave a dangling directory reference. The solution is simple - in both cases, all I had to do was move ocfs2_dentry_attach_lock() above the ocfs2_add_entry() call. Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/ocfs2/namei.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 8ff035eabfd8..4cbb18f26c5f 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -408,23 +408,28 @@ static int ocfs2_mknod(struct inode *dir,
408 } 408 }
409 } 409 }
410 410
411 status = ocfs2_add_entry(handle, dentry, inode, 411 /*
412 OCFS2_I(inode)->ip_blkno, parent_fe_bh, 412 * Do this before adding the entry to the directory. We add
413 &lookup); 413 * also set d_op after success so that ->d_iput() will cleanup
414 if (status < 0) { 414 * the dentry lock even if ocfs2_add_entry() fails below.
415 */
416 status = ocfs2_dentry_attach_lock(dentry, inode,
417 OCFS2_I(dir)->ip_blkno);
418 if (status) {
415 mlog_errno(status); 419 mlog_errno(status);
416 goto leave; 420 goto leave;
417 } 421 }
422 dentry->d_op = &ocfs2_dentry_ops;
418 423
419 status = ocfs2_dentry_attach_lock(dentry, inode, 424 status = ocfs2_add_entry(handle, dentry, inode,
420 OCFS2_I(dir)->ip_blkno); 425 OCFS2_I(inode)->ip_blkno, parent_fe_bh,
421 if (status) { 426 &lookup);
427 if (status < 0) {
422 mlog_errno(status); 428 mlog_errno(status);
423 goto leave; 429 goto leave;
424 } 430 }
425 431
426 insert_inode_hash(inode); 432 insert_inode_hash(inode);
427 dentry->d_op = &ocfs2_dentry_ops;
428 d_instantiate(dentry, inode); 433 d_instantiate(dentry, inode);
429 status = 0; 434 status = 0;
430leave: 435leave:
@@ -1777,22 +1782,27 @@ static int ocfs2_symlink(struct inode *dir,
1777 } 1782 }
1778 } 1783 }
1779 1784
1780 status = ocfs2_add_entry(handle, dentry, inode, 1785 /*
1781 le64_to_cpu(fe->i_blkno), parent_fe_bh, 1786 * Do this before adding the entry to the directory. We add
1782 &lookup); 1787 * also set d_op after success so that ->d_iput() will cleanup
1783 if (status < 0) { 1788 * the dentry lock even if ocfs2_add_entry() fails below.
1789 */
1790 status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
1791 if (status) {
1784 mlog_errno(status); 1792 mlog_errno(status);
1785 goto bail; 1793 goto bail;
1786 } 1794 }
1795 dentry->d_op = &ocfs2_dentry_ops;
1787 1796
1788 status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); 1797 status = ocfs2_add_entry(handle, dentry, inode,
1789 if (status) { 1798 le64_to_cpu(fe->i_blkno), parent_fe_bh,
1799 &lookup);
1800 if (status < 0) {
1790 mlog_errno(status); 1801 mlog_errno(status);
1791 goto bail; 1802 goto bail;
1792 } 1803 }
1793 1804
1794 insert_inode_hash(inode); 1805 insert_inode_hash(inode);
1795 dentry->d_op = &ocfs2_dentry_ops;
1796 d_instantiate(dentry, inode); 1806 d_instantiate(dentry, inode);
1797bail: 1807bail:
1798 if (status < 0 && did_quota) 1808 if (status < 0 && did_quota)