/*
 * linux/fs/reiserfs/xattr.c
 *
 * Copyright (c) 2002 by Jeff Mahoney, <jeffm@suse.com>
 *
 */

/*
 * In order to implement EA/ACLs in a clean, backwards compatible manner,
 * they are implemented as files in a "private" directory.
 * Each EA is in it's own file, with the directory layout like so (/ is assumed
 * to be relative to fs root). Inside the /.reiserfs_priv/xattrs directory,
 * directories named using the capital-hex form of the objectid and
 * generation number are used. Inside each directory are individual files
 * named with the name of the extended attribute.
 *
 * So, for objectid 12648430, we could have:
 * /.reiserfs_priv/xattrs/C0FFEE.0/system.posix_acl_access
 * /.reiserfs_priv/xattrs/C0FFEE.0/system.posix_acl_default
 * /.reiserfs_priv/xattrs/C0FFEE.0/user.Content-Type
 * .. or similar.
 *
 * The file contents are the text of the EA. The size is known based on the
 * stat data describing the file.
 *
 * In the case of system.posix_acl_access and system.posix_acl_default, since
 * these are special cases for filesystem ACLs, they are interpreted by the
 * kernel, in addition, they are negatively and positively cached and attached
 * to the inode so that unnecessary lookups are avoided.
 */

#include <linux/reiserfs_fs.h>
#include <linux/capability.h>
#include <linux/dcache.h>
#include <linux/namei.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/pagemap.h>
#include <linux/xattr.h>
#include <linux/reiserfs_xattr.h>
#include <linux/reiserfs_acl.h>
#include <asm/uaccess.h>
#include <net/checksum.h>
#include <linux/smp_lock.h>
#include <linux/stat.h>
#include <asm/semaphore.h>

#define FL_READONLY 128
#define FL_DIR_SEM_HELD 256
#define PRIVROOT_NAME ".reiserfs_priv"
#define XAROOT_NAME   "xattrs"

static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
								*prefix);

static struct dentry *create_xa_root(struct super_block *sb)
{
	struct dentry *privroot = dget(REISERFS_SB(sb)->priv_root);
	struct dentry *xaroot;

	/* This needs to be created at mount-time */
	if (!privroot)
		return ERR_PTR(-EOPNOTSUPP);

	xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME));
	if (IS_ERR(xaroot)) {
		goto out;
	} else if (!xaroot->d_inode) {
		int err;
		mutex_lock(&privroot->d_inode->i_mutex);
		err =
		    privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot,
						   0700);
		mutex_unlock(&privroot->d_inode->i_mutex);

		if (err) {
			dput(xaroot);
			dput(privroot);
			return ERR_PTR(err);
		}
		REISERFS_SB(sb)->xattr_root = dget(xaroot);
	}

      out:
	dput(privroot);
	return xaroot;
}

/* This will return a dentry, or error, refering to the xa root directory.
 * If the xa root doesn't exist yet, the dentry will be returned without
 * an associated inode. This dentry can be used with ->mkdir to create
 * the xa directory. */
static struct dentry *__get_xa_root(struct super_block *s)
{
	struct dentry *privroot = dget(REISERFS_SB(s)->priv_root);
	struct dentry *xaroot = NULL;

	if (IS_ERR(privroot) || !privroot)
		return privroot;

	xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME));
	if (IS_ERR(xaroot)) {
		goto out;
	} else if (!xaroot->d_inode) {
		dput(xaroot);
		xaroot = NULL;
		goto out;
	}

	REISERFS_SB(s)->xattr_root = dget(xaroot);

      out:
	dput(privroot);
	return xaroot;
}

/* Returns the dentry (or NULL) referring to the root of the extended
 * attribute directory tree. If it has already been retrieved, it is used.
 * Otherwise, we attempt to retrieve it from disk. It may also return
 * a pointer-encoded error.
 */
static inline struct dentry *get_xa_root(struct super_block *s)
{
	struct dentry *dentry = dget(REISERFS_SB(s)->xattr_root);

	if (!dentry)
		dentry = __get_xa_root(s);

	return dentry;
}

/* Opens the directory corresponding to the inode's extended attribute store.
 * If flags allow, the tree to the directory may be created. If creation is
 * prohibited, -ENODATA is returned. */
static struct dentry *open_xa_dir(const struct inode *inode, int flags)
{
	struct dentry *xaroot, *xadir;
	char namebuf[17];

	xaroot = get_xa_root(inode->i_sb);
	if (IS_ERR(xaroot)) {
		return xaroot;
	} else if (!xaroot) {
		if (flags == 0 || flags & XATTR_CREATE) {
			xaroot = create_xa_root(inode->i_sb);
			if (IS_ERR(xaroot))
				return xaroot;
		}
		if (!xaroot)
			return ERR_PTR(-ENODATA);
	}

	/* ok, we have xaroot open */

