示例#1
0
/*
 * Lookup or create a dentry from within the filesystem.
 *
 * We need to use this instead of lookup_dentry, as the 
 * directory semaphore lock is already held.
 */
struct dentry *umsdos_lookup_dentry(struct dentry *parent, char *name, int len,
					int real)
{
	struct dentry *result, *dentry;
	struct qstr qstr;

	qstr.name = name;
	qstr.len  = len;
	qstr.hash = full_name_hash(name, len);
	result = d_lookup(parent, &qstr);
	if (!result) {
		result = ERR_PTR(-ENOMEM);
		dentry = d_alloc(parent, &qstr);
		if (dentry) {
			result = real ?
				UMSDOS_rlookup(parent->d_inode, dentry) :
				UMSDOS_lookup(parent->d_inode, dentry);
			if (result)
				goto out_fail;
			return dentry;
		}
	}
out:
	return result;

out_fail:
	dput(dentry);
	goto out;
}
示例#2
0
struct dentry *umsdos_covered(struct dentry *parent, char *name, int len)
{
	struct dentry *result, *dentry;
	struct qstr qstr;

	qstr.name = name;
	qstr.len  = len;
	qstr.hash = full_name_hash(name, len);
	result = ERR_PTR(-ENOMEM);
	dentry = d_alloc(parent, &qstr);
	if (dentry) {
		/* XXXXXXXXXXXXXXXXXXX Race alert! */
		result = UMSDOS_rlookup(parent->d_inode, dentry);
		d_drop(dentry);
		if (result)
			goto out_fail;
		return dentry;
	}
out:
	return result;

out_fail:
	dput(dentry);
	goto out;
}
示例#3
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;
}