Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/viro/vfs-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (25 commits)
  cifs: remove unnecessary dentry_unhash on rmdir/rename_dir
  ocfs2: remove unnecessary dentry_unhash on rmdir/rename_dir
  exofs: remove unnecessary dentry_unhash on rmdir/rename_dir
  nfs: remove unnecessary dentry_unhash on rmdir/rename_dir
  ext2: remove unnecessary dentry_unhash on rmdir/rename_dir
  ext3: remove unnecessary dentry_unhash on rmdir/rename_dir
  ext4: remove unnecessary dentry_unhash on rmdir/rename_dir
  btrfs: remove unnecessary dentry_unhash in rmdir/rename_dir
  ceph: remove unnecessary dentry_unhash calls
  vfs: clean up vfs_rename_other
  vfs: clean up vfs_rename_dir
  vfs: clean up vfs_rmdir
  vfs: fix vfs_rename_dir for FS_RENAME_DOES_D_MOVE filesystems
  libfs: drop unneeded dentry_unhash
  vfs: update dentry_unhash() comment
  vfs: push dentry_unhash on rename_dir into file systems
  vfs: push dentry_unhash on rmdir into file systems
  vfs: remove dget() from dentry_unhash()
  vfs: dentry_unhash immediately prior to rmdir
  vfs: Block mmapped writes while the fs is frozen
  ...
  • Loading branch information
torvalds committed May 26, 2011
2 parents ca16d14 + b6ff24a commit 32e51f1
Show file tree
Hide file tree
Showing 33 changed files with 332 additions and 269 deletions.
4 changes: 4 additions & 0 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d)

int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
{
dentry_unhash(d);
return v9fs_remove(i, d, 1);
}

Expand All @@ -839,6 +840,9 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct p9_fid *newdirfid;
struct p9_wstat wstat;

if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
dentry_unhash(new_dentry);

P9_DPRINTK(P9_DEBUG_VFS, "\n");
retval = 0;
old_inode = old_dentry->d_inode;
Expand Down
2 changes: 1 addition & 1 deletion fs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ config FS_POSIX_ACL
def_bool n

config EXPORTFS
bool
tristate

config FILE_LOCKING
bool "Enable POSIX file locking API" if EXPERT
Expand Down
5 changes: 5 additions & 0 deletions fs/affs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ affs_rmdir(struct inode *dir, struct dentry *dentry)
dentry->d_inode->i_ino,
(int)dentry->d_name.len, dentry->d_name.name);

dentry_unhash(dentry);

return affs_remove_header(dentry);
}

Expand Down Expand Up @@ -417,6 +419,9 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct buffer_head *bh = NULL;
int retval;

if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
dentry_unhash(new_dentry);

pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n",
(u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name,
(u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name);
Expand Down
5 changes: 5 additions & 0 deletions fs/afs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,8 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
_enter("{%x:%u},{%s}",
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);

dentry_unhash(dentry);

ret = -ENAMETOOLONG;
if (dentry->d_name.len >= AFSNAMEMAX)
goto error;
Expand Down Expand Up @@ -1146,6 +1148,9 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct key *key;
int ret;

if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
dentry_unhash(new_dentry);

vnode = AFS_FS_I(old_dentry->d_inode);
orig_dvnode = AFS_FS_I(old_dir);
new_dvnode = AFS_FS_I(new_dir);
Expand Down
2 changes: 2 additions & 0 deletions fs/autofs4/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
return -EACCES;

dentry_unhash(dentry);

if (atomic_dec_and_test(&ino->count)) {
p_ino = autofs4_dentry_ino(dentry->d_parent);
if (p_ino && dentry->d_parent != dentry)
Expand Down
3 changes: 3 additions & 0 deletions fs/bfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct bfs_sb_info *info;
int error = -ENOENT;

if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
dentry_unhash(new_dentry);

old_bh = new_bh = NULL;
old_inode = old_dentry->d_inode;
if (S_ISDIR(old_inode->i_mode))
Expand Down
59 changes: 42 additions & 17 deletions fs/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2331,24 +2331,26 @@ EXPORT_SYMBOL(block_commit_write);
* page lock we can determine safely if the page is beyond EOF. If it is not
* beyond EOF, then the page is guaranteed safe against truncation until we
* unlock the page.
*
* Direct callers of this function should call vfs_check_frozen() so that page
* fault does not busyloop until the fs is thawed.
*/
int
block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
get_block_t get_block)
int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
get_block_t get_block)
{
struct page *page = vmf->page;
struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
unsigned long end;
loff_t size;
int ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */
int ret;

lock_page(page);
size = i_size_read(inode);
if ((page->mapping != inode->i_mapping) ||
(page_offset(page) > size)) {
/* page got truncated out from underneath us */
unlock_page(page);
goto out;
/* We overload EFAULT to mean page got truncated */
ret = -EFAULT;
goto out_unlock;
}

/* page is wholly or partially inside EOF */
Expand All @@ -2361,18 +2363,41 @@ block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
if (!ret)
ret = block_commit_write(page, 0, end);

if (unlikely(ret)) {
unlock_page(page);
if (ret == -ENOMEM)
ret = VM_FAULT_OOM;
else /* -ENOSPC, -EIO, etc */
ret = VM_FAULT_SIGBUS;
} else
ret = VM_FAULT_LOCKED;

out:
if (unlikely(ret < 0))
goto out_unlock;
/*
* Freezing in progress? We check after the page is marked dirty and
* with page lock held so if the test here fails, we are sure freezing
* code will wait during syncing until the page fault is done - at that
* point page will be dirty and unlocked so freezing code will write it
* and writeprotect it again.
*/
set_page_dirty(page);
if (inode->i_sb->s_frozen != SB_UNFROZEN) {
ret = -EAGAIN;
goto out_unlock;
}
return 0;
out_unlock:
unlock_page(page);
return ret;
}
EXPORT_SYMBOL(__block_page_mkwrite);

int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
get_block_t get_block)
{
int ret;
struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb;

/*
* This check is racy but catches the common case. The check in
* __block_page_mkwrite() is reliable.
*/
vfs_check_frozen(sb, SB_FREEZE_WRITE);
ret = __block_page_mkwrite(vma, vmf, get_block);
return block_page_mkwrite_return(ret);
}
EXPORT_SYMBOL(block_page_mkwrite);

/*
Expand Down
5 changes: 5 additions & 0 deletions fs/coda/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
int len = de->d_name.len;
int error;

dentry_unhash(de);

error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
if (!error) {
/* VFS may delete the child */
Expand All @@ -359,6 +361,9 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
int new_length = new_dentry->d_name.len;
int error;

if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
dentry_unhash(new_dentry);

error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
coda_i2f(new_dir), old_length, new_length,
(const char *) old_name, (const char *)new_name);
Expand Down
2 changes: 2 additions & 0 deletions fs/configfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1359,6 +1359,8 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
struct module *subsys_owner = NULL, *dead_item_owner = NULL;
int ret;

dentry_unhash(dentry);

if (dentry->d_parent == configfs_sb->s_root)
return -EPERM;

Expand Down
5 changes: 5 additions & 0 deletions fs/ecryptfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,8 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
struct dentry *lower_dir_dentry;
int rc;

dentry_unhash(dentry);