	snprintf(namebuf, sizeof(namebuf), "%X.%X",
		 le32_to_cpu(INODE_PKEY(inode)->k_objectid),
		 inode->i_generation);
	xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf));
	if (IS_ERR(xadir)) {
		dput(xaroot);
		return xadir;
	}

	if (!xadir->d_inode) {
		int err;
		if (flags == 0 || flags & XATTR_CREATE) {
			/* Although there is nothing else trying to create this directory,
			 * another directory with the same hash may be created, so we need
			 * to protect against that */
			err =
			    xaroot->d_inode->i_op->mkdir(xaroot->d_inode, xadir,
							 0700);
			if (err) {
				dput(xaroot);
				dput(xadir);
				return ERR_PTR(err);
			}
		}
		if (!xadir->d_inode) {
			dput(xaroot);
			dput(xadir);
			return ERR_PTR(-ENODATA);
		}
	}

	dput(xaroot);
	return xadir;
}

/* Returns a dentry corresponding to a specific extended attribute file
 * for the inode. If flags allow, the file is created. Otherwise, a
 * valid or negative dentry, or an error is returned. */
static struct dentry *get_xa_file_dentry(const struct inode *inode,
					 const char *name, int flags)
{
	struct dentry *xadir, *xafile;
	int err = 0;

	xadir = open_xa_dir(inode, flags);
	if (IS_ERR(xadir)) {
		return ERR_PTR(PTR_ERR(xadir));
	} else if (xadir && !xadir->d_inode) {
		dput(xadir);
		return ERR_PTR(-ENODATA);
	}

	xafile = lookup_one_len(name, xadir, strlen(name));
	if (IS_ERR(xafile)) {
		dput(xadir);
		return ERR_PTR(PTR_ERR(xafile));
	}

	if (xafile->d_inode) {	/* file exists */
		if (flags & XATTR_CREATE) {
			err = -EEXIST;
			dput(xafile);
			goto out;
		}
	} else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
		goto out;
	} else {
		/* inode->i_mutex is down, so nothing else can try to create
		 * the same xattr */
		err = xadir->d_inode->i_op->create(xadir->d_inode, xafile,
						   0700 | S_IFREG, NULL);

		if (err) {
			dput(xafile);
			goto out;
		}
	}

      out:
	dput(xadir);
	if (err)
		xafile = ERR_PTR(err);
	return xafile;
}

/* Opens a file pointer to the attribute associated with inode */
static struct file *open_xa_file(const struct inode *inode, const char *name,
				 int flags)
{
	struct dentry *xafile;
	struct file *fp;

	xafile = get_xa_file_dentry(inode, name, flags);
	if (IS_ERR(xafile))
		return ERR_PTR(PTR_ERR(xafile));
	else if (!xafile->d_inode) {
		dput(xafile);
		return ERR_PTR(-ENODATA);
	}

	fp = dentry_open(xafile, NULL, O_RDWR);
	/* dentry_open dputs the dentry if it fails */

	return fp;
}

/*
 * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but
 * we need to drop the path before calling the filldir struct.  That
 * would be a big performance hit to the non-xattr case, so I've copied
 * the whole thing for now. --clm
 *
 * the big difference is that I go backwards through the directory,
 * and don't mess with f->f_pos, but the idea is the same.  Do some
 * action on each and every entry in the directory.
 *
 * we're called with i_mutex held, so there are no worries about the directory
 * changing underneath us.
 */
