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:
		
					parent
					
						
							
								64252c75a2
							
						
					
				
			
			
				commit
				
					
						79bf7c732b
					
				
			
		
					 37 changed files with 78 additions and 3 deletions
				
			
		| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -461,6 +461,8 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	int r;
 | 
						int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hpfs_adjust_length(name, &len);
 | 
						hpfs_adjust_length(name, &len);
 | 
				
			||||||
	hpfs_lock(dir->i_sb);
 | 
						hpfs_lock(dir->i_sb);
 | 
				
			||||||
	mutex_lock(&hpfs_i(inode)->i_parent_mutex);
 | 
						mutex_lock(&hpfs_i(inode)->i_parent_mutex);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -609,6 +609,8 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	uint32_t now = get_seconds();
 | 
						uint32_t now = get_seconds();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (fd = f->dents ; fd; fd = fd->next) {
 | 
						for (fd = f->dents ; fd; fd = fd->next) {
 | 
				
			||||||
		if (fd->ino)
 | 
							if (fd->ino)
 | 
				
			||||||
			return -ENOTEMPTY;
 | 
								return -ENOTEMPTY;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -360,6 +360,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name);
 | 
						jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Init inode for quota operations. */
 | 
						/* Init inode for quota operations. */
 | 
				
			||||||
	dquot_initialize(dip);
 | 
						dquot_initialize(dip);
 | 
				
			||||||
	dquot_initialize(ip);
 | 
						dquot_initialize(ip);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -311,6 +311,8 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
	if (!simple_empty(dentry))
 | 
						if (!simple_empty(dentry))
 | 
				
			||||||
		return -ENOTEMPTY;
 | 
							return -ENOTEMPTY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drop_nlink(dentry->d_inode);
 | 
						drop_nlink(dentry->d_inode);
 | 
				
			||||||
	simple_unlink(dir, dentry);
 | 
						simple_unlink(dir, dentry);
 | 
				
			||||||
	drop_nlink(dir);
 | 
						drop_nlink(dir);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -273,6 +273,8 @@ static int logfs_rmdir(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct inode *inode = dentry->d_inode;
 | 
						struct inode *inode = dentry->d_inode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!logfs_empty_dir(inode))
 | 
						if (!logfs_empty_dir(inode))
 | 
				
			||||||
		return -ENOTEMPTY;
 | 
							return -ENOTEMPTY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,6 +168,8 @@ static int minix_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 (minix_empty_dir(inode)) {
 | 
						if (minix_empty_dir(inode)) {
 | 
				
			||||||
		err = minix_unlink(dir, dentry);
 | 
							err = minix_unlink(dir, dentry);
 | 
				
			||||||
		if (!err) {
 | 
							if (!err) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2568,7 +2568,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		error = security_inode_rmdir(dir, dentry);
 | 
							error = security_inode_rmdir(dir, dentry);
 | 
				
			||||||
		if (!error) {
 | 
							if (!error) {
 | 
				
			||||||
			dentry_unhash(dentry);
 | 
					 | 
				
			||||||
			error = dir->i_op->rmdir(dir, dentry);
 | 
								error = dir->i_op->rmdir(dir, dentry);
 | 
				
			||||||
			if (!error) {
 | 
								if (!error) {
 | 
				
			||||||
				dentry->d_inode->i_flags |= S_DEAD;
 | 
									dentry->d_inode->i_flags |= S_DEAD;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1033,6 +1033,8 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
	DPRINTK("ncp_rmdir: removing %s/%s\n",
 | 
						DPRINTK("ncp_rmdir: removing %s/%s\n",
 | 
				
			||||||
		dentry->d_parent->d_name.name, dentry->d_name.name);
 | 
							dentry->d_parent->d_name.name, dentry->d_name.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	error = -EBUSY;
 | 
						error = -EBUSY;
 | 
				
			||||||
	if (!d_unhashed(dentry))
 | 
						if (!d_unhashed(dentry))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1748,6 +1748,8 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
	dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n",
 | 
						dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n",
 | 
				
			||||||
			dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
 | 
								dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
 | 
						error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
 | 
				
			||||||
	/* Ensure the VFS deletes this inode */
 | 
						/* Ensure the VFS deletes this inode */
 | 
				
			||||||
	if (error == 0 && dentry->d_inode != NULL)
 | 
						if (error == 0 && dentry->d_inode != NULL)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -334,6 +334,8 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
	struct nilfs_transaction_info ti;
 | 
						struct nilfs_transaction_info ti;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
 | 
						err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -810,6 +810,9 @@ static int ocfs2_unlink(struct inode *dir,
 | 
				
			||||||
			   (unsigned long long)OCFS2_I(dir)->ip_blkno,
 | 
								   (unsigned long long)OCFS2_I(dir)->ip_blkno,
 | 
				
			||||||
			   (unsigned long long)OCFS2_I(inode)->ip_blkno);
 | 
								   (unsigned long long)OCFS2_I(inode)->ip_blkno);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (S_ISDIR(inode->i_mode))
 | 
				
			||||||
 | 
							dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dquot_initialize(dir);
 | 
						dquot_initialize(dir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUG_ON(dentry->d_parent->d_inode != dir);
 | 
						BUG_ON(dentry->d_parent->d_inode != dir);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -240,8 +240,12 @@ static int omfs_remove(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
	struct inode *inode = dentry->d_inode;
 | 
						struct inode *inode = dentry->d_inode;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (S_ISDIR(inode->i_mode) && !omfs_dir_is_empty(inode))
 | 
					
 | 
				
			||||||
		return -ENOTEMPTY;
 | 
						if (S_ISDIR(inode->i_mode)) {
 | 
				
			||||||
 | 
							dentry_unhash(dentry);
 | 
				
			||||||
 | 
							if (!omfs_dir_is_empty(inode))
 | 
				
			||||||
 | 
								return -ENOTEMPTY;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = omfs_delete_entry(dentry);
 | 
						ret = omfs_delete_entry(dentry);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -831,6 +831,8 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
	INITIALIZE_PATH(path);
 | 
						INITIALIZE_PATH(path);
 | 
				
			||||||
	struct reiserfs_dir_entry de;
 | 
						struct reiserfs_dir_entry de;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* we will be doing 2 balancings and update 2 stat data, we change quotas
 | 
						/* we will be doing 2 balancings and update 2 stat data, we change quotas
 | 
				
			||||||
	 * of the owner of the directory and of the owner of the parent directory.
 | 
						 * of the owner of the directory and of the owner of the parent directory.
 | 
				
			||||||
	 * The quota structure is possibly deleted only on last iput => outside
 | 
						 * The quota structure is possibly deleted only on last iput => outside
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -196,6 +196,8 @@ static int sysv_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 (sysv_empty_dir(inode)) {
 | 
						if (sysv_empty_dir(inode)) {
 | 
				
			||||||
		err = sysv_unlink(dir, dentry);
 | 
							err = sysv_unlink(dir, dentry);
 | 
				
			||||||
		if (!err) {
 | 
							if (!err) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -656,6 +656,8 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
	struct ubifs_inode *dir_ui = ubifs_inode(dir);
 | 
						struct ubifs_inode *dir_ui = ubifs_inode(dir);
 | 
				
			||||||
	struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
 | 
						struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Budget request settings: deletion direntry, deletion inode and
 | 
						 * Budget request settings: deletion direntry, deletion inode and
 | 
				
			||||||
	 * changing the parent inode. If budgeting fails, go ahead anyway
 | 
						 * changing the parent inode. If budgeting fails, go ahead anyway
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -783,6 +783,8 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
 | 
				
			||||||
	struct fileIdentDesc *fi, cfi;
 | 
						struct fileIdentDesc *fi, cfi;
 | 
				
			||||||
	struct kernel_lb_addr tloc;
 | 
						struct kernel_lb_addr tloc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dentry_unhash(dentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	retval = -ENOENT;
 | 
						retval = -ENOENT;
 | 
				
			||||||
	fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
 | 
						fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
 | 
				
			||||||
	if (!fi)
 | 
						if (!fi)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -258,6 +258,8 @@ static int ufs_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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lock_ufs(dir->i_sb);
 | 
						lock_ufs(dir->i_sb);
 | 
				
			||||||
	if (ufs_empty_dir (inode)) {
 | 
						if (ufs_empty_dir (inode)) {
 | 
				
			||||||
		err = ufs_unlink(dir, dentry);
 | 
							err = ufs_unlink(dir, dentry);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue