Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bcopeland/omfs

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bcopeland/omfs:
  omfs: make readdir stop when filldir says so
  omfs: merge unlink() and rmdir(), close leak in rename()
  omfs: stop playing silly buggers with omfs_unlink() in ->rename()
  omfs: rename() needs to mark old_inode dirty after ctime update
This commit is contained in:
Linus Torvalds 2011-03-18 10:50:52 -07:00
commit 3f6f7e6d57

View File

@ -235,33 +235,22 @@ static int omfs_dir_is_empty(struct inode *inode)
return *ptr != ~0; return *ptr != ~0;
} }
static int omfs_unlink(struct inode *dir, struct dentry *dentry) static int omfs_remove(struct inode *dir, struct dentry *dentry)
{ {
int ret;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
int ret;
if (S_ISDIR(inode->i_mode) && !omfs_dir_is_empty(inode))
return -ENOTEMPTY;
ret = omfs_delete_entry(dentry); ret = omfs_delete_entry(dentry);
if (ret) if (ret)
goto end_unlink; return ret;
inode_dec_link_count(inode); clear_nlink(inode);
mark_inode_dirty(inode);
mark_inode_dirty(dir); mark_inode_dirty(dir);
return 0;
end_unlink:
return ret;
}
static int omfs_rmdir(struct inode *dir, struct dentry *dentry)
{
int err = -ENOTEMPTY;
struct inode *inode = dentry->d_inode;
if (omfs_dir_is_empty(inode)) {
err = omfs_unlink(dir, dentry);
if (!err)
inode_dec_link_count(inode);
}
return err;
} }
static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode) static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode)
@ -372,9 +361,10 @@ static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir,
res = filldir(dirent, oi->i_name, strnlen(oi->i_name, res = filldir(dirent, oi->i_name, strnlen(oi->i_name,
OMFS_NAMELEN), filp->f_pos, self, d_type); OMFS_NAMELEN), filp->f_pos, self, d_type);
if (res == 0)
filp->f_pos++;
brelse(bh); brelse(bh);
if (res < 0)
break;
filp->f_pos++;
} }
out: out:
return res; return res;
@ -385,44 +375,28 @@ static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry,
{ {
struct inode *new_inode = new_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode;
struct inode *old_inode = old_dentry->d_inode; struct inode *old_inode = old_dentry->d_inode;
struct buffer_head *bh;
int is_dir;
int err; int err;
is_dir = S_ISDIR(old_inode->i_mode);
if (new_inode) { if (new_inode) {
/* overwriting existing file/dir */ /* overwriting existing file/dir */
err = -ENOTEMPTY; err = omfs_remove(new_dir, new_dentry);
if (is_dir && !omfs_dir_is_empty(new_inode))
goto out;
err = -ENOENT;
bh = omfs_find_entry(new_dir, new_dentry->d_name.name,
new_dentry->d_name.len);
if (IS_ERR(bh))
goto out;
brelse(bh);
err = omfs_unlink(new_dir, new_dentry);
if (err) if (err)
goto out; goto out;
} }
/* since omfs locates files by name, we need to unlink _before_ /* since omfs locates files by name, we need to unlink _before_
* adding the new link or we won't find the old one */ * adding the new link or we won't find the old one */
inode_inc_link_count(old_inode); err = omfs_delete_entry(old_dentry);
err = omfs_unlink(old_dir, old_dentry); if (err)
if (err) {
inode_dec_link_count(old_inode);
goto out; goto out;
}
mark_inode_dirty(old_dir);
err = omfs_add_link(new_dentry, old_inode); err = omfs_add_link(new_dentry, old_inode);
if (err) if (err)
goto out; goto out;
old_inode->i_ctime = CURRENT_TIME_SEC; old_inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(old_inode);
out: out:
return err; return err;
} }
@ -488,8 +462,8 @@ const struct inode_operations omfs_dir_inops = {
.mkdir = omfs_mkdir, .mkdir = omfs_mkdir,
.rename = omfs_rename, .rename = omfs_rename,
.create = omfs_create, .create = omfs_create,
.unlink = omfs_unlink, .unlink = omfs_remove,
.rmdir = omfs_rmdir, .rmdir = omfs_remove,
}; };
const struct file_operations omfs_dir_operations = { const struct file_operations omfs_dir_operations = {