static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
	struct inode *inode = filp->f_path.dentry->d_inode;
	struct cpu_key pos_key;	/* key of current position in the directory (key of directory entry) */
	INITIALIZE_PATH(path_to_entry);
	struct buffer_head *bh;
	int entry_num;
	struct item_head *ih, tmp_ih;
	int search_res;
	char *local_buf;
	loff_t next_pos;
	char small_buf[32];	/* avoid kmalloc if we can */
	struct reiserfs_de_head *deh;
	int d_reclen;
	char *d_name;
	off_t d_off;
	ino_t d_ino;
	struct reiserfs_dir_entry de;

	/* form key for search the next directory entry using f_pos field of
	   file structure */
	next_pos = max_reiserfs_offset(inode);

	while (1) {
	      research:
		if (next_pos <= DOT_DOT_OFFSET)
			break;
		make_cpu_key(&pos_key, inode, next_pos, TYPE_DIRENTRY, 3);

		search_res =
		    search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry,
					&de);
		if (search_res == IO_ERROR) {
			// FIXME: we could just skip part of directory which could
			// not be read
			pathrelse(&path_to_entry);
			return -EIO;
		}

		if (search_res == NAME_NOT_FOUND)
			de.de_entry_num--;

		set_de_name_and_namelen(&de);
		entry_num = de.de_entry_num;
		deh = &(de.de_deh[entry_num]);

		bh = de.de_bh;
		ih = de.de_ih;

		if (!is_direntry_le_ih(ih)) {
			reiserfs_warning(inode->i_sb, "not direntry %h", ih);
			break;
		}
		copy_item_head(&tmp_ih, ih);

		/* we must have found item, that is item of this directory, */
		RFALSE(COMP_SHORT_KEYS(&(ih->ih_key), &pos_key),
		       "vs-9000: found item %h does not match to dir we readdir %K",
		       ih, &pos_key);

		if (deh_offset(deh) <= DOT_DOT_OFFSET) {
			break;
		}

		/* look for the previous entry in the directory */
		next_pos = deh_offset(deh) - 1;

		if (!de_visible(deh))
			/* it is hidden entry */
			continue;

		d_reclen = entry_length(bh, ih, entry_num);
		d_name = B_I_DEH_ENTRY_FILE_NAME(bh, ih, deh);
		d_off = deh_offset(deh);
		d_ino = deh_objectid(deh);

		if (!d_name[d_reclen - 1])
			d_reclen = strlen(d_name);

		if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)) {
			/* too big to send back to VFS */
			continue;
		}

		/* Ignore the .reiserfs_priv entry */
		if (reiserfs_xattrs(inode->i_sb) &&
		    !old_format_only(inode->i_sb) &&
		    deh_objectid(deh) ==
		    le32_to_cpu(INODE_PKEY
				(REISERFS_SB(inode->i_sb)->priv_root->d_inode)->
				k_objectid))
			continue;

		if (d_reclen <= 32) {
			local_buf = small_buf;
		} else {
			local_buf = kmalloc(d_reclen, GFP_NOFS);
			if (!local_buf) {
				pathrelse(&path_to_entry);
				return -ENOMEM;
			}
			if (item_moved(&tmp_ih, &path_to_entry)) {
				kfree(local_buf);

				/* sigh, must retry.  Do this same offset again */
				next_pos = d_off;
				goto research;
			}
		}

		// Note, that we copy name to user space via temporary
		// buffer (local_buf) because filldir will block if
		// user space buffer is swapped out. At that time
		// entry can move to somewhere else
		memcpy(local_buf, d_name, d_reclen);

		/* the filldir function might need to start transactions,
		 * or do who knows what.  Release the path now that we've
		 * copied all the important stuff out of the deh
		 */
		pathrelse(&path_to_entry);

		if (filldir(dirent, local_buf, d_reclen, d_off, d_ino,
			    DT_UNKNOWN) < 0) {
			if (local_buf != small_buf) {
				kfree(local_buf);
			}
			goto end;
		}
		if (local_buf != small_buf) {
			kfree(local_buf);
		}
	}			/* while */

      end:
	pathrelse(&path_to_entry);
	return 0;
}

/*
 * this could be done with dedicated readdir ops for the xattr files,
 * but I want to get something working asap
 * this is stolen from vfs_readdir
 *
 */
static
int xattr_readdir(struct file *file, filldir_t filler, void *buf)
{
	struct inode *inode = file->f_path.dentry->d_inode;
	int res = -ENOTDIR;
	if (!file->f_op || !file->f_op->readdir)
		goto out;
	mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR);
//        down(&inode->i_zombie);
	res = -ENOENT;
	if (!IS_DEADDIR(inode)) {
		lock_kernel();
		res = __xattr_readdir(file, buf, filler);
		unlock_kernel();
	}
//        up(&inode->i_zombie);
	mutex_unlock(&inode->i_mutex);
      out:
	return res;
}

/* Internal operations on file data */
static inline void reiserfs_put_page(struct page *page)
{
	kunmap(page);
	page_cache_release(page);
}

static struct page *reiserfs_get_page(struct inode *dir, unsigned long n)
{
	struct address_space *mapping = dir->i_mapping;
	struct page *page;
	/* We can deadlock if we try to free dentries,
	   and an unlink/rmdir has just occured - GFP_NOFS avoids this */
	mapping_set_gfp_mask(mapping, GFP_NOFS);
	page = read_mapping_page(mapping, n, NULL);
	if (!IS_ERR(page)) {
		wait_on_page_locked(page);
		kmap(page);
		if (!PageUptodate(page))
			goto fail;

		if (PageError(page))
			goto fail;
	}
	return page;

      fail:
	reiserfs_put_page(page);
	return ERR_PTR(-EIO);
}

static inline __u32 xattr_hash(const char *msg, int len)
{
	return csum_partial(msg, len, 0);
}

/* Generic extended attribute operations that can be used by xa plugins */

/*
 * inode->i_mutex: down
 */
