Exemplo n.º 1
0
/* based on generic filldir in fs/readir.c */
static int unionfs_filldir(void *dirent, const char *oname, int namelen,
			   loff_t offset, u64 ino, unsigned int d_type)
{
	struct unionfs_getdents_callback *buf = dirent;
	struct filldir_node *found = NULL;
	int err = 0;
	int is_whiteout;
	char *name = (char *) oname;

	buf->filldir_called++;

	is_whiteout = is_whiteout_name(&name, &namelen);

	found = find_filldir_node(buf->rdstate, name, namelen, is_whiteout);

	if (found) {
		/*
		 * If we had non-whiteout entry in dir cache, then mark it
		 * as a whiteout and but leave it in the dir cache.
		 */
		if (is_whiteout && !found->whiteout)
			found->whiteout = is_whiteout;
		goto out;
	}

	/* if 'name' isn't a whiteout, filldir it. */
	if (!is_whiteout) {
		off_t pos = rdstate2offset(buf->rdstate);
		u64 unionfs_ino = ino;

		err = buf->filldir(buf->dirent, name, namelen, pos,
				   unionfs_ino, d_type);
		buf->rdstate->offset++;
		verify_rdstate_offset(buf->rdstate);
	}
	/*
	 * If we did fill it, stuff it in our hash, otherwise return an
	 * error.
	 */
	if (err) {
		buf->filldir_error = err;
		goto out;
	}
	buf->entries_written++;
	err = add_filldir_node(buf->rdstate, name, namelen,
			       buf->rdstate->bindex, is_whiteout);
	if (err)
		buf->filldir_error = err;

out:
	return err;
}
Exemplo n.º 2
0
/* This filldir function makes sure only whiteouts exist within a directory. */
static int readdir_util_callback(void *dirent, const char *oname, int namelen,
				 loff_t offset, u64 ino, unsigned int d_type)
{
	int err = 0;
	struct unionfs_rdutil_callback *buf = dirent;
	int is_whiteout;
	struct filldir_node *found;
	char *name = (char *) oname;

	buf->filldir_called = 1;

	if (name[0] == '.' && (namelen == 1 ||
			       (name[1] == '.' && namelen == 2)))
		goto out;

	is_whiteout = is_whiteout_name(&name, &namelen);

	found = find_filldir_node(buf->rdstate, name, namelen, is_whiteout);
	/* If it was found in the table there was a previous whiteout. */
	if (found)
		goto out;

	/*
	 * if it wasn't found and isn't a whiteout, the directory isn't
	 * empty.
	 */
	err = -ENOTEMPTY;
	if ((buf->mode == RD_CHECK_EMPTY) && !is_whiteout)
		goto out;

	err = add_filldir_node(buf->rdstate, name, namelen,
			       buf->rdstate->bindex, is_whiteout);

out:
	buf->err = err;
	return err;
}