Whamcloud - gitweb
file loop-sync-2.4.21-suse.patch was initially added on branch b1_2_smallfix.
[fs/lustre-release.git] / lustre / smfs / ioctl.c
1 #define DEBUG_SUBSYSTEM S_SM
2
3 #ifndef EXPORT_SYMTAB
4 #define EXPORT_SYMTAB
5 #endif
6
7 #include <linux/module.h>
8 #include <linux/kernel.h>
9 #include <linux/string.h>
10 #include <linux/slab.h>
11 #include <linux/stat.h>
12 #include <linux/unistd.h>
13 #include <linux/miscdevice.h>
14 #include <linux/obd_class.h>
15 #include <linux/obd_support.h>
16 #include <linux/lustre_lib.h>
17 #include <linux/lustre_idl.h>
18 #include <linux/lustre_debug.h>
19 #include <linux/lustre_smfs.h>   
20
21 #include "smfs_internal.h" 
22
23
24 struct smfs_control_device smfs_dev;
25
26 static int smfs_handle_ioctl(unsigned int cmd, unsigned long arg)
27 {
28         struct obd_ioctl_data *data = NULL;
29         struct super_block *sb = NULL;
30         char *buf = NULL, *dir = NULL;
31         int err = 0, len = 0, count = 0, do_kml = 0;
32          
33         if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
34                 CERROR("OBD ioctl: data error\n");
35                 GOTO(out, err = -EINVAL);
36         }
37         data = (struct obd_ioctl_data *)buf;
38         
39         switch (cmd) {
40         case IOC_SMFS_START:
41         case IOC_SMFS_STOP:
42         case IOC_SMFS_REINT:
43         case IOC_SMFS_UNDO:{
44                 char *name;
45                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
46                         CERROR("No mountpoint passed!\n");
47                         GOTO(out, err = -EINVAL);
48                 }
49                 name = (char*) data->ioc_inlbuf1;
50                 sb = smfs_get_sb_by_path(name,  data->ioc_inllen1);
51                 if (!sb) {
52                         CERROR("can not find superblock at %s\n", buf);
53                         GOTO(out, err = -EINVAL);
54                 }
55                 /*get cmd count*/
56                 if (data->ioc_inllen2 && data->ioc_inlbuf2) {
57                         dir = (char *)data->ioc_inlbuf2;
58                 }
59                 if (data->ioc_plen1)
60                         count = *((int*)data->ioc_pbuf1);       
61                 if (data->ioc_plen2)
62                         do_kml = *((int*)data->ioc_pbuf2);      
63                 break;
64         }
65         default: {
66                 CERROR("The command passed in is Invalid\n");
67                 GOTO(out, err = -EINVAL);
68         }       
69         }
70         
71         switch (cmd) {
72         case IOC_SMFS_START:
73                 err = smfs_start_rec(sb);
74                 break;
75         case IOC_SMFS_STOP:
76                 err = smfs_stop_rec(sb);
77                 break;
78         case IOC_SMFS_REINT: 
79         case IOC_SMFS_UNDO: {
80                 int flags = 0;
81                 if (cmd == IOC_SMFS_REINT)
82                         SET_REC_OP_FLAGS(flags, SMFS_REINT_REC);
83                 else
84                         SET_REC_OP_FLAGS(flags, SMFS_UNDO_REC);
85                 if (count == 0)
86                         SET_REC_COUNT_FLAGS(flags, SMFS_REC_ALL);
87                 if (do_kml)
88                         SET_REC_WRITE_KML_FLAGS(flags, SMFS_WRITE_KML); 
89                 err = smfs_process_rec(sb, count, dir, flags);
90                 break;
91         }
92         }                       
93 out:
94         if (buf)
95                 obd_ioctl_freedata(buf, len);
96         RETURN(err);
97 }
98 static int smfs_psdev_ioctl (struct inode * inode, struct file * filp, 
99                        unsigned int cmd, unsigned long arg)
100 {
101         int rc = 0;
102         rc = smfs_handle_ioctl(cmd, arg);       
103         RETURN(rc);     
104 }
105
106 /* called when opening /dev/device */
107 static int smfs_psdev_open(struct inode * inode, struct file * file)
108 {
109         int dev;
110         ENTRY;
111
112         if (!inode)
113                 RETURN(-EINVAL);
114         dev = MINOR(inode->i_rdev);
115         if (dev != SMFS_PSDEV_MINOR)
116                 RETURN(-ENODEV);
117
118         RETURN(0);
119 }
120
121 /* called when closing /dev/device */
122 static int smfs_psdev_release(struct inode * inode, struct file * file)
123 {
124         int dev;
125         ENTRY;
126
127         if (!inode)
128                 RETURN(-EINVAL);
129         dev = MINOR(inode->i_rdev);
130         if (dev != SMFS_PSDEV_MINOR)
131                 RETURN(-ENODEV);
132
133         RETURN(0);
134 }
135
136 /* declare character device */
137 static struct file_operations smfscontrol_fops = {
138         ioctl:          smfs_psdev_ioctl,            /* ioctl */
139         open:           smfs_psdev_open,       /* open */
140         release:        smfs_psdev_release,    /* release */
141 };
142
143 #define SMFS_MINOR 250
144 static struct miscdevice smfscontrol_dev = {
145         minor:  SMFS_MINOR,
146         name:   "smfscontrol",
147         fops:   &smfscontrol_fops
148 };
149
150 int init_smfs_psdev(void)
151 {
152         printk(KERN_INFO "SMFS psdev driver  v0.01, braam@clusterfs.com\n");
153         
154         misc_register(&smfscontrol_dev);
155
156         return 0;
157 }
158
159 void smfs_cleanup_psdev(void)
160 {
161         ENTRY;
162         misc_deregister(&smfscontrol_dev);
163         EXIT;
164 }