int
reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
		   size_t buffer_size, int flags)
{
	int err = 0;
	struct file *fp;
	struct page *page;
	char *data;
	struct address_space *mapping;
	size_t file_pos = 0;
	size_t buffer_pos = 0;
	struct inode *xinode;
	struct iattr newattrs;
	__u32 xahash = 0;

	if (get_inode_sd_version(inode) == STAT_DATA_V1)
		return -EOPNOTSUPP;

	/* Empty xattrs are ok, they're just empty files, no hash */
	if (buffer && buffer_size)
		xahash = xattr_hash(buffer, buffer_size);

      open_file:
	fp = open_xa_file(inode, name, flags);
	if (IS_ERR(fp)) {
		err = PTR_ERR(fp);
		goto out;
	}

	xinode = fp->f_path.dentry->d_inode;
	REISERFS_I(inode)->i_flags |= i_has_xattr_dir;

	/* we need to copy it off.. */
	if (xinode->i_nlink > 1) {
		fput(fp);
		err = reiserfs_xattr_del(inode, name);
		if (err < 0)
			goto out;
		/* We just killed the old one, we're not replacing anymore */
		if (flags & XATTR_REPLACE)
			flags &= ~XATTR_REPLACE;
		goto open_file;
	}

	/* Resize it so we're ok to write there */
	newattrs.ia_size = buffer_size;
	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
	mutex_lock(&xinode->i_mutex);
	err = notify_change(fp->f_path.dentry, &newattrs);
	if (err)
		goto out_filp;

	mapping = xinode->i_mapping;
	while (buffer_pos < buffer_size || buffer_pos == 0) {
		size_t chunk;
		size_t skip = 0;
		size_t page_offset = (file_pos & (PAGE_CACHE_SIZE - 1));
		if (buffer_size - buffer_pos > PAGE_CACHE_SIZE)
			chunk = PAGE_CACHE_SIZE;
		else
			chunk = buffer_size - buffer_pos;

		page = reiserfs_get_page(xinode, file_pos >> PAGE_CACHE_SHIFT);
		if (IS_ERR(page)) {
			err = PTR_ERR(page);
			goto out_filp;
		}

		lock_page(page);
		data = page_address(page);

		if (file_pos == 0) {
			struct reiserfs_xattr_header *rxh;
			skip = file_pos = sizeof(struct reiserfs_xattr_header);
			if (chunk + skip > PAGE_CACHE_SIZE)
				chunk = PAGE_CACHE_SIZE - skip;
			rxh = (struct reiserfs_xattr_header *)data;
			rxh->h_magic = cpu_to_le32(REISERFS_XATTR_MAGIC);
			rxh->h_hash = cpu_to_le32(xahash);
		}

		err = mapping->a_ops->prepare_write(fp, page, page_offset,
						    page_offset + chunk + skip);
		if (!err) {
			if (buffer)
				memcpy(data + skip, buffer + buffer_pos, chunk);
			err =
			    mapping->a_ops->commit_write(fp, page, page_offset,
							 page_offset + chunk +
							 skip);
		}
		unlock_page(page);
		reiserfs_put_page(page);
		buffer_pos += chunk;
		file_pos += chunk;
		skip = 0;
		if (err || buffer_size == 0 || !buffer)
			break;
	}

	/* We can't mark the inode dirty if it's not hashed. This is the case
	 * when we're inheriting the default ACL. If we dirty it, the inode
	 * gets marked dirty, but won't (ever) make it onto the dirty list until
	 * it's synced explicitly to clear I_DIRTY. This is bad. */
	if (!hlist_unhashed(&inode->i_hash)) {
		inode->i_ctime = CURRENT_TIME_SEC;
		mark_inode_dirty(inode);
	}

      out_filp:
	mutex_unlock(&xinode->i_mutex);
	fput(fp);

      out:
	return err;
}

/*
 * inode->i_mutex: down
 */
int
reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer,
		   size_t buffer_size)
{
	ssize_t err = 0;
	struct file *fp;
	size_t isize;
	size_t file_pos = 0;
	size_t buffer_pos = 0;
	struct page *page;
	struct inode *xinode;
	__u32 hash = 0;

	if (name == NULL)
		return -EINVAL;

	/* We can't have xattrs attached to v1 items since they don't have
	 * generation numbers */
	if (get_inode_sd_version(inode) == STAT_DATA_V1)
		return -EOPNOTSUPP;

	fp = open_xa_file(inode, name, FL_READONLY);
	if (IS_ERR(fp)) {
		err = PTR_ERR(fp);
		goto out;
	}

	xinode = fp->f_path.dentry->d_inode;
	isize = xinode->i_size;
	REISERFS_I(inode)->i_flags |= i_has_xattr_dir;

	/* Just return the size needed */
	if (buffer == NULL) {
		err = isize - sizeof(struct reiserfs_xattr_header);
		goto out_dput;
	}

	if (buffer_size < isize - sizeof(struct reiserfs_xattr_header)) {
		err = -ERANGE;
		goto out_dput;
	}

	while (file_pos < isize) {
		size_t chunk;
		char *data;
		size_t skip = 0;
		if (isize - file_pos > PAGE_CACHE_SIZE)
			chunk = PAGE_CACHE_SIZE;
		else
			chunk = isize - file_pos;

		page = reiserfs_get_page(xinode, file_pos >> PAGE_CACHE_SHIFT);
		if (IS_ERR(page)) {
			err = PTR_ERR(page);
			goto out_dput;
		}

		lock_page(page);
		data = page_address(page);
		if (file_pos == 0) {
			struct reiserfs_xattr_header *rxh =
			    (struct reiserfs_xattr_header *)data;
			skip = file_pos = sizeof(struct reiserfs_xattr_header);
			chunk -= skip;
			/* Magic doesn't match up.. */
			if (rxh->h_magic != cpu_to_le32(REISERFS_XATTR_MAGIC)) {
				unlock_page(page);
				reiserfs_put_page(page);
				reiserfs_warning(inode->i_sb,
						 "Invalid magic for xattr (%s) "
						 "associated with %k", name,
						 INODE_PKEY(inode));
				err = -EIO;
				goto out_dput;
			}
			hash = le32_to_cpu(rxh->h_hash);
		}
		memcpy(buffer + buffer_pos, data + skip, chunk);
		unlock_page(page);
		reiserfs_put_page(page);
		file_pos += chunk;
		buffer_pos += chunk;
		skip = 0;
	}
	err = isize - sizeof(struct reiserfs_xattr_header);

	if (xattr_hash(buffer, isize - sizeof(struct reiserfs_xattr_header)) !=
	    hash) {
		reiserfs_warning(inode->i_sb,
				 "Invalid hash for xattr (%s) associated "
				 "with %k", name, INODE_PKEY(inode));
		err = -EIO;
	}

      out_dput:
	fput(fp);

      out:
	return err;
}

