/*
 * 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);

/* Returns the dentry referring to the root of the extended attribute
 * directory tree. If it has already been retrieved, it is used. If it
 * hasn't been created and the flags indicate creation is allowed, we
 * attempt to create it. On error, we return a pointer-encoded error.
 */
static struct dentry *get_xa_root(struct super_block *sb, int flags)
{
	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(-ENODATA);

	mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR);
	if (REISERFS_SB(sb)->xattr_root) {
		xaroot = dget(REISERFS_SB(sb)->xattr_root);
		goto out;
	}

	xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME));
	if (IS_ERR(xaroot)) {
		goto out;
	} else if (!xaroot->d_inode) {
		int err = -ENODATA;
		if (flags == 0 || flags & XATTR_CREATE)
			err = privroot->d_inode->i_op->mkdir(privroot->d_inode,
			                                     xaroot, 0700);
		if (err) {
			dput(xaroot);
			xaroot = ERR_PTR(err);
			goto out;
		}
	}
	REISERFS_SB(sb)->xattr_root = dget(xaroot);

      out:
	mutex_unlock(&privroot->d_inode->i_mutex);
	dput(privroot);
	return xaroot;
}

/* 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, flags);
	if (IS_ERR(xaroot))
		return xaroot;

	/* 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)) {
		kmap(page);
		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, XATTR_REPLACE);
		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);
}
