+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * lustre/smfs/ioctl.c
+ * Lustre filesystem abstraction routines
+ *
+ * Copyright (C) 2004 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
#define DEBUG_SUBSYSTEM S_SM
#ifndef EXPORT_SYMTAB
#include <linux/obd_support.h>
#include <linux/lustre_lib.h>
#include <linux/lustre_idl.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_mds.h>
#include <linux/lustre_debug.h>
-#include <linux/lustre_smfs.h>
+#include <linux/lustre_smfs.h>
+#include <linux/lustre_snap.h>
-#include "smfs_internal.h"
+#include "smfs_internal.h"
+static struct super_block *smfs_get_sb_by_path(char *path, int len)
+{
+ struct super_block *sb;
+ struct nameidata nd;
+
+ ENTRY;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+ if (path_init(path, LOOKUP_FOLLOW, &nd)) {
+ int error = 0;
+ error = path_walk(path, &nd);
+ if (error) {
+ path_release(&nd);
+ RETURN(NULL);
+ }
+ } else {
+ RETURN(NULL);
+ }
+#else
+ if (path_lookup(path, LOOKUP_FOLLOW, &nd))
+ RETURN(NULL);
+
+#endif
+ /* FIXME-WANGDI: add some check code here. */
+ sb = nd.dentry->d_sb;
+ path_release(&nd);
+ RETURN(sb);
+}
struct smfs_control_device smfs_dev;
static int smfs_handle_ioctl(unsigned int cmd, unsigned long arg)
{
struct obd_ioctl_data *data = NULL;
- struct super_block *sb = NULL;
- char *buf = NULL, *dir = NULL;
- int err = 0, len = 0, count = 0, do_kml = 0;
-
- if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
+ struct super_block *sb = NULL;
+ char *buf = NULL;
+ int err = 0, len = 0;
+
+ if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
CERROR("OBD ioctl: data error\n");
GOTO(out, err = -EINVAL);
}
data = (struct obd_ioctl_data *)buf;
-
+
switch (cmd) {
- case IOC_SMFS_START:
- case IOC_SMFS_STOP:
- case IOC_SMFS_REINT:
- case IOC_SMFS_UNDO:{
- char *name;
- if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
- CERROR("No mountpoint passed!\n");
- GOTO(out, err = -EINVAL);
- }
- name = (char*) data->ioc_inlbuf1;
- sb = smfs_get_sb_by_path(name, data->ioc_inllen1);
- if (!sb) {
- CERROR("can not find superblock at %s\n", buf);
- GOTO(out, err = -EINVAL);
- }
- /*get cmd count*/
- if (data->ioc_inllen2 && data->ioc_inlbuf2) {
- dir = (char *)data->ioc_inlbuf2;
- }
- if (data->ioc_plen1)
- count = *((int*)data->ioc_pbuf1);
- if (data->ioc_plen2)
- do_kml = *((int*)data->ioc_pbuf2);
- break;
- }
- default: {
- CERROR("The command passed in is Invalid\n");
- GOTO(out, err = -EINVAL);
- }
- }
-
- switch (cmd) {
- case IOC_SMFS_START:
- err = smfs_start_rec(sb);
- break;
- case IOC_SMFS_STOP:
- err = smfs_stop_rec(sb);
- break;
- case IOC_SMFS_REINT:
- case IOC_SMFS_UNDO: {
- int flags = 0;
- if (cmd == IOC_SMFS_REINT)
- SET_REC_OP_FLAGS(flags, SMFS_REINT_REC);
- else
- SET_REC_OP_FLAGS(flags, SMFS_UNDO_REC);
- if (count == 0)
- SET_REC_COUNT_FLAGS(flags, SMFS_REC_ALL);
- if (do_kml)
- SET_REC_WRITE_KML_FLAGS(flags, SMFS_WRITE_KML);
- err = smfs_process_rec(sb, count, dir, flags);
- break;
- }
- }
+ case OBD_IOC_SMFS_SNAP_ADD:{
+ char *name, *snapshot_name;
+ if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
+ CERROR("No mountpoint passed!\n");
+ GOTO(out, err = -EINVAL);
+ }
+ if (!data->ioc_inllen2 || !data->ioc_inlbuf2) {
+ CERROR("No snapshotname passed!\n");
+ GOTO(out, err = -EINVAL);
+ }
+ name = (char*) data->ioc_inlbuf1;
+ sb = smfs_get_sb_by_path(name, data->ioc_inllen1);
+ if (!sb) {
+ CERROR("can not find superblock at %s\n", buf);
+ GOTO(out, err = -EINVAL);
+ }
+ snapshot_name = (char *)data->ioc_inlbuf2;
+#ifdef CONFIG_SNAPFS
+ err = smfs_add_snap_item(sb, name, snapshot_name);
+#endif
+ break;
+ }
+ default: {
+ CERROR("The command passed in is Invalid\n");
+ GOTO(out, err = -EINVAL);
+ }
+ }
out:
- if (buf)
- obd_ioctl_freedata(buf, len);
- RETURN(err);
+ if (buf)
+ obd_ioctl_freedata(buf, len);
+ RETURN(err);
}
-static int smfs_psdev_ioctl (struct inode * inode, struct file * filp,
- unsigned int cmd, unsigned long arg)
+#define SMFS_MINOR 250
+static int smfs_psdev_ioctl(struct inode * inode, struct file * filp,
+ unsigned int cmd, unsigned long arg)
{
- int rc = 0;
- rc = smfs_handle_ioctl(cmd, arg);
- RETURN(rc);
+ int rc = 0;
+ rc = smfs_handle_ioctl(cmd, arg);
+ RETURN(rc);
}
/* called when opening /dev/device */
static int smfs_psdev_open(struct inode * inode, struct file * file)
{
- int dev;
+ int dev;
ENTRY;
- if (!inode)
- RETURN(-EINVAL);
- dev = MINOR(inode->i_rdev);
- if (dev != SMFS_PSDEV_MINOR)
- RETURN(-ENODEV);
+ if (!inode)
+ RETURN(-EINVAL);
+ dev = MINOR(inode->i_rdev);
+ if (dev != SMFS_MINOR)
+ RETURN(-ENODEV);
RETURN(0);
}
/* called when closing /dev/device */
static int smfs_psdev_release(struct inode * inode, struct file * file)
{
- int dev;
+ int dev;
ENTRY;
- if (!inode)
- RETURN(-EINVAL);
- dev = MINOR(inode->i_rdev);
- if (dev != SMFS_PSDEV_MINOR)
- RETURN(-ENODEV);
+ if (!inode)
+ RETURN(-EINVAL);
+ dev = MINOR(inode->i_rdev);
+ if (dev != SMFS_MINOR)
+ RETURN(-ENODEV);
RETURN(0);
}
/* declare character device */
static struct file_operations smfscontrol_fops = {
- ioctl: smfs_psdev_ioctl, /* ioctl */
- open: smfs_psdev_open, /* open */
- release: smfs_psdev_release, /* release */
+ .owner = THIS_MODULE,
+ .ioctl = smfs_psdev_ioctl, /* ioctl */
+ .open = smfs_psdev_open, /* open */
+ .release = smfs_psdev_release, /* release */
};
-#define SMFS_MINOR 250
static struct miscdevice smfscontrol_dev = {
- minor: SMFS_MINOR,
- name: "smfscontrol",
- fops: &smfscontrol_fops
+ .minor = SMFS_MINOR,
+ .name = "smfscontrol",
+ .fops = &smfscontrol_fops
};
int init_smfs_psdev(void)
{
- printk(KERN_INFO "SMFS psdev driver v0.01, braam@clusterfs.com\n");
-
- misc_register(&smfscontrol_dev);
+ printk(KERN_INFO "SMFS psdev driver v0.01, braam@clusterfs.com\n");
+
+ misc_register(&smfscontrol_dev);
- return 0;
+ return 0;
}
void smfs_cleanup_psdev(void)
{
ENTRY;
- misc_deregister(&smfscontrol_dev);
- EXIT;
+ misc_deregister(&smfscontrol_dev);
+ EXIT;
}