static int
__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen)
{
	struct dentry *dentry;
	struct inode *dir = xadir->d_inode;
	int err = 0;

	dentry = lookup_one_len(name, xadir, namelen);
	if (IS_ERR(dentry)) {
		err = PTR_ERR(dentry);
		goto out;
	} else if (!dentry->d_inode) {
		err = -ENODATA;
		goto out_file;
	}

	/* Skip directories.. */
	if (S_ISDIR(dentry->d_inode->i_mode))
		goto out_file;

	if (!is_reiserfs_priv_object(dentry->d_inode)) {
		reiserfs_warning(dir->i_sb, "OID %08x [%.*s/%.*s] doesn't have "
				 "priv flag set [parent is %sset].",
				 le32_to_cpu(INODE_PKEY(dentry->d_inode)->
					     k_objectid), xadir->d_name.len,
				 xadir->d_name.name, namelen, name,
				 is_reiserfs_priv_object(xadir->
							 d_inode) ? "" :
				 "not ");
		dput(dentry);
		return -EIO;
	}

	err = dir->i_op->unlink(dir, dentry);
	if (!err)
		d_delete(dentry);

      out_file:
	dput(dentry);

      out:
	return err;
}

int reiserfs_xattr_del(struct inode *inode, const char *name)
{
	struct dentry *dir;
	int err;

	dir = open_xa_dir(inode, FL_READONLY);
	if (IS_ERR(dir)) {
		err = PTR_ERR(dir);
		goto out;
	}

	err = __reiserfs_xattr_del(dir, name, strlen(name));
	dput(dir);

	if (!err) {
		inode->i_ctime = CURRENT_TIME_SEC;
		mark_inode_dirty(inode);
	}

      out:
	return err;
}

/* The following are side effects of other operations that aren't explicitly
 * modifying extended attributes. This includes operations such as permissions
 * or ownership changes, object deletions, etc. */

static int
reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
			      loff_t offset, u64 ino, unsigned int d_type)
{
	struct dentry *xadir = (struct dentry *)buf;

	return __reiserfs_xattr_del(xadir, name, namelen);

}

/* This is called w/ inode->i_mutex downed */
int reiserfs_delete_xattrs(struct inode *inode)
{
	struct file *fp;
	struct dentry *dir, *root;
	int err = 0;

	/* Skip out, an xattr has no xattrs associated with it */
	if (is_reiserfs_priv_object(inode) ||
	    get_inode_sd_version(inode) == STAT_DATA_V1 ||
	    !reiserfs_xattrs(inode->i_sb)) {
		return 0;
	}
	reiserfs_read_lock_xattrs(inode->i_sb);
	dir = open_xa_dir(inode, FL_READONLY);
	reiserfs_read_unlock_xattrs(inode->i_sb);
	if (IS_ERR(dir)) {
		err = PTR_ERR(dir);
		goto out;
	} else if (!dir->d_inode) {
		dput(dir);
		return 0;
	}

	fp = dentry_open(dir, NULL, O_RDWR);
	if (IS_ERR(fp)) {
		err = PTR_ERR(fp);
		/* dentry_open dputs the dentry if it fails */
		goto out;
	}

	lock_kernel();
	err = xattr_readdir(fp, reiserfs_delete_xattrs_filler, dir);
	if (err) {
		unlock_kernel();
		goto out_dir;
	}

	/* Leftovers besides . and .. -- that's not good. */
	if (dir->d_inode->i_nlink <= 2) {
		root = get_xa_root(inode->i_sb);
		reiserfs_write_lock_xattrs(inode->i_sb);
		err = vfs_rmdir(root->d_inode, dir);
		reiserfs_write_unlock_xattrs(inode->i_sb);
		dput(root);
	} else {
		reiserfs_warning(inode->i_sb,
				 "Couldn't remove all entries in directory");
	}
	unlock_kernel();

      out_dir:
	fput(fp);

      out:
	if (!err)
		REISERFS_I(inode)->i_flags =
		    REISERFS_I(inode)->i_flags & ~i_has_xattr_dir;
	return err;
}