lower_dentry = ecryptfs_dentry_to_lower(dentry);
dget(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
Expand Down Expand Up @@ -571,6 +573,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct dentry *lower_new_dir_dentry;
struct dentry *trap = NULL;

if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
dentry_unhash(new_dentry);

lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
dget(lower_old_dentry);
Expand Down
5 changes: 5 additions & 0 deletions fs/fat/namei_msdos.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;

dentry_unhash(dentry);

lock_super(sb);
/*
* Check whether the directory is not in use, then check
Expand Down Expand Up @@ -457,6 +459,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode;

if (new_inode && S_ISDIR(new_inode->i_mode))
dentry_unhash(new_dentry);

err = fat_scan(old_dir, old_name, &old_sinfo);
if (err) {
err = -EIO;
Expand Down
5 changes: 5 additions & 0 deletions fs/fat/namei_vfat.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,8 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;

dentry_unhash(dentry);

lock_super(sb);

err = fat_dir_empty(inode);
Expand Down Expand Up @@ -931,6 +933,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
int err, is_dir, update_dotdot, corrupt = 0;
struct super_block *sb = old_dir->i_sb;

if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode))
dentry_unhash(new_dentry);

old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode;
Expand Down
6 changes: 6 additions & 0 deletions fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,8 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
if (IS_ERR(req))
return PTR_ERR(req);

dentry_unhash(entry);

req->in.h.opcode = FUSE_RMDIR;
req->in.h.nodeid = get_node_id(dir);
req->in.numargs = 1;
Expand All @@ -691,6 +693,10 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
struct fuse_rename_in inarg;
struct fuse_conn *fc = get_fuse_conn(olddir);
struct fuse_req *req = fuse_get_req(fc);

if (newent->d_inode && S_ISDIR(newent->d_inode->i_mode))
dentry_unhash(newent);

if (IS_ERR(req))
return PTR_ERR(req);

Expand Down
6 changes: 6 additions & 0 deletions fs/hfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ static int hfs_remove(struct inode *dir, struct dentry *dentry)
struct inode *inode = dentry->d_inode;
int res;

if (S_ISDIR(inode->i_mode))
dentry_unhash(dentry);

if (S_ISDIR(inode->i_mode) && inode->i_size != 2)
return -ENOTEMPTY;
res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name);
Expand Down Expand Up @@ -283,6 +286,9 @@ static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry,

/* Unlink destination if it already exists */
if (new_dentry->d_inode) {
if (S_ISDIR(new_dentry->d_inode->i_mode))
dentry_unhash(new_dentry);

res = hfs_remove(new_dir, new_dentry);
if (res)
return res;
Expand Down
8 changes: 6 additions & 2 deletions fs/hfsplus/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry)
struct inode *inode = dentry->d_inode;
int res;

dentry_unhash(dentry);

if (inode->i_size != 2)
return -ENOTEMPTY;

Expand Down Expand Up @@ -467,10 +469,12 @@ static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry,

/* Unlink destination if it already exists */
if (new_dentry->d_inode) {
if (S_ISDIR(new_dentry->d_inode->i_mode))
if (S_ISDIR(new_dentry->d_inode->i_mode)) {
dentry_unhash(new_dentry);
res = hfsplus_rmdir(new_dir, new_dentry);
else
} else {
res = hfsplus_unlink(new_dir, new_dentry);
}
if (res)
return res;
}
Expand Down
5 changes: 5 additions & 0 deletions fs/hostfs/hostfs_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,8 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
char *file;
int err;

dentry_unhash(dentry);

if ((file = dentry_name(dentry)) == NULL)
return -ENOMEM;
err = do_rmdir(file);
Expand Down Expand Up @@ -736,6 +738,9 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
char *from_name, *to_name;
int err;

if (to->d_inode && S_ISDIR(to->d_inode->i_mode))
dentry_unhash(to);

if ((from_name = dentry_name(from)) == NULL)
return -ENOMEM;
if ((to_name = dentry_name(to)) == NULL) {
Expand Down
9 changes: 6 additions & 3 deletions fs/hpfs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,23 +395,20 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry)

dentry_unhash(dentry);
if (!d_unhashed(dentry)) {
dput(dentry);
hpfs_unlock(dir->i_sb);
return -ENOSPC;
}
if (generic_permission(inode, MAY_WRITE, 0, NULL) ||
!S_ISREG(inode->i_mode) ||
get_write_access(inode)) {
d_rehash(dentry);
dput(dentry);
} else {
struct iattr newattrs;
/*printk("HPFS: truncating file before delete.\n");*/
newattrs.ia_size = 0;
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
err = notify_change(dentry, &newattrs);
put_write_access(inode);
dput(dentry);
if (!err)
goto again;
}
Expand Down Expand Up @@ -442,6 +439,8 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
int err;
int r;

dentry_unhash(dentry);

hpfs_adjust_length(name, &len);
hpfs_lock(dir->i_sb);
err = -ENOENT;
Expand Down Expand Up @@ -535,6 +534,10 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct buffer_head *bh;
struct fnode *fnode;
int err;

if (new_inode && S_ISDIR(new_inode->i_mode))
dentry_unhash(new_dentry);

if ((err = hpfs_chk_name(new_name, &new_len))) return err;
err = 0;
hpfs_adjust_length(old_name, &old_len);
Expand Down
Loading

0 comments on commit 32e51f1

Please sign in to comment.