Skip to content

Commit

Permalink
ocfs2: Add directory entry later in ocfs2_symlink() and ocfs2_mknod()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Fasheh committed Apr 23, 2010
1 parent 062d340 commit a9743fc
Showing 1 changed file with 25 additions and 15 deletions.
40 changes: 25 additions & 15 deletions fs/ocfs2/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,23 +408,28 @@ static int ocfs2_mknod(struct inode *dir,
}
}

status = ocfs2_add_entry(handle, dentry, inode,
OCFS2_I(inode)->ip_blkno, parent_fe_bh,
&lookup);
if (status < 0) {
/*
* Do this before adding the entry to the directory. We add
* also set d_op after success so that ->d_iput() will cleanup
* the dentry lock even if ocfs2_add_entry() fails below.
*/
status = ocfs2_dentry_attach_lock(dentry, inode,
OCFS2_I(dir)->ip_blkno);
if (status) {
mlog_errno(status);
goto leave;
}
dentry->d_op = &ocfs2_dentry_ops;

status = ocfs2_dentry_attach_lock(dentry, inode,
OCFS2_I(dir)->ip_blkno);
if (status) {
status = ocfs2_add_entry(handle, dentry, inode,
OCFS2_I(inode)->ip_blkno, parent_fe_bh,
&lookup);
if (status < 0) {
mlog_errno(status);
goto leave;
}

insert_inode_hash(inode);
dentry->d_op = &ocfs2_dentry_ops;
d_instantiate(dentry, inode);
status = 0;
leave:
Expand Down Expand Up @@ -1777,22 +1782,27 @@ static int ocfs2_symlink(struct inode *dir,
}
}

status = ocfs2_add_entry(handle, dentry, inode,
le64_to_cpu(fe->i_blkno), parent_fe_bh,
&lookup);
if (status < 0) {
/*
* Do this before adding the entry to the directory. We add
* also set d_op after success so that ->d_iput() will cleanup
* the dentry lock even if ocfs2_add_entry() fails below.
*/
status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
if (status) {
mlog_errno(status);
goto bail;
}
dentry->d_op = &ocfs2_dentry_ops;

status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
if (status) {
status = ocfs2_add_entry(handle, dentry, inode,
le64_to_cpu(fe->i_blkno), parent_fe_bh,
&lookup);
if (status < 0) {
mlog_errno(status);
goto bail;
}

insert_inode_hash(inode);
dentry->d_op = &ocfs2_dentry_ops;
d_instantiate(dentry, inode);
bail:
if (status < 0 && did_quota)
Expand Down

0 comments on commit a9743fc

Please sign in to comment.