struct reiserfs_chown_buf {
	struct inode *inode;
	struct dentry *xadir;
	struct iattr *attrs;
};

/* XXX: If there is a better way to do this, I'd love to hear about it */
static int
reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
			     loff_t offset, u64 ino, unsigned int d_type)
{
	struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
	struct dentry *xafile, *xadir = chown_buf->xadir;
	struct iattr *attrs = chown_buf->attrs;
	int err = 0;

	xafile = lookup_one_len(name, xadir, namelen);
	if (IS_ERR(xafile))
		return PTR_ERR(xafile);
	else if (!xafile->d_inode) {
		dput(xafile);
		return -ENODATA;
	}

	if (!S_ISDIR(xafile->d_inode->i_mode))
		err = notify_change(xafile, attrs);
	dput(xafile);

	return err;
}

int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
{
	struct file *fp;
	struct dentry *dir;
	int err = 0;
	struct reiserfs_chown_buf buf;
	unsigned int ia_valid = attrs->ia_valid;

	/* Skip out, an xattr has no xattrs associated with it */
	if (is_reiserfs_priv_object(inode) ||
	    get_inode_sd_version(inode) == STAT_DATA_V1 ||
	    !reiserfs_xattrs(inode->i_sb)) {
		return 0;
	}
	reiserfs_read_lock_xattrs(inode->i_sb);
	dir = open_xa_dir(inode, FL_READONLY);
	reiserfs_read_unlock_xattrs(inode->i_sb);
	if (IS_ERR(dir)) {
		if (PTR_ERR(dir) != -ENODATA)
			err = PTR_ERR(dir);
		goto out;
	} else if (!dir->d_inode) {
		dput(dir);
		goto out;
	}

	fp = dentry_open(dir, NULL, O_RDWR);
	if (IS_ERR(fp)) {
		err = PTR_ERR(fp);
		/* dentry_open dputs the dentry if it fails */
		goto out;
	}

	lock_kernel();

	attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
	buf.xadir = dir;
	buf.attrs = attrs;
	buf.inode = inode;

	err = xattr_readdir(fp, reiserfs_chown_xattrs_filler, &buf);
	if (err) {
		unlock_kernel();
		goto out_dir;
	}

	err = notify_change(dir, attrs);
	unlock_kernel();

      out_dir:
	fput(fp);

      out:
	attrs->ia_valid = ia_valid;
	return err;
}

/* Actual operations that are exported to VFS-land */

/*
 * Inode operation getxattr()
 * Preliminary locking: we down dentry->d_inode->i_mutex
 */
ssize_t
reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer,
		  size_t size)
{
	struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name);
	int err;

	if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
		return -EOPNOTSUPP;

	reiserfs_read_lock_xattr_i(dentry->d_inode);
	reiserfs_read_lock_xattrs(dentry->d_sb);
	err = xah->get(dentry->d_inode, name, buffer, size);
	reiserfs_read_unlock_xattrs(dentry->d_sb);
	reiserfs_read_unlock_xattr_i(dentry->d_inode);
	return err;
}

/*
 * Inode operation setxattr()
 *
 * dentry->d_inode->i_mutex down
 */
int
reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
		  size_t size, int flags)
{
	struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name);
	int err;
	int lock;

	if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
		return -EOPNOTSUPP;

	reiserfs_write_lock_xattr_i(dentry->d_inode);
	lock = !has_xattr_dir(dentry->d_inode);
	if (lock)
		reiserfs_write_lock_xattrs(dentry->d_sb);
	else
		reiserfs_read_lock_xattrs(dentry->d_sb);
	err = xah->set(dentry->d_inode, name, value, size, flags);
	if (lock)
		reiserfs_write_unlock_xattrs(dentry->d_sb);
	else
		reiserfs_read_unlock_xattrs(dentry->d_sb);
	reiserfs_write_unlock_xattr_i(dentry->d_inode);
	return err;
}

/*
 * Inode operation removexattr()
 *
 * dentry->d_inode->i_mutex down
 */
int reiserfs_removexattr(struct dentry *dentry, const char *name)
{
	int err;
	struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name);

	if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
		return -EOPNOTSUPP;

	reiserfs_write_lock_xattr_i(dentry->d_inode);
	reiserfs_read_lock_xattrs(dentry->d_sb);

	/* Deletion pre-operation */
	if (xah->del) {
		err = xah->del(dentry->d_inode, name);
		if (err)
			goto out;
	}

	err = reiserfs_xattr_del(dentry->d_inode, name);

	dentry->d_inode->i_ctime = CURRENT_TIME_SEC;
	mark_inode_dirty(dentry->d_inode);

      out:
	reiserfs_read_unlock_xattrs(dentry->d_sb);
	reiserfs_write_unlock_xattr_i(dentry->d_inode);
	return err;
}

/* This is what filldir will use:
 * r_pos will always contain the amount of space required for the entire
 * list. If r_pos becomes larger than r_size, we need more space and we
 * return an error indicating this. If r_pos is less than r_size, then we've
 * filled the buffer successfully and we return success */
struct reiserfs_listxattr_buf {
	int r_pos;
	int r_size;
	char *r_buf;
	struct inode *r_inode;
};

static int
reiserfs_listxattr_filler(void *buf, const char *name, int namelen,
			  loff_t offset, u64 ino, unsigned int d_type)
{
	struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
	int len = 0;
	if (name[0] != '.'
	    || (namelen != 1 && (name[1] != '.' || namelen != 2))) {
		struct reiserfs_xattr_handler *xah =
		    find_xattr_handler_prefix(name);
		if (!xah)
			return 0;	/* Unsupported xattr name, skip it */

		/* We call ->list() twice because the operation isn't required to just
		 * return the name back - we want to make sure we have enough space */
		len += xah->list(b->r_inode, name, namelen, NULL);

		if (len) {
			if (b->r_pos + len + 1 <= b->r_size) {
				char *p = b->r_buf + b->r_pos;
				p += xah->list(b->r_inode, name, namelen, p);
				*p++ = '\0';
			}
			b->r_pos += len + 1;
		}
	}

	return 0;
}

/*
 * Inode operation listxattr()
 *
 * Preliminary locking: we down dentry->d_inode->i_mutex
 */
ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
{
	struct file *fp;
	struct dentry *dir;
	int err = 0;
	struct reiserfs_listxattr_buf buf;

	if (!dentry->d_inode)
		return -EINVAL;

	if (!reiserfs_xattrs(dentry->d_sb) ||
	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
		return -EOPNOTSUPP;

	reiserfs_read_lock_xattr_i(dentry->d_inode);
	reiserfs_read_lock_xattrs(dentry->d_sb);
	dir = open_xa_dir(dentry->d_inode, FL_READONLY);
	reiserfs_read_unlock_xattrs(dentry->d_sb);
	if (IS_ERR(dir)) {
		err = PTR_ERR(dir);
		if (err == -ENODATA)
			err = 0;	/* Not an error if there aren't any xattrs */
		goto out;
	}

	fp = dentry_open(dir, NULL, O_RDWR);
	if (IS_ERR(fp)) {
		err = PTR_ERR(fp);
		/* dentry_open dputs the dentry if it fails */
		goto out;
	}

	buf.r_buf = buffer;
	buf.r_size = buffer ? size : 0;
	buf.r_pos = 0;
	buf.r_inode = dentry->d_inode;

	REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir;

	err = xattr_readdir(fp, reiserfs_listxattr_filler, &buf);
	if (err)
		goto out_dir;

	if (buf.r_pos > buf.r_size && buffer != NULL)
		err = -ERANGE;
	else
		err = buf.r_pos;

      out_dir:
	fput(fp);

      out:
	reiserfs_read_unlock_xattr_i(dentry->d_inode);
	return err;
}

/* This is the implementation for the xattr plugin infrastructure */
static struct list_head xattr_handlers = LIST_HEAD_INIT(xattr_handlers);
static DEFINE_RWLOCK(handler_lock);

static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
								*prefix)
{
	struct reiserfs_xattr_handler *xah = NULL;
	struct list_head *p;

	read_lock(&handler_lock);
	list_for_each(p, &xattr_handlers) {
		xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
		if (strncmp(xah->prefix, prefix, strlen(xah->prefix)) == 0)
			break;
		xah = NULL;
	}

	read_unlock(&handler_lock);
	return xah;
}

static void __unregister_handlers(void)
{
	struct reiserfs_xattr_handler *xah;
	struct list_head *p, *tmp;

	list_for_each_safe(p, tmp, &xattr_handlers) {
		xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
		if (xah->exit)
			xah->exit();

		list_del_init(p);
	}
	INIT_LIST_HEAD(&xattr_handlers);
}

int __init reiserfs_xattr_register_handlers(void)
{
	int err = 0;
	struct reiserfs_xattr_handler *xah;
	struct list_head *p;

	write_lock(&handler_lock);

	/* If we're already initialized, nothing to do */
	if (!list_empty(&xattr_handlers)) {
		write_unlock(&handler_lock);
		return 0;
	}

	/* Add the handlers */
	list_add_tail(&user_handler.handlers, &xattr_handlers);
	list_add_tail(&trusted_handler.handlers, &xattr_handlers);
#ifdef CONFIG_REISERFS_FS_SECURITY
	list_add_tail(&security_handler.handlers, &xattr_handlers);
#endif
#ifdef CONFIG_REISERFS_FS_POSIX_ACL
	list_add_tail(&posix_acl_access_handler.handlers, &xattr_handlers);
	list_add_tail(&posix_acl_default_handler.handlers, &xattr_handlers);
#endif

	/* Run initializers, if available */
	list_for_each(p, &xattr_handlers) {
		xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
		if (xah->init) {
			err = xah->init();
			if (err) {
				list_del_init(p);
				break;
			}
		}
	}

	/* Clean up other handlers, if any failed */
	if (err)
		__unregister_handlers();

	write_unlock(&handler_lock);
	return err;
}

