You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
vfs: push dentry_unhash on rmdir into file systems
Only a few file systems need this. Start by pushing it down into each fs rmdir method (except gfs2 and xfs) so it can be dealt with on a per-fs basis. This does not change behavior for any in-tree file systems. Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Sage Weil <sage@newdream.net> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -814,6 +814,7 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
|
|||||||
|
|
||||||
int v9fs_vfs_rmdir(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);
|
return v9fs_remove(i, d, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -320,6 +320,8 @@ affs_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
dentry->d_inode->i_ino,
|
dentry->d_inode->i_ino,
|
||||||
(int)dentry->d_name.len, dentry->d_name.name);
|
(int)dentry->d_name.len, dentry->d_name.name);
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
return affs_remove_header(dentry);
|
return affs_remove_header(dentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -845,6 +845,8 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
_enter("{%x:%u},{%s}",
|
_enter("{%x:%u},{%s}",
|
||||||
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);
|
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
ret = -ENAMETOOLONG;
|
ret = -ENAMETOOLONG;
|
||||||
if (dentry->d_name.len >= AFSNAMEMAX)
|
if (dentry->d_name.len >= AFSNAMEMAX)
|
||||||
goto error;
|
goto error;
|
||||||
|
|||||||
@@ -583,6 +583,8 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
|
|||||||
if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
|
if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
if (atomic_dec_and_test(&ino->count)) {
|
if (atomic_dec_and_test(&ino->count)) {
|
||||||
p_ino = autofs4_dentry_ino(dentry->d_parent);
|
p_ino = autofs4_dentry_ino(dentry->d_parent);
|
||||||
if (p_ino && dentry->d_parent != dentry)
|
if (p_ino && dentry->d_parent != dentry)
|
||||||
|
|||||||
@@ -3062,6 +3062,8 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
|
inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
|
||||||
return -ENOTEMPTY;
|
return -ENOTEMPTY;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
trans = __unlink_start_trans(dir, dentry);
|
trans = __unlink_start_trans(dir, dentry);
|
||||||
if (IS_ERR(trans))
|
if (IS_ERR(trans))
|
||||||
return PTR_ERR(trans);
|
return PTR_ERR(trans);
|
||||||
|
|||||||
@@ -827,6 +827,9 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
|
|||||||
int err = -EROFS;
|
int err = -EROFS;
|
||||||
int op;
|
int op;
|
||||||
|
|
||||||
|
if ((dentry->d_inode->i_mode & S_IFMT) == S_IFDIR)
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
if (ceph_snap(dir) == CEPH_SNAPDIR) {
|
if (ceph_snap(dir) == CEPH_SNAPDIR) {
|
||||||
/* rmdir .snap/foo is RMSNAP */
|
/* rmdir .snap/foo is RMSNAP */
|
||||||
dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len,
|
dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len,
|
||||||
|
|||||||
@@ -1461,6 +1461,8 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
|
|||||||
|
|
||||||
cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
|
cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
|
||||||
|
|
||||||
|
dentry_unhash(direntry);
|
||||||
|
|
||||||
xid = GetXid();
|
xid = GetXid();
|
||||||
|
|
||||||
full_path = build_path_from_dentry(direntry);
|
full_path = build_path_from_dentry(direntry);
|
||||||
|
|||||||
@@ -336,6 +336,8 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
|
|||||||
int len = de->d_name.len;
|
int len = de->d_name.len;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
dentry_unhash(de);
|
||||||
|
|
||||||
error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
|
error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
/* VFS may delete the child */
|
/* VFS may delete the child */
|
||||||
|
|||||||
@@ -1355,6 +1355,8 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
struct module *subsys_owner = NULL, *dead_item_owner = NULL;
|
struct module *subsys_owner = NULL, *dead_item_owner = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
if (dentry->d_parent == configfs_sb->s_root)
|
if (dentry->d_parent == configfs_sb->s_root)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
|||||||
@@ -521,6 +521,8 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
struct dentry *lower_dir_dentry;
|
struct dentry *lower_dir_dentry;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||||
dget(dentry);
|
dget(dentry);
|
||||||
lower_dir_dentry = lock_parent(lower_dentry);
|
lower_dir_dentry = lock_parent(lower_dentry);
|
||||||
|
|||||||
@@ -227,6 +227,8 @@ static int exofs_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
int err = -ENOTEMPTY;
|
int err = -ENOTEMPTY;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
if (exofs_empty_dir(inode)) {
|
if (exofs_empty_dir(inode)) {
|
||||||
err = exofs_unlink(dir, dentry);
|
err = exofs_unlink(dir, dentry);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
|
|||||||
@@ -296,6 +296,8 @@ static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
|
|||||||
struct inode * inode = dentry->d_inode;
|
struct inode * inode = dentry->d_inode;
|
||||||
int err = -ENOTEMPTY;
|
int err = -ENOTEMPTY;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
if (ext2_empty_dir(inode)) {
|
if (ext2_empty_dir(inode)) {
|
||||||
err = ext2_unlink(dir, dentry);
|
err = ext2_unlink(dir, dentry);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
|
|||||||
@@ -2074,6 +2074,8 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
|
|||||||
struct ext3_dir_entry_2 * de;
|
struct ext3_dir_entry_2 * de;
|
||||||
handle_t *handle;
|
handle_t *handle;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
/* Initialize quotas before so that eventual writes go in
|
/* Initialize quotas before so that eventual writes go in
|
||||||
* separate transaction */
|
* separate transaction */
|
||||||
dquot_initialize(dir);
|
dquot_initialize(dir);
|
||||||
|
|||||||
@@ -2123,6 +2123,8 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
struct ext4_dir_entry_2 *de;
|
struct ext4_dir_entry_2 *de;
|
||||||
handle_t *handle;
|
handle_t *handle;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
/* Initialize quotas before so that eventual writes go in
|
/* Initialize quotas before so that eventual writes go in
|
||||||
* separate transaction */
|
* separate transaction */
|
||||||
dquot_initialize(dir);
|
dquot_initialize(dir);
|
||||||
|
|||||||
@@ -326,6 +326,8 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
struct fat_slot_info sinfo;
|
struct fat_slot_info sinfo;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
lock_super(sb);
|
lock_super(sb);
|
||||||
/*
|
/*
|
||||||
* Check whether the directory is not in use, then check
|
* Check whether the directory is not in use, then check
|
||||||
|
|||||||
@@ -824,6 +824,8 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
struct fat_slot_info sinfo;
|
struct fat_slot_info sinfo;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
lock_super(sb);
|
lock_super(sb);
|
||||||
|
|
||||||
err = fat_dir_empty(inode);
|
err = fat_dir_empty(inode);
|
||||||
|
|||||||
@@ -667,6 +667,8 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
|
|||||||
if (IS_ERR(req))
|
if (IS_ERR(req))
|
||||||
return PTR_ERR(req);
|
return PTR_ERR(req);
|
||||||
|
|
||||||
|
dentry_unhash(entry);
|
||||||
|
|
||||||
req->in.h.opcode = FUSE_RMDIR;
|
req->in.h.opcode = FUSE_RMDIR;
|
||||||
req->in.h.nodeid = get_node_id(dir);
|
req->in.h.nodeid = get_node_id(dir);
|
||||||
req->in.numargs = 1;
|
req->in.numargs = 1;
|
||||||
|
|||||||
@@ -253,6 +253,9 @@ static int hfs_remove(struct inode *dir, struct dentry *dentry)
|
|||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
if (S_ISDIR(inode->i_mode))
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
if (S_ISDIR(inode->i_mode) && inode->i_size != 2)
|
if (S_ISDIR(inode->i_mode) && inode->i_size != 2)
|
||||||
return -ENOTEMPTY;
|
return -ENOTEMPTY;
|
||||||
res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name);
|
res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name);
|
||||||
|
|||||||
@@ -370,6 +370,8 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
if (inode->i_size != 2)
|
if (inode->i_size != 2)
|
||||||
return -ENOTEMPTY;
|
return -ENOTEMPTY;
|
||||||
|
|
||||||
|
|||||||
@@ -683,6 +683,8 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
|
|||||||
char *file;
|
char *file;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
dentry_unhash(dentry);
|
||||||
|
|
||||||
if ((file = dentry_name(dentry)) == NULL)
|
if ((file = dentry_name(dentry)) == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
err = do_rmdir(file);
|
err = do_rmdir(file);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user