]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - fs/hppfs/hppfs_kern.c
hppfs pass vfsmount to dentry_open()
[linux-2.6-omap-h63xx.git] / fs / hppfs / hppfs_kern.c
1 /*
2  * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3  * Licensed under the GPL
4  */
5
6 #include <linux/ctype.h>
7 #include <linux/dcache.h>
8 #include <linux/file.h>
9 #include <linux/fs.h>
10 #include <linux/init.h>
11 #include <linux/kernel.h>
12 #include <linux/list.h>
13 #include <linux/module.h>
14 #include <linux/mount.h>
15 #include <linux/slab.h>
16 #include <linux/statfs.h>
17 #include <linux/types.h>
18 #include <asm/uaccess.h>
19 #include "os.h"
20
21 static int init_inode(struct inode *inode, struct dentry *dentry,
22                       struct vfsmount *mnt);
23
24 struct hppfs_data {
25         struct list_head list;
26         char contents[PAGE_SIZE - sizeof(struct list_head)];
27 };
28
29 struct hppfs_private {
30         struct file *proc_file;
31         int host_fd;
32         loff_t len;
33         struct hppfs_data *contents;
34 };
35
36 struct hppfs_inode_info {
37         struct dentry *proc_dentry;
38         struct vfsmount *proc_mnt;
39         struct inode vfs_inode;
40 };
41
42 static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
43 {
44         return container_of(inode, struct hppfs_inode_info, vfs_inode);
45 }
46
47 #define HPPFS_SUPER_MAGIC 0xb00000ee
48
49 static const struct super_operations hppfs_sbops;
50
51 static int is_pid(struct dentry *dentry)
52 {
53         struct super_block *sb;
54         int i;
55
56         sb = dentry->d_sb;
57         if ((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
58                 return 0;
59
60         for (i = 0; i < dentry->d_name.len; i++) {
61                 if (!isdigit(dentry->d_name.name[i]))
62                         return 0;
63         }
64         return 1;
65 }
66
67 static char *dentry_name(struct dentry *dentry, int extra)
68 {
69         struct dentry *parent;
70         char *root, *name;
71         const char *seg_name;
72         int len, seg_len;
73
74         len = 0;
75         parent = dentry;
76         while (parent->d_parent != parent) {
77                 if (is_pid(parent))
78                         len += strlen("pid") + 1;
79                 else len += parent->d_name.len + 1;
80                 parent = parent->d_parent;
81         }
82
83         root = "proc";
84         len += strlen(root);
85         name = kmalloc(len + extra + 1, GFP_KERNEL);
86         if (name == NULL)
87                 return NULL;
88
89         name[len] = '\0';
90         parent = dentry;
91         while (parent->d_parent != parent) {
92                 if (is_pid(parent)) {
93                         seg_name = "pid";
94                         seg_len = strlen("pid");
95                 }
96                 else {
97                         seg_name = parent->d_name.name;
98                         seg_len = parent->d_name.len;
99                 }
100
101                 len -= seg_len + 1;
102                 name[len] = '/';
103                 strncpy(&name[len + 1], seg_name, seg_len);
104                 parent = parent->d_parent;
105         }
106         strncpy(name, root, strlen(root));
107         return name;
108 }
109
110 static int file_removed(struct dentry *dentry, const char *file)
111 {
112         char *host_file;
113         int extra, fd;
114
115         extra = 0;
116         if (file != NULL)
117                 extra += strlen(file) + 1;
118
119         host_file = dentry_name(dentry, extra + strlen("/remove"));
120         if (host_file == NULL) {
121                 printk(KERN_ERR "file_removed : allocation failed\n");
122                 return -ENOMEM;
123         }
124
125         if (file != NULL) {
126                 strcat(host_file, "/");
127                 strcat(host_file, file);
128         }
129         strcat(host_file, "/remove");
130
131         fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
132         kfree(host_file);
133         if (fd > 0) {
134                 os_close_file(fd);
135                 return 1;
136         }
137         return 0;
138 }
139
140 static void hppfs_read_inode(struct inode *ino)
141 {
142         struct inode *proc_ino;
143
144         if (HPPFS_I(ino)->proc_dentry == NULL)
145                 return;
146
147         proc_ino = HPPFS_I(ino)->proc_dentry->d_inode;
148         ino->i_uid = proc_ino->i_uid;
149         ino->i_gid = proc_ino->i_gid;
150         ino->i_atime = proc_ino->i_atime;
151         ino->i_mtime = proc_ino->i_mtime;
152         ino->i_ctime = proc_ino->i_ctime;
153         ino->i_ino = proc_ino->i_ino;
154         ino->i_mode = proc_ino->i_mode;
155         ino->i_nlink = proc_ino->i_nlink;
156         ino->i_size = proc_ino->i_size;
157         ino->i_blocks = proc_ino->i_blocks;
158 }
159
160 static struct inode *hppfs_iget(struct super_block *sb)
161 {
162         struct inode *inode;
163
164         inode = iget_locked(sb, 0);
165         if (!inode)
166                 return ERR_PTR(-ENOMEM);
167         if (inode->i_state & I_NEW) {
168                 hppfs_read_inode(inode);
169                 unlock_new_inode(inode);
170         }
171         return inode;
172 }
173
174 static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
175                                   struct nameidata *nd)
176 {
177         struct dentry *proc_dentry, *new, *parent;
178         struct inode *inode;
179         int err, deleted;
180
181         deleted = file_removed(dentry, NULL);
182         if (deleted < 0)
183                 return ERR_PTR(deleted);
184         else if (deleted)
185                 return ERR_PTR(-ENOENT);
186
187         err = -ENOMEM;
188         parent = HPPFS_I(ino)->proc_dentry;
189         mutex_lock(&parent->d_inode->i_mutex);
190         proc_dentry = d_lookup(parent, &dentry->d_name);
191         if (proc_dentry == NULL) {
192                 proc_dentry = d_alloc(parent, &dentry->d_name);
193                 if (proc_dentry == NULL) {
194                         mutex_unlock(&parent->d_inode->i_mutex);
195                         goto out;
196                 }
197                 new = (*parent->d_inode->i_op->lookup)(parent->d_inode,
198                                                        proc_dentry, NULL);
199                 if (new) {
200                         dput(proc_dentry);
201                         proc_dentry = new;
202                 }
203         }
204         mutex_unlock(&parent->d_inode->i_mutex);
205
206         if (IS_ERR(proc_dentry))
207                 return proc_dentry;
208
209         inode = hppfs_iget(ino->i_sb);
210         if (IS_ERR(inode)) {
211                 err = PTR_ERR(inode);
212                 goto out_dput;
213         }
214
215         err = init_inode(inode, proc_dentry, HPPFS_I(ino)->proc_mnt);
216         if (err)
217                 goto out_put;
218
219         hppfs_read_inode(inode);
220
221         d_add(dentry, inode);
222         return NULL;
223
224  out_put:
225         iput(inode);
226  out_dput:
227         dput(proc_dentry);
228  out:
229         return ERR_PTR(err);
230 }
231
232 static const struct inode_operations hppfs_file_iops = {
233 };
234
235 static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count,
236                          loff_t *ppos, int is_user)
237 {
238         ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
239         ssize_t n;
240
241         read = file->f_path.dentry->d_inode->i_fop->read;
242
243         if (!is_user)
244                 set_fs(KERNEL_DS);
245
246         n = (*read)(file, buf, count, &file->f_pos);
247
248         if (!is_user)
249                 set_fs(USER_DS);
250
251         if (ppos)
252                 *ppos = file->f_pos;
253         return n;
254 }
255
256 static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count)
257 {
258         ssize_t n;
259         int cur, err;
260         char *new_buf;
261
262         n = -ENOMEM;
263         new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
264         if (new_buf == NULL) {
265                 printk(KERN_ERR "hppfs_read_file : kmalloc failed\n");
266                 goto out;
267         }
268         n = 0;
269         while (count > 0) {
270                 cur = min_t(ssize_t, count, PAGE_SIZE);
271                 err = os_read_file(fd, new_buf, cur);
272                 if (err < 0) {
273                         printk(KERN_ERR "hppfs_read : read failed, "
274                                "errno = %d\n", err);
275                         n = err;
276                         goto out_free;
277                 } else if (err == 0)
278                         break;
279
280                 if (copy_to_user(buf, new_buf, err)) {
281                         n = -EFAULT;
282                         goto out_free;
283                 }
284                 n += err;
285                 count -= err;
286         }
287  out_free:
288         kfree(new_buf);
289  out:
290         return n;
291 }
292
293 static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
294                           loff_t *ppos)
295 {
296         struct hppfs_private *hppfs = file->private_data;
297         struct hppfs_data *data;
298         loff_t off;
299         int err;
300
301         if (hppfs->contents != NULL) {
302                 if (*ppos >= hppfs->len)
303                         return 0;
304
305                 data = hppfs->contents;
306                 off = *ppos;
307                 while (off >= sizeof(data->contents)) {
308                         data = list_entry(data->list.next, struct hppfs_data,
309                                           list);
310                         off -= sizeof(data->contents);
311                 }
312
313                 if (off + count > hppfs->len)
314                         count = hppfs->len - off;
315                 copy_to_user(buf, &data->contents[off], count);
316                 *ppos += count;
317         } else if (hppfs->host_fd != -1) {
318                 err = os_seek_file(hppfs->host_fd, *ppos);
319                 if (err) {
320                         printk(KERN_ERR "hppfs_read : seek failed, "
321                                "errno = %d\n", err);
322                         return err;
323                 }
324                 count = hppfs_read_file(hppfs->host_fd, buf, count);
325                 if (count > 0)
326                         *ppos += count;
327         }
328         else count = read_proc(hppfs->proc_file, buf, count, ppos, 1);
329
330         return count;
331 }
332
333 static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len,
334                            loff_t *ppos)
335 {
336         struct hppfs_private *data = file->private_data;
337         struct file *proc_file = data->proc_file;
338         ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
339         int err;
340
341         write = proc_file->f_path.dentry->d_inode->i_fop->write;
342
343         proc_file->f_pos = file->f_pos;
344         err = (*write)(proc_file, buf, len, &proc_file->f_pos);
345         file->f_pos = proc_file->f_pos;
346
347         return err;
348 }
349
350 static int open_host_sock(char *host_file, int *filter_out)
351 {
352         char *end;
353         int fd;
354
355         end = &host_file[strlen(host_file)];
356         strcpy(end, "/rw");
357         *filter_out = 1;
358         fd = os_connect_socket(host_file);
359         if (fd > 0)
360                 return fd;
361
362         strcpy(end, "/r");
363         *filter_out = 0;
364         fd = os_connect_socket(host_file);
365         return fd;
366 }
367
368 static void free_contents(struct hppfs_data *head)
369 {
370         struct hppfs_data *data;
371         struct list_head *ele, *next;
372
373         if (head == NULL)
374                 return;
375
376         list_for_each_safe(ele, next, &head->list) {
377                 data = list_entry(ele, struct hppfs_data, list);
378                 kfree(data);
379         }
380         kfree(head);
381 }
382
383 static struct hppfs_data *hppfs_get_data(int fd, int filter,
384                                          struct file *proc_file,
385                                          struct file *hppfs_file,
386                                          loff_t *size_out)
387 {
388         struct hppfs_data *data, *new, *head;
389         int n, err;
390
391         err = -ENOMEM;
392         data = kmalloc(sizeof(*data), GFP_KERNEL);
393         if (data == NULL) {
394                 printk(KERN_ERR "hppfs_get_data : head allocation failed\n");
395                 goto failed;
396         }
397
398         INIT_LIST_HEAD(&data->list);
399
400         head = data;
401         *size_out = 0;
402
403         if (filter) {
404                 while ((n = read_proc(proc_file, data->contents,
405                                      sizeof(data->contents), NULL, 0)) > 0)
406                         os_write_file(fd, data->contents, n);
407                 err = os_shutdown_socket(fd, 0, 1);
408                 if (err) {
409                         printk(KERN_ERR "hppfs_get_data : failed to shut down "
410                                "socket\n");
411                         goto failed_free;
412                 }
413         }
414         while (1) {
415                 n = os_read_file(fd, data->contents, sizeof(data->contents));
416                 if (n < 0) {
417                         err = n;
418                         printk(KERN_ERR "hppfs_get_data : read failed, "
419                                "errno = %d\n", err);
420                         goto failed_free;
421                 } else if (n == 0)
422                         break;
423
424                 *size_out += n;
425
426                 if (n < sizeof(data->contents))
427                         break;
428
429                 new = kmalloc(sizeof(*data), GFP_KERNEL);
430                 if (new == 0) {
431                         printk(KERN_ERR "hppfs_get_data : data allocation "
432                                "failed\n");
433                         err = -ENOMEM;
434                         goto failed_free;
435                 }
436
437                 INIT_LIST_HEAD(&new->list);
438                 list_add(&new->list, &data->list);
439                 data = new;
440         }
441         return head;
442
443  failed_free:
444         free_contents(head);
445  failed:
446         return ERR_PTR(err);
447 }
448
449 static struct hppfs_private *hppfs_data(void)
450 {
451         struct hppfs_private *data;
452
453         data = kmalloc(sizeof(*data), GFP_KERNEL);
454         if (data == NULL)
455                 return data;
456
457         *data = ((struct hppfs_private ) { .host_fd             = -1,
458                                            .len                 = -1,
459                                            .contents            = NULL } );
460         return data;
461 }
462
463 static int file_mode(int fmode)
464 {
465         if (fmode == (FMODE_READ | FMODE_WRITE))
466                 return O_RDWR;
467         if (fmode == FMODE_READ)
468                 return O_RDONLY;
469         if (fmode == FMODE_WRITE)
470                 return O_WRONLY;
471         return 0;
472 }
473
474 static int hppfs_open(struct inode *inode, struct file *file)
475 {
476         struct hppfs_private *data;
477         struct dentry *proc_dentry;
478         struct vfsmount *proc_mnt;
479         char *host_file;
480         int err, fd, type, filter;
481
482         err = -ENOMEM;
483         data = hppfs_data();
484         if (data == NULL)
485                 goto out;
486
487         host_file = dentry_name(file->f_path.dentry, strlen("/rw"));
488         if (host_file == NULL)
489                 goto out_free2;
490
491         proc_dentry = HPPFS_I(inode)->proc_dentry;
492         proc_mnt = HPPFS_I(inode)->proc_mnt;
493
494         /* XXX This isn't closed anywhere */
495         data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
496                                       file_mode(file->f_mode));
497         err = PTR_ERR(data->proc_file);
498         if (IS_ERR(data->proc_file))
499                 goto out_free1;
500
501         type = os_file_type(host_file);
502         if (type == OS_TYPE_FILE) {
503                 fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
504                 if (fd >= 0)
505                         data->host_fd = fd;
506                 else
507                         printk(KERN_ERR "hppfs_open : failed to open '%s', "
508                                "errno = %d\n", host_file, -fd);
509
510                 data->contents = NULL;
511         } else if (type == OS_TYPE_DIR) {
512                 fd = open_host_sock(host_file, &filter);
513                 if (fd > 0) {
514                         data->contents = hppfs_get_data(fd, filter,
515                                                         data->proc_file,
516                                                         file, &data->len);
517                         if (!IS_ERR(data->contents))
518                                 data->host_fd = fd;
519                 } else
520                         printk(KERN_ERR "hppfs_open : failed to open a socket "
521                                "in '%s', errno = %d\n", host_file, -fd);
522         }
523         kfree(host_file);
524
525         file->private_data = data;
526         return 0;
527
528  out_free1:
529         kfree(host_file);
530  out_free2:
531         free_contents(data->contents);
532         kfree(data);
533  out:
534         return err;
535 }
536
537 static int hppfs_dir_open(struct inode *inode, struct file *file)
538 {
539         struct hppfs_private *data;
540         struct dentry *proc_dentry;
541         struct vfsmount *proc_mnt;
542         int err;
543
544         err = -ENOMEM;
545         data = hppfs_data();
546         if (data == NULL)
547                 goto out;
548
549         proc_dentry = HPPFS_I(inode)->proc_dentry;
550         proc_mnt = HPPFS_I(inode)->proc_mnt;
551         data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
552                                       file_mode(file->f_mode));
553         err = PTR_ERR(data->proc_file);
554         if (IS_ERR(data->proc_file))
555                 goto out_free;
556
557         file->private_data = data;
558         return 0;
559
560  out_free:
561         kfree(data);
562  out:
563         return err;
564 }
565
566 static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
567 {
568         struct hppfs_private *data = file->private_data;
569         struct file *proc_file = data->proc_file;
570         loff_t (*llseek)(struct file *, loff_t, int);
571         loff_t ret;
572
573         llseek = proc_file->f_path.dentry->d_inode->i_fop->llseek;
574         if (llseek != NULL) {
575                 ret = (*llseek)(proc_file, off, where);
576                 if (ret < 0)
577                         return ret;
578         }
579
580         return default_llseek(file, off, where);
581 }
582
583 static const struct file_operations hppfs_file_fops = {
584         .owner          = NULL,
585         .llseek         = hppfs_llseek,
586         .read           = hppfs_read,
587         .write          = hppfs_write,
588         .open           = hppfs_open,
589 };
590
591 struct hppfs_dirent {
592         void *vfs_dirent;
593         filldir_t filldir;
594         struct dentry *dentry;
595 };
596
597 static int hppfs_filldir(void *d, const char *name, int size,
598                          loff_t offset, u64 inode, unsigned int type)
599 {
600         struct hppfs_dirent *dirent = d;
601
602         if (file_removed(dirent->dentry, name))
603                 return 0;
604
605         return (*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
606                                   inode, type);
607 }
608
609 static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
610 {
611         struct hppfs_private *data = file->private_data;
612         struct file *proc_file = data->proc_file;
613         int (*readdir)(struct file *, void *, filldir_t);
614         struct hppfs_dirent dirent = ((struct hppfs_dirent)
615                                       { .vfs_dirent     = ent,
616                                         .filldir        = filldir,
617                                         .dentry         = file->f_path.dentry
618                                       });
619         int err;
620
621         readdir = proc_file->f_path.dentry->d_inode->i_fop->readdir;
622
623         proc_file->f_pos = file->f_pos;
624         err = (*readdir)(proc_file, &dirent, hppfs_filldir);
625         file->f_pos = proc_file->f_pos;
626
627         return err;
628 }
629
630 static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
631 {
632         return 0;
633 }
634
635 static const struct file_operations hppfs_dir_fops = {
636         .owner          = NULL,
637         .readdir        = hppfs_readdir,
638         .open           = hppfs_dir_open,
639         .fsync          = hppfs_fsync,
640 };
641
642 static int hppfs_statfs(struct dentry *dentry, struct kstatfs *sf)
643 {
644         sf->f_blocks = 0;
645         sf->f_bfree = 0;
646         sf->f_bavail = 0;
647         sf->f_files = 0;
648         sf->f_ffree = 0;
649         sf->f_type = HPPFS_SUPER_MAGIC;
650         return 0;
651 }
652
653 static struct inode *hppfs_alloc_inode(struct super_block *sb)
654 {
655         struct hppfs_inode_info *hi;
656
657         hi = kmalloc(sizeof(*hi), GFP_KERNEL);
658         if (!hi)
659                 return NULL;
660
661         hi->proc_dentry = NULL;
662         hi->proc_mnt = NULL;
663         inode_init_once(&hi->vfs_inode);
664         return &hi->vfs_inode;
665 }
666
667 void hppfs_delete_inode(struct inode *ino)
668 {
669         clear_inode(ino);
670 }
671
672 static void hppfs_destroy_inode(struct inode *inode)
673 {
674         kfree(HPPFS_I(inode));
675 }
676
677 static void hppfs_put_super(struct super_block *sb)
678 {
679         mntput(HPPFS_I(sb->s_root->d_inode)->proc_mnt);
680 }
681
682 static const struct super_operations hppfs_sbops = {
683         .alloc_inode    = hppfs_alloc_inode,
684         .destroy_inode  = hppfs_destroy_inode,
685         .delete_inode   = hppfs_delete_inode,
686         .statfs         = hppfs_statfs,
687         .put_super      = hppfs_put_super,
688 };
689
690 static int hppfs_readlink(struct dentry *dentry, char __user *buffer,
691                           int buflen)
692 {
693         struct file *proc_file;
694         struct dentry *proc_dentry;
695         struct vfsmount *proc_mnt;
696         int ret;
697
698         proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
699         proc_mnt = HPPFS_I(dentry->d_inode)->proc_mnt;
700
701         proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
702         if (IS_ERR(proc_file))
703                 return PTR_ERR(proc_file);
704
705         ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen);
706
707         fput(proc_file);
708
709         return ret;
710 }
711
712 static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
713 {
714         struct file *proc_file;
715         struct dentry *proc_dentry;
716         struct vfsmount *proc_mnt;
717         void *ret;
718
719         proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
720         proc_mnt = HPPFS_I(dentry->d_inode)->proc_mnt;
721
722         proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
723         if (IS_ERR(proc_file))
724                 return proc_file;
725
726         ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
727
728         fput(proc_file);
729
730         return ret;
731 }
732
733 static const struct inode_operations hppfs_dir_iops = {
734         .lookup         = hppfs_lookup,
735 };
736
737 static const struct inode_operations hppfs_link_iops = {
738         .readlink       = hppfs_readlink,
739         .follow_link    = hppfs_follow_link,
740 };
741
742 static int init_inode(struct inode *inode, struct dentry *dentry,
743                 struct vfsmount *mnt)
744 {
745         if (S_ISDIR(dentry->d_inode->i_mode)) {
746                 inode->i_op = &hppfs_dir_iops;
747                 inode->i_fop = &hppfs_dir_fops;
748         } else if (S_ISLNK(dentry->d_inode->i_mode)) {
749                 inode->i_op = &hppfs_link_iops;
750                 inode->i_fop = &hppfs_file_fops;
751         } else {
752                 inode->i_op = &hppfs_file_iops;
753                 inode->i_fop = &hppfs_file_fops;
754         }
755
756         HPPFS_I(inode)->proc_dentry = dentry;
757         HPPFS_I(inode)->proc_mnt = mnt;
758
759         return 0;
760 }
761
762 static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
763 {
764         struct inode *root_inode;
765         struct file_system_type *procfs;
766         struct vfsmount *proc_mnt;
767         int err;
768
769         err = -ENOENT;
770         procfs = get_fs_type("proc");
771         if (!procfs)
772                 goto out;
773
774         proc_mnt = vfs_kern_mount(procfs, 0, procfs->name, NULL);
775         put_filesystem(procfs);
776         if (IS_ERR(proc_mnt))
777                 goto out;
778
779         sb->s_blocksize = 1024;
780         sb->s_blocksize_bits = 10;
781         sb->s_magic = HPPFS_SUPER_MAGIC;
782         sb->s_op = &hppfs_sbops;
783
784         root_inode = hppfs_iget(sb);
785         if (IS_ERR(root_inode)) {
786                 err = PTR_ERR(root_inode);
787                 goto out;
788         }
789
790         err = init_inode(root_inode, proc_mnt->mnt_sb->s_root, proc_mnt);
791         if (err)
792                 goto out_iput;
793
794         err = -ENOMEM;
795         sb->s_root = d_alloc_root(root_inode);
796         if (!sb->s_root)
797                 goto out_iput;
798
799         hppfs_read_inode(root_inode);
800
801         return 0;
802
803  out_iput:
804         iput(root_inode);
805  out_mntput:
806         mntput(proc_mnt);
807  out:
808         return(err);
809 }
810
811 static int hppfs_read_super(struct file_system_type *type,
812                             int flags, const char *dev_name,
813                             void *data, struct vfsmount *mnt)
814 {
815         return get_sb_nodev(type, flags, data, hppfs_fill_super, mnt);
816 }
817
818 static struct file_system_type hppfs_type = {
819         .owner          = THIS_MODULE,
820         .name           = "hppfs",
821         .get_sb         = hppfs_read_super,
822         .kill_sb        = kill_anon_super,
823         .fs_flags       = 0,
824 };
825
826 static int __init init_hppfs(void)
827 {
828         return register_filesystem(&hppfs_type);
829 }
830
831 static void __exit exit_hppfs(void)
832 {
833         unregister_filesystem(&hppfs_type);
834 }
835
836 module_init(init_hppfs)
837 module_exit(exit_hppfs)
838 MODULE_LICENSE("GPL");