Whamcloud - gitweb
b=3550
[fs/lustre-release.git] / lustre / smfs / ioctl.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lustre/smfs/ioctl.c
5  *  Lustre filesystem abstraction routines
6  *
7  *  Copyright (C) 2004 Cluster File Systems, Inc.
8  *
9  *   This file is part of Lustre, http://www.lustre.org.
10  *
11  *   Lustre is free software; you can redistribute it and/or
12  *   modify it under the terms of version 2 of the GNU General Public
13  *   License as published by the Free Software Foundation.
14  *
15  *   Lustre is distributed in the hope that it will be useful,
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *   GNU General Public License for more details.
19  *
20  *   You should have received a copy of the GNU General Public License
21  *   along with Lustre; if not, write to the Free Software
22  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24 #define DEBUG_SUBSYSTEM S_SM
25
26 #ifndef EXPORT_SYMTAB
27 #define EXPORT_SYMTAB
28 #endif
29
30 #include <linux/module.h>
31 #include <linux/kernel.h>
32 #include <linux/string.h>
33 #include <linux/slab.h>
34 #include <linux/stat.h>
35 #include <linux/unistd.h>
36 #include <linux/miscdevice.h>
37 #include <linux/obd_class.h>
38 #include <linux/obd_support.h>
39 #include <linux/lustre_lib.h>
40 #include <linux/lustre_idl.h>
41 #include <linux/lustre_fsfilt.h>
42 #include <linux/lustre_mds.h>
43 #include <linux/lustre_debug.h>
44 #include <linux/lustre_smfs.h>
45
46 #include "smfs_internal.h"
47
48
49 struct smfs_control_device smfs_dev;
50
51 static int smfs_handle_ioctl(unsigned int cmd, unsigned long arg)
52 {
53         struct obd_ioctl_data *data = NULL;
54          struct super_block *sb = NULL;
55         char *buf = NULL, *dir = NULL;
56         int err = 0, len = 0, count = 0, do_kml = 0;
57
58         if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
59                 CERROR("OBD ioctl: data error\n");
60                 GOTO(out, err = -EINVAL);
61         }
62         data = (struct obd_ioctl_data *)buf;
63
64         switch (cmd) {
65         case IOC_SMFS_START:
66         case IOC_SMFS_STOP:
67         case IOC_SMFS_REINT:
68         case IOC_SMFS_UNDO:{
69                 char *name;
70                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
71                         CERROR("No mountpoint passed!\n");
72                         GOTO(out, err = -EINVAL);
73                 }
74                 name = (char*) data->ioc_inlbuf1;
75                 sb = smfs_get_sb_by_path(name,  data->ioc_inllen1);
76                 if (!sb) {
77                         CERROR("can not find superblock at %s\n", buf);
78                         GOTO(out, err = -EINVAL);
79                 }
80                 /*get cmd count*/
81                 if (data->ioc_inllen2 && data->ioc_inlbuf2) {
82                         dir = (char *)data->ioc_inlbuf2;
83                 }
84                 if (data->ioc_plen1)
85                         count = *((int*)data->ioc_pbuf1);
86                 if (data->ioc_plen2)
87                         do_kml = *((int*)data->ioc_pbuf2);
88                 break;
89         }
90         default: {
91                 CERROR("The command passed in is Invalid\n");
92                 GOTO(out, err = -EINVAL);
93         }
94         }
95
96         switch (cmd) {
97         case IOC_SMFS_START:
98                 err = smfs_start_rec(sb, NULL);
99                 break;
100         case IOC_SMFS_STOP:
101                 err = smfs_stop_rec(sb);
102                 break;
103         case IOC_SMFS_REINT:
104         case IOC_SMFS_UNDO: {
105                 int flags = 0;
106                 if (cmd == IOC_SMFS_REINT)
107                         SET_REC_OP_FLAGS(flags, SMFS_REINT_REC);
108                 else
109                         SET_REC_OP_FLAGS(flags, SMFS_UNDO_REC);
110                 if (count == 0)
111                         SET_REC_COUNT_FLAGS(flags, SMFS_REC_ALL);
112                 if (do_kml)
113                         SET_REC_WRITE_KML_FLAGS(flags, SMFS_WRITE_KML);
114                 err = smfs_process_rec(sb, count, dir, flags);
115                 break;
116         }
117         }
118 out:
119         if (buf)
120                 obd_ioctl_freedata(buf, len);
121         RETURN(err);
122 }
123
124 static int smfs_psdev_ioctl(struct inode * inode, struct file * filp,
125                             unsigned int cmd, unsigned long arg)
126 {
127         int rc = 0;
128         rc = smfs_handle_ioctl(cmd, arg);
129         RETURN(rc);
130 }
131
132 /* called when opening /dev/device */
133 static int smfs_psdev_open(struct inode * inode, struct file * file)
134 {
135         int dev;
136         ENTRY;
137
138         if (!inode)
139                 RETURN(-EINVAL);
140         dev = MINOR(inode->i_rdev);
141         if (dev != SMFS_PSDEV_MINOR)
142                 RETURN(-ENODEV);
143
144         RETURN(0);
145 }
146
147 /* called when closing /dev/device */
148 static int smfs_psdev_release(struct inode * inode, struct file * file)
149 {
150         int dev;
151         ENTRY;
152
153         if (!inode)
154                 RETURN(-EINVAL);
155         dev = MINOR(inode->i_rdev);
156         if (dev != SMFS_PSDEV_MINOR)
157                 RETURN(-ENODEV);
158
159         RETURN(0);
160 }
161
162 /* declare character device */
163 static struct file_operations smfscontrol_fops = {
164         ioctl:                smfs_psdev_ioctl,            /* ioctl */
165         open:                smfs_psdev_open,       /* open */
166         release:        smfs_psdev_release,    /* release */
167 };
168
169 #define SMFS_MINOR 250
170 static struct miscdevice smfscontrol_dev = {
171         minor:        SMFS_MINOR,
172         name:        "smfscontrol",
173         fops:        &smfscontrol_fops
174 };
175
176 int init_smfs_psdev(void)
177 {
178         printk(KERN_INFO "SMFS psdev driver  v0.01, braam@clusterfs.com\n");
179
180         misc_register(&smfscontrol_dev);
181
182         return 0;
183 }
184
185 void smfs_cleanup_psdev(void)
186 {
187         ENTRY;
188         misc_deregister(&smfscontrol_dev);
189         EXIT;
190 }