summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2015-04-21 14:52:26 -0400
committerRichard Weinberger <richard@nod.at>2015-05-31 07:23:08 -0400
commitf74a14e870c80d6261afed66d4bad779c1213e03 (patch)
tree93b176482eaa49113a583ff9f690085134bcd6e9
parent89520d999683cb945d7540efd0944b3af2db9a54 (diff)
um: Remove hppfs
hppfs (honeypot procfs) was an attempt to use UML as honeypot. It was never stable nor in heavy use. As Al Viro and Christoph Hellwig pointed some major issues out it is better to let it die. Signed-off-by: Richard Weinberger <richard@nod.at>
-rw-r--r--arch/um/Kconfig.um15
-rw-r--r--fs/Makefile1
-rw-r--r--fs/hppfs/Makefile6
-rw-r--r--fs/hppfs/hppfs.c766
4 files changed, 0 insertions, 788 deletions
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um
index 6e67847f5272..bd5459ce77b1 100644
--- a/arch/um/Kconfig.um
+++ b/arch/um/Kconfig.um
@@ -44,21 +44,6 @@ config HOSTFS
44 If you'd like to be able to work with files stored on the host, 44 If you'd like to be able to work with files stored on the host,
45 say Y or M here; otherwise say N. 45 say Y or M here; otherwise say N.
46 46
47config HPPFS
48 tristate "HoneyPot ProcFS"
49 depends on PROC_FS
50 help
51 hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
52 entries to be overridden, removed, or fabricated from the host.
53 Its purpose is to allow a UML to appear to be a physical machine
54 by removing or changing anything in /proc which gives away the
55 identity of a UML.
56
57 See <http://user-mode-linux.sf.net/old/hppfs.html> for more information.
58
59 You only need this if you are setting up a UML honeypot. Otherwise,
60 it is safe to say 'N' here.
61
62config MCONSOLE 47config MCONSOLE
63 bool "Management console" 48 bool "Management console"
64 default y 49 default y
diff --git a/fs/Makefile b/fs/Makefile
index cb92fd4c3172..cb20e4bf2303 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -115,7 +115,6 @@ obj-$(CONFIG_AFS_FS) += afs/
115obj-$(CONFIG_NILFS2_FS) += nilfs2/ 115obj-$(CONFIG_NILFS2_FS) += nilfs2/
116obj-$(CONFIG_BEFS_FS) += befs/ 116obj-$(CONFIG_BEFS_FS) += befs/
117obj-$(CONFIG_HOSTFS) += hostfs/ 117obj-$(CONFIG_HOSTFS) += hostfs/
118obj-$(CONFIG_HPPFS) += hppfs/
119obj-$(CONFIG_CACHEFILES) += cachefiles/ 118obj-$(CONFIG_CACHEFILES) += cachefiles/
120obj-$(CONFIG_DEBUG_FS) += debugfs/ 119obj-$(CONFIG_DEBUG_FS) += debugfs/
121obj-$(CONFIG_TRACING) += tracefs/ 120obj-$(CONFIG_TRACING) += tracefs/
diff --git a/fs/hppfs/Makefile b/fs/hppfs/Makefile
deleted file mode 100644
index 3a982bd975d2..000000000000
--- a/fs/hppfs/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
1#
2# Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3# Licensed under the GPL
4#
5
6obj-$(CONFIG_HPPFS) += hppfs.o
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
deleted file mode 100644
index fa2bd5366ecf..000000000000
--- a/fs/hppfs/hppfs.c
+++ /dev/null
@@ -1,766 +0,0 @@
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 <linux/pid_namespace.h>
19#include <linux/namei.h>
20#include <asm/uaccess.h>
21#include <os.h>
22
23static struct inode *get_inode(struct super_block *, struct dentry *);
24
25struct hppfs_data {
26 struct list_head list;
27 char contents[PAGE_SIZE - sizeof(struct list_head)];
28};
29
30struct hppfs_private {
31 struct file *proc_file;
32 int host_fd;
33 loff_t len;
34 struct hppfs_data *contents;
35};
36
37struct hppfs_inode_info {
38 struct dentry *proc_dentry;
39 struct inode vfs_inode;
40};
41
42static 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
49static const struct super_operations hppfs_sbops;
50
51static int is_pid(struct dentry *dentry)
52{
53 struct super_block *sb;
54 int i;
55
56 sb = dentry->d_sb;
57 if (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
67static 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, root_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 root_len = strlen(root);
85 len += root_len;
86 name = kmalloc(len + extra + 1, GFP_KERNEL);
87 if (name == NULL)
88 return NULL;
89
90 name[len] = '\0';
91 parent = dentry;
92 while (parent->d_parent != parent) {
93 if (is_pid(parent)) {
94 seg_name = "pid";
95 seg_len = strlen(seg_name);
96 }
97 else {
98 seg_name = parent->d_name.name;
99 seg_len = parent->d_name.len;
100 }
101
102 len -= seg_len + 1;
103 name[len] = '/';
104 memcpy(&name[len + 1], seg_name, seg_len);
105 parent = parent->d_parent;
106 }
107 memcpy(name, root, root_len);
108 return name;
109}
110
111static int file_removed(struct dentry *dentry, const char *file)
112{
113 char *host_file;
114 int extra, fd;
115
116 extra = 0;
117 if (file != NULL)
118 extra += strlen(file) + 1;
119
120 host_file = dentry_name(dentry, extra + strlen("/remove"));
121 if (host_file == NULL) {
122 printk(KERN_ERR "file_removed : allocation failed\n");
123 return -ENOMEM;
124 }
125
126 if (file != NULL) {
127 strcat(host_file, "/");
128 strcat(host_file, file);
129 }
130 strcat(host_file, "/remove");
131
132 fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
133 kfree(host_file);
134 if (fd > 0) {
135 os_close_file(fd);
136 return 1;
137 }
138 return 0;
139}
140
141static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
142 unsigned int flags)
143{
144 struct dentry *proc_dentry, *parent;
145 struct qstr *name = &dentry->d_name;
146 struct inode *inode;
147 int err, deleted;
148
149 deleted = file_removed(dentry, NULL);
150 if (deleted < 0)
151 return ERR_PTR(deleted);
152 else if (deleted)
153 return ERR_PTR(-ENOENT);
154
155 parent = HPPFS_I(ino)->proc_dentry;
156 mutex_lock(&d_inode(parent)->i_mutex);
157 proc_dentry = lookup_one_len(name->name, parent, name->len);
158 mutex_unlock(&d_inode(parent)->i_mutex);
159
160 if (IS_ERR(proc_dentry))
161 return proc_dentry;
162
163 err = -ENOMEM;
164 inode = get_inode(ino->i_sb, proc_dentry);
165 if (!inode)
166 goto out;
167
168 d_add(dentry, inode);
169 return NULL;
170
171 out:
172 return ERR_PTR(err);
173}
174
175static const struct inode_operations hppfs_file_iops = {
176};
177
178static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count,
179 loff_t *ppos, int is_user)
180{
181 ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
182 ssize_t n;
183
184 read = file_inode(file)->i_fop->read;
185
186 if (!is_user)
187 set_fs(KERNEL_DS);
188
189 n = (*read)(file, buf, count, &file->f_pos);
190
191 if (!is_user)
192 set_fs(USER_DS);
193
194 if (ppos)
195 *ppos = file->f_pos;
196 return n;
197}
198
199static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count)
200{
201 ssize_t n;
202 int cur, err;
203 char *new_buf;
204
205 n = -ENOMEM;
206 new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
207 if (new_buf == NULL) {
208 printk(KERN_ERR "hppfs_read_file : kmalloc failed\n");
209 goto out;
210 }
211 n = 0;
212 while (count > 0) {
213 cur = min_t(ssize_t, count, PAGE_SIZE);
214 err = os_read_file(fd, new_buf, cur);
215 if (err < 0) {
216 printk(KERN_ERR "hppfs_read : read failed, "
217 "errno = %d\n", err);
218 n = err;
219 goto out_free;
220 } else if (err == 0)
221 break;
222
223 if (copy_to_user(buf, new_buf, err)) {
224 n = -EFAULT;
225 goto out_free;
226 }
227 n += err;
228 count -= err;
229 }
230 out_free:
231 kfree(new_buf);
232 out:
233 return n;
234}
235
236static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
237 loff_t *ppos)
238{
239 struct hppfs_private *hppfs = file->private_data;
240 struct hppfs_data *data;
241 loff_t off;
242 int err;
243
244 if (hppfs->contents != NULL) {
245 int rem;
246
247 if (*ppos >= hppfs->len)
248 return 0;
249
250 data = hppfs->contents;
251 off = *ppos;
252 while (off >= sizeof(data->contents)) {
253 data = list_entry(data->list.next, struct hppfs_data,
254 list);
255 off -= sizeof(data->contents);
256 }
257
258 if (off + count > hppfs->len)
259 count = hppfs->len - off;
260 rem = copy_to_user(buf, &data->contents[off], count);
261 *ppos += count - rem;
262 if (rem > 0)
263 return -EFAULT;
264 } else if (hppfs->host_fd != -1) {
265 err = os_seek_file(hppfs->host_fd, *ppos);
266 if (err) {
267 printk(KERN_ERR "hppfs_read : seek failed, "
268 "errno = %d\n", err);
269 return err;
270 }
271 err = hppfs_read_file(hppfs->host_fd, buf, count);
272 if (err < 0) {
273 printk(KERN_ERR "hppfs_read: read failed: %d\n", err);
274 return err;
275 }
276 count = err;
277 if (count > 0)
278 *ppos += count;
279 }
280 else count = read_proc(hppfs->proc_file, buf, count, ppos, 1);
281
282 return count;
283}
284
285static ssize_t hppfs_write(struct file *file, const char __user *buf,
286 size_t len, loff_t *ppos)
287{
288 struct hppfs_private *data = file->private_data;
289 struct file *proc_file = data->proc_file;
290 ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
291
292 write = file_inode(proc_file)->i_fop->write;
293 return (*write)(proc_file, buf, len, ppos);
294}
295
296static int open_host_sock(char *host_file, int *filter_out)
297{
298 char *end;
299 int fd;
300
301 end = &host_file[strlen(host_file)];
302 strcpy(end, "/rw");
303 *filter_out = 1;
304 fd = os_connect_socket(host_file);
305 if (fd > 0)
306 return fd;
307
308 strcpy(end, "/r");
309 *filter_out = 0;
310 fd = os_connect_socket(host_file);
311 return fd;
312}
313
314static void free_contents(struct hppfs_data *head)
315{
316 struct hppfs_data *data;
317 struct list_head *ele, *next;
318
319 if (head == NULL)
320 return;
321
322 list_for_each_safe(ele, next, &head->list) {
323 data = list_entry(ele, struct hppfs_data, list);
324 kfree(data);
325 }
326 kfree(head);
327}
328
329static struct hppfs_data *hppfs_get_data(int fd, int filter,
330 struct file *proc_file,
331 struct file *hppfs_file,
332 loff_t *size_out)
333{
334 struct hppfs_data *data, *new, *head;
335 int n, err;
336
337 err = -ENOMEM;
338 data = kmalloc(sizeof(*data), GFP_KERNEL);
339 if (data == NULL) {
340 printk(KERN_ERR "hppfs_get_data : head allocation failed\n");
341 goto failed;
342 }
343
344 INIT_LIST_HEAD(&data->list);
345
346 head = data;
347 *size_out = 0;
348
349 if (filter) {
350 while ((n = read_proc(proc_file, data->contents,
351 sizeof(data->contents), NULL, 0)) > 0)
352 os_write_file(fd, data->contents, n);
353 err = os_shutdown_socket(fd, 0, 1);
354 if (err) {
355 printk(KERN_ERR "hppfs_get_data : failed to shut down "
356 "socket\n");
357 goto failed_free;
358 }
359 }
360 while (1) {
361 n = os_read_file(fd, data->contents, sizeof(data->contents));
362 if (n < 0) {
363 err = n;
364 printk(KERN_ERR "hppfs_get_data : read failed, "
365 "errno = %d\n", err);
366 goto failed_free;
367 } else if (n == 0)
368 break;
369
370 *size_out += n;
371
372 if (n < sizeof(data->contents))
373 break;
374
375 new = kmalloc(sizeof(*data), GFP_KERNEL);
376 if (new == 0) {
377 printk(KERN_ERR "hppfs_get_data : data allocation "
378 "failed\n");
379 err = -ENOMEM;
380 goto failed_free;
381 }
382
383 INIT_LIST_HEAD(&new->list);
384 list_add(&new->list, &data->list);
385 data = new;
386 }
387 return head;
388
389 failed_free:
390 free_contents(head);
391 failed:
392 return ERR_PTR(err);
393}
394
395static struct hppfs_private *hppfs_data(void)
396{
397 struct hppfs_private *data;
398
399 data = kmalloc(sizeof(*data), GFP_KERNEL);
400 if (data == NULL)
401 return data;
402
403 *data = ((struct hppfs_private ) { .host_fd = -1,
404 .len = -1,
405 .contents = NULL } );
406 return data;
407}
408
409static int file_mode(int fmode)
410{
411 if (fmode == (FMODE_READ | FMODE_WRITE))
412 return O_RDWR;
413 if (fmode == FMODE_READ)
414 return O_RDONLY;
415 if (fmode == FMODE_WRITE)
416 return O_WRONLY;
417 return 0;
418}
419
420static int hppfs_open(struct inode *inode, struct file *file)
421{
422 const struct cred *cred = file->f_cred;
423 struct hppfs_private *data;
424 struct path path;
425 char *host_file;
426 int err, fd, type, filter;
427
428 err = -ENOMEM;
429 data = hppfs_data();
430 if (data == NULL)
431 goto out;
432
433 host_file = dentry_name(file->f_path.dentry, strlen("/rw"));
434 if (host_file == NULL)
435 goto out_free2;
436
437 path.mnt = inode->i_sb->s_fs_info;
438 path.dentry = HPPFS_I(inode)->proc_dentry;
439
440 data->proc_file = dentry_open(&path, file_mode(file->f_mode), cred);
441 err = PTR_ERR(data->proc_file);
442 if (IS_ERR(data->proc_file))
443 goto out_free1;
444
445 type = os_file_type(host_file);
446 if (type == OS_TYPE_FILE) {
447 fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
448 if (fd >= 0)
449 data->host_fd = fd;
450 else
451 printk(KERN_ERR "hppfs_open : failed to open '%s', "
452 "errno = %d\n", host_file, -fd);
453
454 data->contents = NULL;
455 } else if (type == OS_TYPE_DIR) {
456 fd = open_host_sock(host_file, &filter);
457 if (fd > 0) {
458 data->contents = hppfs_get_data(fd, filter,
459 data->proc_file,
460 file, &data->len);
461 if (!IS_ERR(data->contents))
462 data->host_fd = fd;
463 } else
464 printk(KERN_ERR "hppfs_open : failed to open a socket "
465 "in '%s', errno = %d\n", host_file, -fd);
466 }
467 kfree(host_file);
468
469 file->private_data = data;
470 return 0;
471
472 out_free1:
473 kfree(host_file);
474 out_free2:
475 free_contents(data->contents);
476 kfree(data);
477 out:
478 return err;
479}
480
481static int hppfs_dir_open(struct inode *inode, struct file *file)
482{
483 const struct cred *cred = file->f_cred;
484 struct hppfs_private *data;
485 struct path path;
486 int err;
487
488 err = -ENOMEM;
489 data = hppfs_data();
490 if (data == NULL)
491 goto out;
492
493 path.mnt = inode->i_sb->s_fs_info;
494 path.dentry = HPPFS_I(inode)->proc_dentry;
495 data->proc_file = dentry_open(&path, file_mode(file->f_mode), cred);
496 err = PTR_ERR(data->proc_file);
497 if (IS_ERR(data->proc_file))
498 goto out_free;
499
500 file->private_data = data;
501 return 0;
502
503 out_free:
504 kfree(data);
505 out:
506 return err;
507}
508
509static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
510{
511 struct hppfs_private *data = file->private_data;
512 struct file *proc_file = data->proc_file;
513 loff_t (*llseek)(struct file *, loff_t, int);
514 loff_t ret;
515
516 llseek = file_inode(proc_file)->i_fop->llseek;
517 if (llseek != NULL) {
518 ret = (*llseek)(proc_file, off, where);
519 if (ret < 0)
520 return ret;
521 }
522
523 return default_llseek(file, off, where);
524}
525
526static int hppfs_release(struct inode *inode, struct file *file)
527{
528 struct hppfs_private *data = file->private_data;
529 struct file *proc_file = data->proc_file;
530 if (proc_file)
531 fput(proc_file);
532 kfree(data);
533 return 0;
534}
535
536static const struct file_operations hppfs_file_fops = {
537 .owner = NULL,
538 .llseek = hppfs_llseek,
539 .read = hppfs_read,
540 .write = hppfs_write,
541 .open = hppfs_open,
542 .release = hppfs_release,
543};
544
545struct hppfs_dirent {
546 struct dir_context ctx;
547 struct dir_context *caller;
548 struct dentry *dentry;
549};
550
551static int hppfs_filldir(struct dir_context *ctx, const char *name, int size,
552 loff_t offset, u64 inode, unsigned int type)
553{
554 struct hppfs_dirent *dirent =
555 container_of(ctx, struct hppfs_dirent, ctx);
556
557 if (file_removed(dirent->dentry, name))
558 return 0;
559
560 dirent->caller->pos = dirent->ctx.pos;
561 return !dir_emit(dirent->caller, name, size, inode, type);
562}
563
564static int hppfs_readdir(struct file *file, struct dir_context *ctx)
565{
566 struct hppfs_private *data = file->private_data;
567 struct file *proc_file = data->proc_file;
568 struct hppfs_dirent d = {
569 .ctx.actor = hppfs_filldir,
570 .caller = ctx,
571 .dentry = file->f_path.dentry
572 };
573 int err;
574 proc_file->f_pos = ctx->pos;
575 err = iterate_dir(proc_file, &d.ctx);
576 ctx->pos = d.ctx.pos;
577 return err;
578}
579
580static const struct file_operations hppfs_dir_fops = {
581 .owner = NULL,
582 .iterate = hppfs_readdir,
583 .open = hppfs_dir_open,
584 .llseek = default_llseek,
585 .release = hppfs_release,
586};
587
588static int hppfs_statfs(struct dentry *dentry, struct kstatfs *sf)
589{
590 sf->f_blocks = 0;
591 sf->f_bfree = 0;
592 sf->f_bavail = 0;
593 sf->f_files = 0;
594 sf->f_ffree = 0;
595 sf->f_type = HPPFS_SUPER_MAGIC;
596 return 0;
597}
598
599static struct inode *hppfs_alloc_inode(struct super_block *sb)
600{
601 struct hppfs_inode_info *hi;
602
603 hi = kmalloc(sizeof(*hi), GFP_KERNEL);
604 if (!hi)
605 return NULL;
606
607 hi->proc_dentry = NULL;
608 inode_init_once(&hi->vfs_inode);
609 return &hi->vfs_inode;
610}
611
612void hppfs_evict_inode(struct inode *ino)
613{
614 clear_inode(ino);
615 dput(HPPFS_I(ino)->proc_dentry);
616 mntput(ino->i_sb->s_fs_info);
617}
618
619static void hppfs_i_callback(struct rcu_head *head)
620{
621 struct inode *inode = container_of(head, struct inode, i_rcu);
622 kfree(HPPFS_I(inode));
623}
624
625static void hppfs_destroy_inode(struct inode *inode)
626{
627 call_rcu(&inode->i_rcu, hppfs_i_callback);
628}
629
630static const struct super_operations hppfs_sbops = {
631 .alloc_inode = hppfs_alloc_inode,
632 .destroy_inode = hppfs_destroy_inode,
633 .evict_inode = hppfs_evict_inode,
634 .statfs = hppfs_statfs,
635};
636
637static int hppfs_readlink(struct dentry *dentry, char __user *buffer,
638 int buflen)
639{
640 struct dentry *proc_dentry = HPPFS_I(d_inode(dentry))->proc_dentry;
641 return d_inode(proc_dentry)->i_op->readlink(proc_dentry, buffer,
642 buflen);
643}
644
645static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
646{
647 struct dentry *proc_dentry = HPPFS_I(d_inode(dentry))->proc_dentry;
648
649 return d_inode(proc_dentry)->i_op->follow_link(proc_dentry, nd);
650}
651
652static void hppfs_put_link(struct dentry *dentry, struct nameidata *nd,
653 void *cookie)
654{
655 struct dentry *proc_dentry = HPPFS_I(d_inode(dentry))->proc_dentry;
656
657 if (d_inode(proc_dentry)->i_op->put_link)
658 d_inode(proc_dentry)->i_op->put_link(proc_dentry, nd, cookie);
659}
660
661static const struct inode_operations hppfs_dir_iops = {
662 .lookup = hppfs_lookup,
663};
664
665static const struct inode_operations hppfs_link_iops = {
666 .readlink = hppfs_readlink,
667 .follow_link = hppfs_follow_link,
668 .put_link = hppfs_put_link,
669};
670
671static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
672{
673 struct inode *proc_ino = d_inode(dentry);
674 struct inode *inode = new_inode(sb);
675
676 if (!inode) {
677 dput(dentry);
678 return NULL;
679 }
680
681 if (d_is_dir(dentry)) {
682 inode->i_op = &hppfs_dir_iops;
683 inode->i_fop = &hppfs_dir_fops;
684 } else if (d_is_symlink(dentry)) {
685 inode->i_op = &hppfs_link_iops;
686 inode->i_fop = &hppfs_file_fops;
687 } else {
688 inode->i_op = &hppfs_file_iops;
689 inode->i_fop = &hppfs_file_fops;
690 }
691
692 HPPFS_I(inode)->proc_dentry = dentry;
693
694 inode->i_uid = proc_ino->i_uid;
695 inode->i_gid = proc_ino->i_gid;
696 inode->i_atime = proc_ino->i_atime;
697 inode->i_mtime = proc_ino->i_mtime;
698 inode->i_ctime = proc_ino->i_ctime;
699 inode->i_ino = proc_ino->i_ino;
700 inode->i_mode = proc_ino->i_mode;
701 set_nlink(inode, proc_ino->i_nlink);
702 inode->i_size = proc_ino->i_size;
703 inode->i_blocks = proc_ino->i_blocks;
704
705 return inode;
706}
707
708static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
709{
710 struct inode *root_inode;
711 struct vfsmount *proc_mnt;
712 int err = -ENOENT;
713
714 proc_mnt = mntget(task_active_pid_ns(current)->proc_mnt);
715 if (IS_ERR(proc_mnt))
716 goto out;
717
718 sb->s_blocksize = 1024;
719 sb->s_blocksize_bits = 10;
720 sb->s_magic = HPPFS_SUPER_MAGIC;
721 sb->s_op = &hppfs_sbops;
722 sb->s_fs_info = proc_mnt;
723
724 err = -ENOMEM;
725 root_inode = get_inode(sb, dget(proc_mnt->mnt_root));
726 sb->s_root = d_make_root(root_inode);
727 if (!sb->s_root)
728 goto out_mntput;
729
730 return 0;
731
732 out_mntput:
733 mntput(proc_mnt);
734 out:
735 return(err);
736}
737
738static struct dentry *hppfs_read_super(struct file_system_type *type,
739 int flags, const char *dev_name,
740 void *data)
741{
742 return mount_nodev(type, flags, data, hppfs_fill_super);
743}
744
745static struct file_system_type hppfs_type = {
746 .owner = THIS_MODULE,
747 .name = "hppfs",
748 .mount = hppfs_read_super,
749 .kill_sb = kill_anon_super,
750 .fs_flags = 0,
751};
752MODULE_ALIAS_FS("hppfs");
753
754static int __init init_hppfs(void)
755{
756 return register_filesystem(&hppfs_type);
757}
758
759static void __exit exit_hppfs(void)
760{
761 unregister_filesystem(&hppfs_type);
762}
763
764module_init(init_hppfs)
765module_exit(exit_hppfs)
766MODULE_LICENSE("GPL");