Пример #1
0
/* #Specification: pseudo root / rmdir /DOS
 * The pseudo sub-directory /DOS can't be removed!
 * This is done even if the pseudo root is not a Umsdos
 * directory anymore (very unlikely), but an accident (under
 * MS-DOS) is always possible.
 * 
 * EPERM is returned.
 */
static int UMSDOS_rrmdir ( struct inode *dir, struct dentry *dentry)
{
	int ret, empty;

	ret = -EPERM;
	if (umsdos_is_pseudodos (dir, dentry))
		goto out;

	ret = -EBUSY;
	if (!d_unhashed(dentry))
		goto out;

	ret = msdos_rmdir (dir, dentry);
	if (ret != -ENOTEMPTY)
		goto out;

	empty = umsdos_isempty (dentry);
	if (empty == 1) {
		struct dentry *demd;
		/* We have to remove the EMD file. */
		demd = umsdos_get_emd_dentry(dentry);
		ret = PTR_ERR(demd);
		if (!IS_ERR(demd)) {
			ret = 0;
			if (demd->d_inode)
				ret = msdos_unlink (dentry->d_inode, demd);
			if (!ret)
				d_delete(demd);
			dput(demd);
		}
	}
	if (ret)
		goto out;

	/* now retry the original ... */
	ret = msdos_rmdir (dir, dentry);

out:
	return ret;
}
Пример #2
0
static int UMSDOS_rrmdir (
	struct inode *dir,
	const char *name,
	int len)
{
	/* #Specification: dual mode / rmdir in a DOS directory
		In a DOS (not EMD in it) directory, we use a reverse strategy
		compared with an Umsdos directory. We assume that a subdirectory
		of a DOS directory is also a DOS directory. This is not always
		true (umssync may be used anywhere), but make sense.

		So we call msdos_rmdir() directly. If it failed with a -ENOTEMPTY
		then we check if it is a Umsdos directory. We check if it is
		really empty (only . .. and --linux-.--- in it). If it is true
		we remove the EMD and do a msdos_rmdir() again.

		In a Umsdos directory, we assume all subdirectory are also
		Umsdos directory, so we check the EMD file first.
	*/
	int ret;
	if (umsdos_is_pseudodos(dir,name,len)){
		/* #Specification: pseudo root / rmdir /DOS
			The pseudo sub-directory /DOS can't be removed!
			This is done even if the pseudo root is not a Umsdos
			directory anymore (very unlikely), but an accident (under
			MsDOS) is always possible.

			EPERM is returned.
		*/
		ret = -EPERM;
	}else{
		umsdos_lockcreate (dir);
		dir->i_count++;
		ret = msdos_rmdir (dir,name,len);
		if (ret == -ENOTEMPTY){
			struct inode *sdir;
			dir->i_count++;
			ret = UMSDOS_rlookup (dir,name,len,&sdir);
			PRINTK (("rrmdir lookup %d ",ret));
			if (ret == 0){
				int empty;
				if ((empty = umsdos_isempty (sdir)) != 0){
					PRINTK (("isempty %d i_count %d ",empty,sdir->i_count));
					if (empty == 2){
						/*
							Not a Umsdos directory, so the previous msdos_rmdir
							was not lying :-)
						*/
						ret = -ENOTEMPTY;
					}else if (empty == 1){
						/* We have to removed the EMD file */
						ret = msdos_unlink(sdir,UMSDOS_EMD_FILE
							,UMSDOS_EMD_NAMELEN);
						sdir = NULL;
						if (ret == 0){
							dir->i_count++;
							ret = msdos_rmdir (dir,name,len);
						}
					}
				}else{
					ret = -ENOTEMPTY;
				}
				iput (sdir);
			}
		}
		umsdos_unlockcreate (dir);
	}
	iput (dir);
	return ret;
}