/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License version 2.
 */

#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/capability.h>
#include <linux/xattr.h>
#include <linux/gfs2_ondisk.h>
#include <linux/lm_interface.h>
#include <asm/uaccess.h>

#include "gfs2.h"
#include "incore.h"
#include "acl.h"
#include "eaops.h"
#include "eattr.h"
#include "util.h"

/**
 * gfs2_ea_name2type - get the type of the ea, and truncate type from the name
 * @namep: ea name, possibly with type appended
 *
 * Returns: GFS2_EATYPE_XXX
 */

unsigned int gfs2_ea_name2type(const char *name, const char **truncated_name)
{
	unsigned int type;

	if (strncmp(name, "system.", 7) == 0) {
		type = GFS2_EATYPE_SYS;
		if (truncated_name)
			*truncated_name = name + sizeof("system.") - 1;
	} else if (strncmp(name, "user.", 5) == 0) {
		type = GFS2_EATYPE_USR;
		if (truncated_name)
			*truncated_name = name + sizeof("user.") - 1;
	} else if (strncmp(name, "security.", 9) == 0) {
		type = GFS2_EATYPE_SECURITY;
		if (truncated_name)
			*truncated_name = name + sizeof("security.") - 1;
	} else {
		type = GFS2_EATYPE_UNUSED;
		if (truncated_name)
			*truncated_name = NULL;
	}

	return type;
}

static int system_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
{
	if (!GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) &&
	    !GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len) &&
	    !capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl == 0 &&
	    (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) ||
	     GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)))
		return -EOPNOTSUPP;

	return gfs2_ea_get_i(ip, er);
}

static int system_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
{
	int remove = 0;
	int error;

	if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) {
		if (!(er->er_flags & GFS2_ERF_MODE)) {
			er->er_mode = ip->i_inode.i_mode;
			er->er_flags |= GFS2_ERF_MODE;
		}
		error = gfs2_acl_validate_set(ip, 1, er,
					      &remove, &er->er_mode);
		if (error)
			return error;
		error = gfs2_ea_set_i(ip, er);
		if (error)
			return error;
		if (remove)
			gfs2_ea_remove_i(ip, er);
		return 0;

	} else if (GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) {
		error = gfs2_acl_validate_set(ip, 0, er,
					      &remove, NULL);
		if (error)
			return error;
		if (!remove)
			error = gfs2_ea_set_i(ip, er);
		else {
			error = gfs2_ea_remove_i(ip, er);
			if (error == -ENODATA)
				error = 0;
		}
		return error;
	}

	return -EPERM;
}

static int system_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
{
	if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) {
		int error = gfs2_acl_validate_remove(ip, 1);
		if (error)
			return error;

	} else if (GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) {
		int error = gfs2_acl_validate_remove(ip, 0);
		if (error)
			return error;

	} else
		return -EPERM;

	return gfs2_ea_remove_i(ip, er);
}

static const struct gfs2_eattr_operations gfs2_user_eaops = {
	.eo_get = gfs2_ea_get_i,
	.eo_set = gfs2_ea_set_i,
	.eo_remove = gfs2_ea_remove_i,
	.eo_name = "user",
};

const struct gfs2_eattr_operations gfs2_system_eaops = {
	.eo_get = system_eo_get,
	.eo_set = system_eo_set,
	.eo_remove = system_eo_remove,
	.eo_name = "system",
};

static const struct gfs2_eattr_operations gfs2_security_eaops = {
	.eo_get = gfs2_ea_get_i,
	.eo_set = gfs2_ea_set_i,
	.eo_remove = gfs2_ea_remove_i,
	.eo_name = "security",
};

const struct gfs2_eattr_operations *gfs2_ea_ops[] = {
	NULL,
	&gfs2_user_eaops,
	&gfs2_system_eaops,
	&gfs2_security_eaops,
};

