/* -*- mode: c; c-basic-offset: 8; -*-
 * vim: noexpandtab sw=8 ts=8 sts=0:
 *
 * filecheck.c
 *
 * Code which implements online file check.
 *
 * Copyright (C) 2016 SuSE.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation, version 2.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/kmod.h>
#include <linux/fs.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/sysctl.h>
#include <cluster/masklog.h>

#include "ocfs2.h"
#include "ocfs2_fs.h"
#include "stackglue.h"
#include "inode.h"

#include "filecheck.h"


/* File check error strings,
 * must correspond with error number in header file.
 */
static const char * const ocfs2_filecheck_errs[] = {
	"SUCCESS",
	"FAILED",
	"INPROGRESS",
	"READONLY",
	"INJBD",
	"INVALIDINO",
	"BLOCKECC",
	"BLOCKNO",
	"VALIDFLAG",
	"GENERATION",
	"UNSUPPORTED"
};

static DEFINE_SPINLOCK(ocfs2_filecheck_sysfs_lock);
static LIST_HEAD(ocfs2_filecheck_sysfs_list);

struct ocfs2_filecheck {
	struct list_head fc_head;	/* File check entry list head */
	spinlock_t fc_lock;
	unsigned int fc_max;	/* Maximum number of entry in list */
	unsigned int fc_size;	/* Current entry count in list */
	unsigned int fc_done;	/* Finished entry count in list */
};

struct ocfs2_filecheck_sysfs_entry {	/* sysfs entry per mounting */
	struct list_head fs_list;
	atomic_t fs_count;
	struct super_block *fs_sb;
	struct kset *fs_devicekset;
	struct kset *fs_fcheckkset;
	struct ocfs2_filecheck *fs_fcheck;
};

#define OCFS2_FILECHECK_MAXSIZE		100
#define OCFS2_FILECHECK_MINSIZE		10

/* File check operation type */
enum {
	OCFS2_FILECHECK_TYPE_CHK = 0,	/* Check a file(inode) */
	OCFS2_FILECHECK_TYPE_FIX,	/* Fix a file(inode) */
	OCFS2_FILECHECK_TYPE_SET = 100	/* Set entry list maximum size */
};

struct ocfs2_filecheck_entry {
	struct list_head fe_list;
	unsigned long fe_ino;
	unsigned int fe_type;
	unsigned int fe_done:1;
	unsigned int fe_status:31;
};

struct ocfs2_filecheck_args {
	unsigned int fa_type;
	union {
		unsigned long fa_ino;
		unsigned int fa_len;
	};
};

static const char *
ocfs2_filecheck_error(int errno)
{
	if (!errno)
		return ocfs2_filecheck_errs[errno];

	BUG_ON(errno < OCFS2_FILECHECK_ERR_START ||
	       errno > OCFS2_FILECHECK_ERR_END);
	return ocfs2_filecheck_errs[errno - OCFS2_FILECHECK_ERR_START + 1];
}

static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
				    struct kobj_attribute *attr,
				    char *buf);
static ssize_t ocfs2_filecheck_store(struct kobject *kobj,
				     struct kobj_attribute *attr,
				     const char *buf, size_t count);
static struct kobj_attribute ocfs2_attr_filecheck_chk =
					__ATTR(check, S_IRUSR | S_IWUSR,
					ocfs2_filecheck_show,
					ocfs2_filecheck_store);
static struct kobj_attribute ocfs2_attr_filecheck_fix =
					__ATTR(fix, S_IRUSR | S_IWUSR,
					ocfs2_filecheck_show,
					ocfs2_filecheck_store);
static struct kobj_attribute ocfs2_attr_filecheck_set =
					__ATTR(set, S_IRUSR | S_IWUSR,
					ocfs2_filecheck_show,
					ocfs2_filecheck_store);

static int ocfs2_filecheck_sysfs_wait(atomic_t *p)
{
	schedule();
	return 0;
}