void reiserfs_xattr_unregister_handlers(void)
{
	write_lock(&handler_lock);
	__unregister_handlers();
	write_unlock(&handler_lock);
}

/* This will catch lookups from the fs root to .reiserfs_priv */
static int
xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
{
	struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root;
	if (name->len == priv_root->d_name.len &&
	    name->hash == priv_root->d_name.hash &&
	    !memcmp(name->name, priv_root->d_name.name, name->len)) {
		return -ENOENT;
	} else if (q1->len == name->len &&
		   !memcmp(q1->name, name->name, name->len))
		return 0;
	return 1;
}

static struct dentry_operations xattr_lookup_poison_ops = {
	.d_compare = xattr_lookup_poison,
};

/* We need to take a copy of the mount flags since things like
 * MS_RDONLY don't get set until *after* we're called.
 * mount_flags != mount_options */
int reiserfs_xattr_init(struct super_block *s, int mount_flags)
{
	int err = 0;

	/* We need generation numbers to ensure that the oid mapping is correct
	 * v3.5 filesystems don't have them. */
	if (!old_format_only(s)) {
		set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
	} else if (reiserfs_xattrs_optional(s)) {
		/* Old format filesystem, but optional xattrs have been enabled
		 * at mount time. Error out. */
		reiserfs_warning(s, "xattrs/ACLs not supported on pre v3.6 "
				 "format filesystem. Failing mount.");
		err = -EOPNOTSUPP;
		goto error;
	} else {
		/* Old format filesystem, but no optional xattrs have been enabled. This
		 * means we silently disable xattrs on the filesystem. */
		clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
	}

	/* If we don't have the privroot located yet - go find it */
	if (reiserfs_xattrs(s) && !REISERFS_SB(s)->priv_root) {
		struct dentry *dentry;
		dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
					strlen(PRIVROOT_NAME));
		if (!IS_ERR(dentry)) {
			if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {
				struct inode *inode = dentry->d_parent->d_inode;
				mutex_lock(&inode->i_mutex);
				err = inode->i_op->mkdir(inode, dentry, 0700);
				mutex_unlock(&inode->i_mutex);
				if (err) {
					dput(dentry);
					dentry = NULL;
				}

				if (dentry && dentry->d_inode)
					reiserfs_warning(s,
							 "Created %s on %s - reserved for "
							 "xattr storage.",
							 PRIVROOT_NAME,
							 reiserfs_bdevname
							 (inode->i_sb));
			} else if (!dentry->d_inode) {
				dput(dentry);
				dentry = NULL;
			}
		} else
			err = PTR_ERR(dentry);

		if (!err && dentry) {
			s->s_root->d_op = &xattr_lookup_poison_ops;
			reiserfs_mark_inode_private(dentry->d_inode);
			REISERFS_SB(s)->priv_root = dentry;
		} else if (!(mount_flags & MS_RDONLY)) {	/* xattrs are unavailable */
			/* If we're read-only it just means that the dir hasn't been
			 * created. Not an error -- just no xattrs on the fs. We'll
			 * check again if we go read-write */
			reiserfs_warning(s, "xattrs/ACLs enabled and couldn't "
					 "find/create .reiserfs_priv. Failing mount.");
			err = -EOPNOTSUPP;
		}
	}

      error:
	/* This is only nonzero if there was an error initializing the xattr
	 * directory or if there is a condition where we don't support them. */
	if (err) {
		clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
		clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt));
		clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt));
	}

	/* The super_block MS_POSIXACL must mirror the (no)acl mount option. */
	s->s_flags = s->s_flags & ~MS_POSIXACL;
	if (reiserfs_posixacl(s))
		s->s_flags |= MS_POSIXACL;

	return err;
}

static int reiserfs_check_acl(struct inode *inode, int mask)
{
	struct posix_acl *acl;
	int error = -EAGAIN; /* do regular unix permission checks by default */

	reiserfs_read_lock_xattr_i(inode);
	reiserfs_read_lock_xattrs(inode->i_sb);

	acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);

	reiserfs_read_unlock_xattrs(inode->i_sb);
	reiserfs_read_unlock_xattr_i(inode);

	if (acl) {
		if (!IS_ERR(acl)) {
			error = posix_acl_permission(inode, acl, mask);
			posix_acl_release(acl);
		} else if (PTR_ERR(acl) != -ENODATA)
			error = PTR_ERR(acl);
	}

	return error;
}

int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd)
{
	/*
	 * We don't do permission checks on the internal objects.
	 * Permissions are determined by the "owning" object.
	 */
	if (is_reiserfs_priv_object(inode))
		return 0;

	/*
	 * Stat data v1 doesn't support ACLs.
	 */
	if (get_inode_sd_version(inode) == STAT_DATA_V1)
		return generic_permission(inode, mask, NULL);
	else
		return generic_permission(inode, mask, reiserfs_check_acl);
}
