Whamcloud - gitweb
current branches now use lnet from HEAD
[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 #include <linux/lustre_snap.h>
46
47 #include "smfs_internal.h"
48
49 static struct super_block *smfs_get_sb_by_path(char *path, int len)
50 {
51         struct super_block *sb;
52         struct nameidata nd;
53
54         ENTRY;
55 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
56         if (path_init(path, LOOKUP_FOLLOW, &nd)) {
57                 int error = 0;
58                 error = path_walk(path, &nd);
59                 if (error) {
60                         path_release(&nd);
61                         RETURN(NULL);
62                 }
63         } else {
64                 RETURN(NULL);
65         }
66 #else
67         if (path_lookup(path, LOOKUP_FOLLOW, &nd))
68                 RETURN(NULL); 
69         
70 #endif
71         /* FIXME-WANGDI: add some check code here. */
72         sb = nd.dentry->d_sb;
73         path_release(&nd);
74         RETURN(sb);
75 }
76
77 struct smfs_control_device smfs_dev;
78
79 static int smfs_handle_ioctl(unsigned int cmd, unsigned long arg)
80 {
81         struct obd_ioctl_data *data = NULL;
82          struct super_block *sb = NULL;
83         char *buf = NULL;
84         int err = 0, len = 0;
85
86         if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
87                 CERROR("OBD ioctl: data error\n");
88                 GOTO(out, err = -EINVAL);
89         }
90         data = (struct obd_ioctl_data *)buf;
91
92         switch (cmd) {
93         case OBD_IOC_SMFS_SNAP_ADD:{
94                 char *name, *snapshot_name;
95                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
96                         CERROR("No mountpoint passed!\n");
97                         GOTO(out, err = -EINVAL);
98                 }
99                 if (!data->ioc_inllen2 || !data->ioc_inlbuf2) {
100                         CERROR("No snapshotname passed!\n");
101                         GOTO(out, err = -EINVAL);
102                 }
103                 name = (char*) data->ioc_inlbuf1;
104                 sb = smfs_get_sb_by_path(name,  data->ioc_inllen1);
105                 if (!sb) {
106                         CERROR("can not find superblock at %s\n", buf);
107                         GOTO(out, err = -EINVAL);
108                 }
109                 snapshot_name = (char *)data->ioc_inlbuf2;
110 #ifdef CONFIG_SNAPFS
111                 err = smfs_add_snap_item(sb, name, snapshot_name);
112 #endif         
113                 break;
114         }
115         default: {
116                 CERROR("The command passed in is Invalid\n");
117                 GOTO(out, err = -EINVAL);
118         }
119         }
120 out:
121         if (buf)
122                 obd_ioctl_freedata(buf, len);
123         RETURN(err);
124 }
125 #define SMFS_MINOR 250
126 static int smfs_psdev_ioctl(struct inode * inode, struct file * filp,
127                             unsigned int cmd, unsigned long arg)
128 {
129         int rc = 0;
130         rc = smfs_handle_ioctl(cmd, arg);
131         RETURN(rc);
132 }
133
134 /* called when opening /dev/device */
135 static int smfs_psdev_open(struct inode * inode, struct file * file)
136 {
137         int dev;
138         ENTRY;
139
140         if (!inode)
141                 RETURN(-EINVAL);
142         dev = MINOR(inode->i_rdev);
143         if (dev != SMFS_MINOR)
144                 RETURN(-ENODEV);
145
146         RETURN(0);
147 }
148
149 /* called when closing /dev/device */
150 static int smfs_psdev_release(struct inode * inode, struct file * file)
151 {
152         int dev;
153         ENTRY;
154
155         if (!inode)
156                 RETURN(-EINVAL);
157         dev = MINOR(inode->i_rdev);
158         if (dev != SMFS_MINOR)
159                 RETURN(-ENODEV);
160
161         RETURN(0);
162 }
163
164 /* declare character device */
165 static struct file_operations smfscontrol_fops = {
166         .owner   = THIS_MODULE,
167         .ioctl   = smfs_psdev_ioctl,            /* ioctl */
168         .open    = smfs_psdev_open,       /* open */
169         .release = smfs_psdev_release,    /* release */
170 };
171
172 static struct miscdevice smfscontrol_dev = {
173         .minor         = SMFS_MINOR,
174         .name          = "smfscontrol",
175         .fops          = &smfscontrol_fops
176 };
177
178 int init_smfs_psdev(void)
179 {
180         printk(KERN_INFO "SMFS psdev driver  v0.01, braam@clusterfs.com\n");
181
182         misc_register(&smfscontrol_dev);
183
184         return 0;
185 }
186
187 void smfs_cleanup_psdev(void)
188 {
189         ENTRY;
190         misc_deregister(&smfscontrol_dev);
191         EXIT;
192 }