static void
ocfs2_filecheck_sysfs_free(struct ocfs2_filecheck_sysfs_entry *entry)
{
	struct ocfs2_filecheck_entry *p;

	if (!atomic_dec_and_test(&entry->fs_count))
		wait_on_atomic_t(&entry->fs_count, ocfs2_filecheck_sysfs_wait,
				 TASK_UNINTERRUPTIBLE);

	spin_lock(&entry->fs_fcheck->fc_lock);
	while (!list_empty(&entry->fs_fcheck->fc_head)) {
		p = list_first_entry(&entry->fs_fcheck->fc_head,
				     struct ocfs2_filecheck_entry, fe_list);
		list_del(&p->fe_list);
		BUG_ON(!p->fe_done); /* To free a undone file check entry */
		kfree(p);
	}
	spin_unlock(&entry->fs_fcheck->fc_lock);

	kset_unregister(entry->fs_fcheckkset);
	kset_unregister(entry->fs_devicekset);
	kfree(entry->fs_fcheck);
	kfree(entry);
}

static void
ocfs2_filecheck_sysfs_add(struct ocfs2_filecheck_sysfs_entry *entry)
{
	spin_lock(&ocfs2_filecheck_sysfs_lock);
	list_add_tail(&entry->fs_list, &ocfs2_filecheck_sysfs_list);
	spin_unlock(&ocfs2_filecheck_sysfs_lock);
}

static int ocfs2_filecheck_sysfs_del(const char *devname)
{
	struct ocfs2_filecheck_sysfs_entry *p;

	spin_lock(&ocfs2_filecheck_sysfs_lock);
	list_for_each_entry(p, &ocfs2_filecheck_sysfs_list, fs_list) {
		if (!strcmp(p->fs_sb->s_id, devname)) {
			list_del(&p->fs_list);
			spin_unlock(&ocfs2_filecheck_sysfs_lock);
			ocfs2_filecheck_sysfs_free(p);
			return 0;
		}
	}
	spin_unlock(&ocfs2_filecheck_sysfs_lock);
	return 1;
}

static void
ocfs2_filecheck_sysfs_put(struct ocfs2_filecheck_sysfs_entry *entry)
{
	if (atomic_dec_and_test(&entry->fs_count))
		wake_up_atomic_t(&entry->fs_count);
}

static struct ocfs2_filecheck_sysfs_entry *
ocfs2_filecheck_sysfs_get(const char *devname)
{
	struct ocfs2_filecheck_sysfs_entry *p = NULL;

	spin_lock(&ocfs2_filecheck_sysfs_lock);
	list_for_each_entry(p, &ocfs2_filecheck_sysfs_list, fs_list) {
		if (!strcmp(p->fs_sb->s_id, devname)) {
			atomic_inc(&p->fs_count);
			spin_unlock(&ocfs2_filecheck_sysfs_lock);
			return p;
		}
	}
	spin_unlock(&ocfs2_filecheck_sysfs_lock);
	return NULL;
}

