1 #include <linux/errno.h>
2 #include <linux/slab.h>
3 #include <linux/vmalloc.h>
4 #include <linux/module.h>
5 #include <asm/uaccess.h>
7 #include "intermezzo_fs.h"
8 #include "intermezzo_upcall.h"
9 #include "intermezzo_psdev.h"
10 #include "intermezzo_kml.h"
12 static struct presto_file_set * kml_getfset (char *path)
14 return presto_path2fileset(path);
17 /* Send the KML buffer and related volume info into kernel */
18 int begin_kml_reint (struct file *file, unsigned long arg)
24 int reclen; /* int newpos; */
26 struct kml_fsdata *kml_fsdata = NULL;
27 struct presto_file_set *fset = NULL;
32 /* allocate buffer & copy it to kernel space */
33 if (copy_from_user(&input, (char *)arg, sizeof(input))) {
38 if (input.reclen > kml_fsdata->kml_maxsize)
39 return -ENOMEM; /* we'll find solution to this in the future */
41 PRESTO_ALLOC(path, char *, input.namelen + 1);
46 if (copy_from_user(path, input.volname, input.namelen)) {
47 PRESTO_FREE(path, input.namelen + 1);
51 path[input.namelen] = '\0';
52 fset = kml_getfset (path);
53 PRESTO_FREE(path, input.namelen + 1);
55 kml_fsdata = FSET_GET_KMLDATA(fset);
56 /* read the buf from user memory here */
57 if (copy_from_user(kml_fsdata->kml_buf, input.recbuf, input.reclen)) {
61 kml_fsdata->kml_len = input.reclen;
63 decode_kmlrec (&kml_fsdata->kml_reint_cache,
64 kml_fsdata->kml_buf, kml_fsdata->kml_len);
66 kml_fsdata->kml_reint_current = kml_fsdata->kml_reint_cache.next;
67 kml_fsdata->kml_reintpos = 0;
68 kml_fsdata->kml_count = 0;
73 int do_kml_reint (struct file *file, unsigned long arg)
88 struct kml_rec *close_rec;
89 struct kml_fsdata *kml_fsdata;
90 struct presto_file_set *fset;
93 if (copy_from_user(&input, (char *)arg, sizeof(input))) {
97 PRESTO_ALLOC(path, char *, input.namelen + 1);
102 if (copy_from_user(path, input.volname, input.namelen)) {
103 PRESTO_FREE(path, input.namelen + 1);
107 path[input.namelen] = '\0';
108 fset = kml_getfset (path);
109 PRESTO_FREE(path, input.namelen + 1);
111 kml_fsdata = FSET_GET_KMLDATA(fset);
113 error = kml_reintbuf(kml_fsdata,
114 fset->fset_mtpt->d_name.name,
117 if (error == KML_CLOSE_BACKFETCH && close_rec != NULL) {
118 struct kml_close *close = &close_rec->rec_kml.close;
119 input.ino = close->ino;
120 input.generation = close->generation;
121 if (strlen (close->path) + 1 < input.pathlen) {
122 strcpy (input.path, close->path);
123 input.pathlen = strlen (close->path) + 1;
124 input.recno = close_rec->rec_tail.recno;
125 input.offset = close_rec->rec_kml_offset;
126 input.len = close_rec->rec_size;
127 input.generation = close->generation;
128 input.ino = close->ino;
131 CDEBUG(D_KML, "KML_DO_REINT::no space to save:%d < %d",
132 strlen (close->path) + 1, input.pathlen);
135 if (copy_to_user((char *)arg, &input, sizeof (input)))
142 int end_kml_reint (struct file *file, unsigned long arg)
144 /* Free KML buffer and related volume info */
153 struct presto_file_set *fset = NULL;
154 struct kml_fsdata *kml_fsdata = NULL;
159 if (copy_from_user(&input, (char *)arg, sizeof(input))) {
164 PRESTO_ALLOC(path, char *, input.namelen + 1);
169 if (copy_from_user(path, input.volname, input.namelen)) {
171 PRESTO_FREE(path, input.namelen + 1);
175 path[input.namelen] = '\0';
176 fset = kml_getfset (path);
177 PRESTO_FREE(path, input.namelen + 1);
179 kml_fsdata = FSET_GET_KMLDATA(fset);
180 delete_kmlrec (&kml_fsdata->kml_reint_cache);
182 /* kml reint support */
183 kml_fsdata->kml_reint_current = NULL;
184 kml_fsdata->kml_len = 0;
185 kml_fsdata->kml_reintpos = 0;
186 kml_fsdata->kml_count = 0;
188 input.newpos = kml_upc->newpos;
189 input.count = kml_upc->count;
190 if (copy_to_user((char *)arg, &input, sizeof (input)))