Example #1
0
int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
{
	int err = 0;
	struct unionfs_dir_state *namelist = NULL;

	print_entry_location();
	lock_dentry(dentry);
	fist_print_dentry("IN unionfs_rmdir: ", dentry);

	/* check if this unionfs directory is empty or not */
	err = check_empty(dentry, &namelist);
	if (err) {
		goto out;
	}

	if (IS_SET(dir->i_sb, DELETE_WHITEOUT)) {
		/* Delete the first directory. */
		err = unionfs_rmdir_first(dir, dentry, namelist);
		/* create whiteout */
		if (!err) {
			err = create_whiteout(dentry, dbstart(dentry));
		} else {
			int new_err;

			if (dbstart(dentry) == 0)
				goto out;

			/* exit if the error returned was NOT -EROFS */
			if (!IS_COPYUP_ERR(err))
				goto out;

			new_err = create_whiteout(dentry, dbstart(dentry) - 1);
			if (new_err != -EEXIST)
				err = new_err;
		}
	} else {
		/* delete all. */
		err = unionfs_rmdir_all(dir, dentry, namelist);
	}

      out:
	/* call d_drop so the system "forgets" about us */
	if (!err)
		d_drop(dentry);

	if (namelist)
		free_rdstate(namelist);

	unlock_dentry(dentry);
	print_exit_status(err);
	return err;
}
Example #2
0
int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
{
	int err = 0;
	struct unionfs_dir_state *namelist = NULL;

	unionfs_lock_dentry(dentry);

	/* check if this unionfs directory is empty or not */
	err = check_empty(dentry, &namelist);
	if (err)
		goto out;

	err = unionfs_rmdir_first(dir, dentry, namelist);
	/* create whiteout */
	if (!err)
		err = create_whiteout(dentry, dbstart(dentry));
	else {
		int new_err;

		if (dbstart(dentry) == 0)
			goto out;

		/* exit if the error returned was NOT -EROFS */
		if (!IS_COPYUP_ERR(err))
			goto out;

		new_err = create_whiteout(dentry, dbstart(dentry) - 1);
		if (new_err != -EEXIST)
			err = new_err;
	}

out:
	/* call d_drop so the system "forgets" about us */
	if (!err)
		d_drop(dentry);

	if (namelist)
		free_rdstate(namelist);

	unionfs_unlock_dentry(dentry);
	return err;
}
Example #3
0
int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
{
	int err = 0;
	struct unionfs_dir_state *namelist = NULL;

	print_entry_location();
	lock_dentry(dentry);
	fist_print_dentry("IN unionfs_rmdir: ", dentry);

	/* check if this unionfs directory is empty or not */
	err = check_empty(dentry, &namelist);
	if (err) {
#if 0
		/* vfs_rmdir(our caller) unhashed the dentry.  This will recover
		 * the Unionfs inode number for the directory itself, but the 
		 * children are already lost.  It seems that tmpfs manages its
		 * way around this by upping the refcount on everything.
		 *
		 * Even if we do this, we still lose the inode numbers of the
		 * children.  The best way to fix this is to fix the VFS (or
		 * use persistent inode maps). */
		if (d_unhashed(dentry))
			d_rehash(dentry);
#endif
		goto out;
	}
#ifdef UNIONFS_DELETE_ALL
	if (IS_SET(dir->i_sb, DELETE_ALL)) {
		/* delete all. */
		err = unionfs_rmdir_all(dir, dentry, namelist);
	} else {		/* Delete the first directory. */
#endif
		err = unionfs_rmdir_first(dir, dentry, namelist);
		/* create whiteout */
		if (!err) {
			err = create_whiteout(dentry, dbstart(dentry));
		} else {
			int new_err;

			if (dbstart(dentry) == 0)
				goto out;

			/* exit if the error returned was NOT -EROFS */
			if (!IS_COPYUP_ERR(err))
				goto out;

			new_err = create_whiteout(dentry, dbstart(dentry) - 1);
			if (new_err != -EEXIST)
				err = new_err;
		}

#ifdef UNIONFS_DELETE_ALL
	}
#endif
      out:
	/* call d_drop so the system "forgets" about us */
	if (!err)
		d_drop(dentry);

	if (namelist)
		free_rdstate(namelist);

	unlock_dentry(dentry);
	print_exit_status(err);
	return err;
}