int ocfs2_filecheck_create_sysfs(struct super_block *sb)
{
	int ret = 0;
	struct kset *device_kset = NULL;
	struct kset *fcheck_kset = NULL;
	struct ocfs2_filecheck *fcheck = NULL;
	struct ocfs2_filecheck_sysfs_entry *entry = NULL;
	struct attribute **attrs = NULL;
	struct attribute_group attrgp;

	if (!ocfs2_kset)
		return -ENOMEM;

	attrs = kmalloc(sizeof(struct attribute *) * 4, GFP_NOFS);
	if (!attrs) {
		ret = -ENOMEM;
		goto error;
	} else {
		attrs[0] = &ocfs2_attr_filecheck_chk.attr;
		attrs[1] = &ocfs2_attr_filecheck_fix.attr;
		attrs[2] = &ocfs2_attr_filecheck_set.attr;
		attrs[3] = NULL;
		memset(&attrgp, 0, sizeof(attrgp));
		attrgp.attrs = attrs;
	}

	fcheck = kmalloc(sizeof(struct ocfs2_filecheck), GFP_NOFS);
	if (!fcheck) {
		ret = -ENOMEM;
		goto error;
	} else {
		INIT_LIST_HEAD(&fcheck->fc_head);
		spin_lock_init(&fcheck->fc_lock);
		fcheck->fc_max = OCFS2_FILECHECK_MINSIZE;
		fcheck->fc_size = 0;
		fcheck->fc_done = 0;
	}

	if (strlen(sb->s_id) <= 0) {
		mlog(ML_ERROR,
		"Cannot get device basename when create filecheck sysfs\n");
		ret = -ENODEV;
		goto error;
	}

	device_kset = kset_create_and_add(sb->s_id, NULL, &ocfs2_kset->kobj);
	if (!device_kset) {
		ret = -ENOMEM;
		goto error;
	}

	fcheck_kset = kset_create_and_add("filecheck", NULL,
					  &device_kset->kobj);
	if (!fcheck_kset) {
		ret = -ENOMEM;
		goto error;
	}

	ret = sysfs_create_group(&fcheck_kset->kobj, &attrgp);
	if (ret)
		goto error;

	entry = kmalloc(sizeof(struct ocfs2_filecheck_sysfs_entry), GFP_NOFS);
	if (!entry) {
		ret = -ENOMEM;
		goto error;
	} else {
		atomic_set(&entry->fs_count, 1);
		entry->fs_sb = sb;
		entry->fs_devicekset = device_kset;
		entry->fs_fcheckkset = fcheck_kset;
		entry->fs_fcheck = fcheck;
		ocfs2_filecheck_sysfs_add(entry);
	}

	kfree(attrs);
	return 0;

error:
	kfree(attrs);
	kfree(entry);
	kfree(fcheck);
	kset_unregister(fcheck_kset);
	kset_unregister(device_kset);
	return ret;
}

int ocfs2_filecheck_remove_sysfs(struct super_block *sb)
{
	return ocfs2_filecheck_sysfs_del(sb->s_id);
}

static int
ocfs2_filecheck_erase_entries(struct ocfs2_filecheck_sysfs_entry *ent,
			      unsigned int count);
static int
ocfs2_filecheck_adjust_max(struct ocfs2_filecheck_sysfs_entry *ent,
			   unsigned int len)
{
	int ret;

	if ((len < OCFS2_FILECHECK_MINSIZE) || (len > OCFS2_FILECHECK_MAXSIZE))
		return -EINVAL;

	spin_lock(&ent->fs_fcheck->fc_lock);
	if (len < (ent->fs_fcheck->fc_size - ent->fs_fcheck->fc_done)) {
		mlog(ML_ERROR,
		"Cannot set online file check maximum entry number "
		"to %u due to too many pending entries(%u)\n",
		len, ent->fs_fcheck->fc_size - ent->fs_fcheck->fc_done);
		ret = -EBUSY;
	} else {
		if (len < ent->fs_fcheck->fc_size)
			BUG_ON(!ocfs2_filecheck_erase_entries(ent,
				ent->fs_fcheck->fc_size - len));

		ent->fs_fcheck->fc_max = len;
		ret = 0;
	}
	spin_unlock(&ent->fs_fcheck->fc_lock);

	return ret;
}

#define OCFS2_FILECHECK_ARGS_LEN	24
static int
ocfs2_filecheck_args_get_long(const char *buf, size_t count,
			      unsigned long *val)
{
	char buffer[OCFS2_FILECHECK_ARGS_LEN];

	memcpy(buffer, buf, count);
	buffer[count] = '\0';

	if (kstrtoul(buffer, 0, val))
		return 1;

	return 0;
}

static int
ocfs2_filecheck_type_parse(const char *name, unsigned int *type)
{
	if (!strncmp(name, "fix", 4))
		*type = OCFS2_FILECHECK_TYPE_FIX;
	else if (!strncmp(name, "check", 6))
		*type = OCFS2_FILECHECK_TYPE_CHK;
	else if (!strncmp(name, "set", 4))
		*type = OCFS2_FILECHECK_TYPE_SET;
	else
		return 1;

	return 0;
}

