diff options
author | Christoph Hellwig <hch@tuxera.com> | 2010-10-01 05:43:54 +0200 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2010-10-01 05:43:54 +0200 |
commit | f17c89bfcc9cccd405098eac3ec1ebfddf03279e (patch) | |
tree | f8c33976eb35e7ee62f59fbe200a92f447d42fbd | |
parent | 30d3abbec730a5a9c954a6342271f7a7db155b08 (diff) | |
download | linux-f17c89bfcc9cccd405098eac3ec1ebfddf03279e.tar.gz linux-f17c89bfcc9cccd405098eac3ec1ebfddf03279e.tar.bz2 linux-f17c89bfcc9cccd405098eac3ec1ebfddf03279e.zip |
hfsplus: fix error handling in hfsplus_symlink
We need to free the inode again on a hfsplus_create_cat failure.
Signed-off-by: Christoph Hellwig <hch@tuxera.com>
-rw-r--r-- | fs/hfsplus/dir.c | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 7efcf75ea73a..f8ae468f4ab6 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -364,31 +364,29 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry) static int hfsplus_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { - struct super_block *sb; struct inode *inode; int res; - sb = dir->i_sb; - inode = hfsplus_new_inode(sb, S_IFLNK | S_IRWXUGO); + inode = hfsplus_new_inode(dir->i_sb, S_IFLNK | S_IRWXUGO); if (!inode) return -ENOSPC; res = page_symlink(inode, symname, strlen(symname) + 1); - if (res) { - inode->i_nlink = 0; - hfsplus_delete_inode(inode); - iput(inode); - return res; - } + if (res) + goto out_err; - mark_inode_dirty(inode); res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); + if (res) + goto out_err; - if (!res) { - hfsplus_instantiate(dentry, inode, inode->i_ino); - mark_inode_dirty(inode); - } + hfsplus_instantiate(dentry, inode, inode->i_ino); + mark_inode_dirty(inode); + return 0; +out_err: + inode->i_nlink = 0; + hfsplus_delete_inode(inode); + iput(inode); return res; } |