/*
 * 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/gfs2_ondisk.h>
#include <linux/lm_interface.h>
#include <linux/parser.h>

#include "gfs2.h"
#include "incore.h"
#include "mount.h"
#include "sys.h"
#include "util.h"

enum {
	Opt_lockproto,
	Opt_locktable,
	Opt_hostdata,
	Opt_spectator,
	Opt_ignore_local_fs,
	Opt_localflocks,
	Opt_localcaching,
	Opt_debug,
	Opt_nodebug,
	Opt_upgrade,
	Opt_acl,
	Opt_noacl,
	Opt_quota_off,
	Opt_quota_account,
	Opt_quota_on,
	Opt_suiddir,
	Opt_nosuiddir,
	Opt_data_writeback,
	Opt_data_ordered,
	Opt_meta,
	Opt_err,
};

static const match_table_t tokens = {
	{Opt_lockproto, "lockproto=%s"},
	{Opt_locktable, "locktable=%s"},
	{Opt_hostdata, "hostdata=%s"},
	{Opt_spectator, "spectator"},
	{Opt_ignore_local_fs, "ignore_local_fs"},
	{Opt_localflocks, "localflocks"},
	{Opt_localcaching, "localcaching"},
	{Opt_debug, "debug"},
	{Opt_nodebug, "nodebug"},
	{Opt_upgrade, "upgrade"},
	{Opt_acl, "acl"},
	{Opt_noacl, "noacl"},
	{Opt_quota_off, "quota=off"},
	{Opt_quota_account, "quota=account"},
	{Opt_quota_on, "quota=on"},
	{Opt_suiddir, "suiddir"},
	{Opt_nosuiddir, "nosuiddir"},
	{Opt_data_writeback, "data=writeback"},
	{Opt_data_ordered, "data=ordered"},
	{Opt_meta, "meta"},
	{Opt_err, NULL}
};

/**
 * gfs2_mount_args - Parse mount options
 * @sdp:
 * @data:
 *
 * Return: errno
 */

int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
{
	struct gfs2_args *args = &sdp->sd_args;
	char *data = data_arg;
	char *options, *o, *v;
	int error = 0;

	if (!remount) {
		/*  Set some defaults  */
		args->ar_quota = GFS2_QUOTA_DEFAULT;
		args->ar_data = GFS2_DATA_DEFAULT;
	}

	/* Split the options into tokens with the "," character and
	   process them */

	for (options = data; (o = strsep(&options, ",")); ) {
		int token;
		substring_t tmp[MAX_OPT_ARGS];

		if (!*o)
			continue;

		token = match_token(o, tokens, tmp);
		switch (token) {
		case Opt_lockproto:
			v = match_strdup(&tmp[0]);
			if (!v) {
				fs_info(sdp, "no memory for lockproto\n");
				error = -ENOMEM;
				goto out_error;
			}

			if (remount && strcmp(v, args->ar_lockproto)) {
				kfree(v);
				goto cant_remount;
			}
			
			strncpy(args->ar_lockproto, v, GFS2_LOCKNAME_LEN);
			args->ar_lockproto[GFS2_LOCKNAME_LEN - 1] = 0;
			kfree(v);
			break;
		case Opt_locktable:
			v = match_strdup(&tmp[0]);
			if (!v) {
				fs_info(sdp, "no memory for locktable\n");
				error = -ENOMEM;
				goto out_error;
			}

			if (remount && strcmp(v, args->ar_locktable)) {
				kfree(v);
				goto cant_remount;
			}

			strncpy(args->ar_locktable, v, GFS2_LOCKNAME_LEN);
			args->ar_locktable[GFS2_LOCKNAME_LEN - 1]  = 0;
			kfree(v);
			break;
		case Opt_hostdata:
			v = match_strdup(&tmp[0]);
			if (!v) {
				fs_info(sdp, "no memory for hostdata\n");
				error = -ENOMEM;
				goto out_error;
			}

			if (remount && strcmp(v, args->ar_hostdata)) {
				kfree(v);
				goto cant_remount;
			}

			strncpy(args->ar_hostdata, v, GFS2_LOCKNAME_LEN);
			args->ar_hostdata[GFS2_LOCKNAME_LEN - 1] = 0;
			kfree(v);
			break;
		case Opt_spectator:
			if (remount && !args->ar_spectator)
				goto cant_remount;
			args->ar_spectator = 1;
			sdp->sd_vfs->s_flags |= MS_RDONLY;
			break;
		case Opt_ignore_local_fs:
			if (remount && !args->ar_ignore_local_fs)
				goto cant_remount;
			args->ar_ignore_local_fs = 1;
			break;
		case Opt_localflocks:
			if (remount && !args->ar_localflocks)
				goto cant_remount;
			args->ar_localflocks = 1;
			break;
		case Opt_localcaching:
			if (remount && !args->ar_localcaching)
				goto cant_remount;
			args->ar_localcaching = 1;
			break;
		case Opt_debug:
			args->ar_debug = 1;
			break;
		case Opt_nodebug:
			args->ar_debug = 0;
			break;
		case Opt_upgrade:
			if (remount && !args->ar_upgrade)
				goto cant_remount;
			args->ar_upgrade = 1;
			break;
		case Opt_acl:
			args->ar_posix_acl = 1;
			sdp->sd_vfs->s_flags |= MS_POSIXACL;
			break;
		case Opt_noacl:
			args->ar_posix_acl = 0;
			sdp->sd_vfs->s_flags &= ~MS_POSIXACL;
			break;
		case Opt_quota_off:
			args->ar_quota = GFS2_QUOTA_OFF;
			break;
		case Opt_quota_account:
			args->ar_quota = GFS2_QUOTA_ACCOUNT;
			break;
		case Opt_quota_on:
			args->ar_quota = GFS2_QUOTA_ON;
			break;
		case Opt_suiddir:
			args->ar_suiddir = 1;
			break;
		case Opt_nosuiddir:
			args->ar_suiddir = 0;
			break;
		case Opt_data_writeback:
			args->ar_data = GFS2_DATA_WRITEBACK;
			break;
		case Opt_data_ordered:
			args->ar_data = GFS2_DATA_ORDERED;
			break;
		case Opt_meta:
			if (remount && args->ar_meta != 1)
				goto cant_remount;
			args->ar_meta = 1;
			break;
		case Opt_err:
		default:
			fs_info(sdp, "unknown option: %s\n", o);
			error = -EINVAL;
			goto out_error;
		}
	}

out_error:
	if (error)
		fs_info(sdp, "invalid mount option(s)\n");

	if (data != data_arg)
		kfree(data);

	return error;

cant_remount:
	fs_info(sdp, "can't remount with option %s\n", o);
	return -EINVAL;
}