static int
ocfs2_filecheck_args_parse(const char *name, const char *buf, size_t count,
			   struct ocfs2_filecheck_args *args)
{
	unsigned long val = 0;
	unsigned int type;

	/* too short/long args length */
	if ((count < 1) || (count >= OCFS2_FILECHECK_ARGS_LEN))
		return 1;

	if (ocfs2_filecheck_type_parse(name, &type))
		return 1;
	if (ocfs2_filecheck_args_get_long(buf, count, &val))
		return 1;

	if (val <= 0)
		return 1;

	args->fa_type = type;
	if (type == OCFS2_FILECHECK_TYPE_SET)
		args->fa_len = (unsigned int)val;
	else
		args->fa_ino = val;

	return 0;
}

static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
				    struct kobj_attribute *attr,
				    char *buf)
{

	ssize_t ret = 0, total = 0, remain = PAGE_SIZE;
	unsigned int type;
	struct ocfs2_filecheck_entry *p;
	struct ocfs2_filecheck_sysfs_entry *ent;

	if (ocfs2_filecheck_type_parse(attr->attr.name, &type))
		return -EINVAL;

	ent = ocfs2_filecheck_sysfs_get(kobj->parent->name);
	if (!ent) {
		mlog(ML_ERROR,
		"Cannot get the corresponding entry via device basename %s\n",
		kobj->name);
		return -ENODEV;
	}

	if (type == OCFS2_FILECHECK_TYPE_SET) {
		spin_lock(&ent->fs_fcheck->fc_lock);
		total = snprintf(buf, remain, "%u\n", ent->fs_fcheck->fc_max);
		spin_unlock(&ent->fs_fcheck->fc_lock);
		goto exit;
	}

	ret = snprintf(buf, remain, "INO\t\tDONE\tERROR\n");
	total += ret;
	remain -= ret;
	spin_lock(&ent->fs_fcheck->fc_lock);
	list_for_each_entry(p, &ent->fs_fcheck->fc_head, fe_list) {
		if (p->fe_type != type)
			continue;

		ret = snprintf(buf + total, remain, "%lu\t\t%u\t%s\n",
			       p->fe_ino, p->fe_done,
			       ocfs2_filecheck_error(p->fe_status));
		if (ret < 0) {
			total = ret;
			break;
		}
		if (ret == remain) {
			/* snprintf() didn't fit */
			total = -E2BIG;
			break;
		}
		total += ret;
		remain -= ret;
	}
	spin_unlock(&ent->fs_fcheck->fc_lock);

exit:
	ocfs2_filecheck_sysfs_put(ent);
	return total;
}

static int
ocfs2_filecheck_erase_entry(struct ocfs2_filecheck_sysfs_entry *ent)
{
	struct ocfs2_filecheck_entry *p;

	list_for_each_entry(p, &ent->fs_fcheck->fc_head, fe_list) {
		if (p->fe_done) {
			list_del(&p->fe_list);
			kfree(p);
			ent->fs_fcheck->fc_size--;
			ent->fs_fcheck->fc_done--;
			return 1;
		}
	}

	return 0;
}

static int
ocfs2_filecheck_erase_entries(struct ocfs2_filecheck_sysfs_entry *ent,
			      unsigned int count)
{
	unsigned int i = 0;
	unsigned int ret = 0;

	while (i++ < count) {
		if (ocfs2_filecheck_erase_entry(ent))
			ret++;
		else
			break;
	}

	return (ret == count ? 1 : 0);
}

static void
ocfs2_filecheck_done_entry(struct ocfs2_filecheck_sysfs_entry *ent,
			   struct ocfs2_filecheck_entry *entry)
{
	entry->fe_done = 1;
	spin_lock(&ent->fs_fcheck->fc_lock);
	ent->fs_fcheck->fc_done++;
	spin_unlock(&ent->fs_fcheck->fc_lock);
}

