diff options
Diffstat (limited to 'fs/ext3/namei.c')
-rw-r--r-- | fs/ext3/namei.c | 31 |
1 files changed, 11 insertions, 20 deletions
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 4df39c4315e1..49159f13cc1f 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1618,21 +1618,6 @@ static int ext3_delete_entry (handle_t *handle, return -ENOENT; } -/* - * ext3_mark_inode_dirty is somewhat expensive, so unlike ext2 we - * do not perform it in these functions. We perform it at the call site, - * if it is needed. - */ -static inline void ext3_inc_count(handle_t *handle, struct inode *inode) -{ - inc_nlink(inode); -} - -static inline void ext3_dec_count(handle_t *handle, struct inode *inode) -{ - drop_nlink(inode); -} - static int ext3_add_nondir(handle_t *handle, struct dentry *dentry, struct inode *inode) { @@ -1642,7 +1627,7 @@ static int ext3_add_nondir(handle_t *handle, d_instantiate(dentry, inode); return 0; } - ext3_dec_count(handle, inode); + drop_nlink(inode); iput(inode); return err; } @@ -2163,7 +2148,7 @@ retry: err = __page_symlink(inode, symname, l, mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); if (err) { - ext3_dec_count(handle, inode); + drop_nlink(inode); ext3_mark_inode_dirty(handle, inode); iput (inode); goto out_stop; @@ -2191,6 +2176,12 @@ static int ext3_link (struct dentry * old_dentry, if (inode->i_nlink >= EXT3_LINK_MAX) return -EMLINK; + /* + * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing + * otherwise has the potential to corrupt the orphan inode list. + */ + if (inode->i_nlink == 0) + return -ENOENT; retry: handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + @@ -2202,7 +2193,7 @@ retry: handle->h_sync = 1; inode->i_ctime = CURRENT_TIME_SEC; - ext3_inc_count(handle, inode); + inc_nlink(inode); atomic_inc(&inode->i_count); err = ext3_add_nondir(handle, dentry, inode); @@ -2374,7 +2365,7 @@ end_rename: /* * directories can handle most operations... */ -struct inode_operations ext3_dir_inode_operations = { +const struct inode_operations ext3_dir_inode_operations = { .create = ext3_create, .lookup = ext3_lookup, .link = ext3_link, @@ -2394,7 +2385,7 @@ struct inode_operations ext3_dir_inode_operations = { .permission = ext3_permission, }; -struct inode_operations ext3_special_inode_operations = { +const struct inode_operations ext3_special_inode_operations = { .setattr = ext3_setattr, #ifdef CONFIG_EXT3_FS_XATTR .setxattr = generic_setxattr, |