static unsigned int
ocfs2_filecheck_handle(struct super_block *sb,
		       unsigned long ino, unsigned int flags)
{
	unsigned int ret = OCFS2_FILECHECK_ERR_SUCCESS;
	struct inode *inode = NULL;
	int rc;

	inode = ocfs2_iget(OCFS2_SB(sb), ino, flags, 0);
	if (IS_ERR(inode)) {
		rc = (int)(-(long)inode);
		if (rc >= OCFS2_FILECHECK_ERR_START &&
		    rc < OCFS2_FILECHECK_ERR_END)
			ret = rc;
		else
			ret = OCFS2_FILECHECK_ERR_FAILED;
	} else
		iput(inode);

	return ret;
}

static void
ocfs2_filecheck_handle_entry(struct ocfs2_filecheck_sysfs_entry *ent,
			     struct ocfs2_filecheck_entry *entry)
{
	if (entry->fe_type == OCFS2_FILECHECK_TYPE_CHK)
		entry->fe_status = ocfs2_filecheck_handle(ent->fs_sb,
				entry->fe_ino, OCFS2_FI_FLAG_FILECHECK_CHK);
	else if (entry->fe_type == OCFS2_FILECHECK_TYPE_FIX)
		entry->fe_status = ocfs2_filecheck_handle(ent->fs_sb,
				entry->fe_ino, OCFS2_FI_FLAG_FILECHECK_FIX);
	else
		entry->fe_status = OCFS2_FILECHECK_ERR_UNSUPPORTED;

	ocfs2_filecheck_done_entry(ent, entry);
}

static ssize_t ocfs2_filecheck_store(struct kobject *kobj,
				     struct kobj_attribute *attr,
				     const char *buf, size_t count)
{
	struct ocfs2_filecheck_args args;
	struct ocfs2_filecheck_entry *entry;
	struct ocfs2_filecheck_sysfs_entry *ent;
	ssize_t ret = 0;

	if (count == 0)
		return count;

	if (ocfs2_filecheck_args_parse(attr->attr.name, buf, count, &args)) {
		mlog(ML_ERROR, "Invalid arguments for online file check\n");
		return -EINVAL;
	}

	ent = ocfs2_filecheck_sysfs_get(kobj->parent->name);
	if (!ent) {
		mlog(ML_ERROR,
		"Cannot get the corresponding entry via device basename %s\n",
		kobj->parent->name);
		return -ENODEV;
	}

	if (args.fa_type == OCFS2_FILECHECK_TYPE_SET) {
		ret = ocfs2_filecheck_adjust_max(ent, args.fa_len);
		goto exit;
	}

	entry = kmalloc(sizeof(struct ocfs2_filecheck_entry), GFP_NOFS);
	if (!entry) {
		ret = -ENOMEM;
		goto exit;
	}

	spin_lock(&ent->fs_fcheck->fc_lock);
	if ((ent->fs_fcheck->fc_size >= ent->fs_fcheck->fc_max) &&
	    (ent->fs_fcheck->fc_done == 0)) {
		mlog(ML_ERROR,
		"Cannot do more file check "
		"since file check queue(%u) is full now\n",
		ent->fs_fcheck->fc_max);
		ret = -EBUSY;
		kfree(entry);
	} else {
		if ((ent->fs_fcheck->fc_size >= ent->fs_fcheck->fc_max) &&
		    (ent->fs_fcheck->fc_done > 0)) {
			/* Delete the oldest entry which was done,
			 * make sure the entry size in list does
			 * not exceed maximum value
			 */
			BUG_ON(!ocfs2_filecheck_erase_entry(ent));
		}

		entry->fe_ino = args.fa_ino;
		entry->fe_type = args.fa_type;
		entry->fe_done = 0;
		entry->fe_status = OCFS2_FILECHECK_ERR_INPROGRESS;
		list_add_tail(&entry->fe_list, &ent->fs_fcheck->fc_head);
		ent->fs_fcheck->fc_size++;
	}
	spin_unlock(&ent->fs_fcheck->fc_lock);

	if (!ret)
		ocfs2_filecheck_handle_entry(ent, entry);

exit:
	ocfs2_filecheck_sysfs_put(ent);
	return (!ret ? count : ret);
}
