1
2
3
4
5
6
7
8
9#include <linux/fs.h>
10#include <linux/module.h>
11#include <linux/mm.h>
12#include <linux/pagemap.h>
13#include <linux/statfs.h>
14#include <linux/seq_file.h>
15#include <linux/mount.h>
16#include "hostfs.h"
17#include "init.h"
18#include "kern.h"
19
20struct hostfs_inode_info {
21 char *host_filename;
22 int fd;
23 fmode_t mode;
24 struct inode vfs_inode;
25};
26
27static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
28{
29 return list_entry(inode, struct hostfs_inode_info, vfs_inode);
30}
31
32#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode)
33
34static int hostfs_d_delete(struct dentry *dentry)
35{
36 return 1;
37}
38
39static const struct dentry_operations hostfs_dentry_ops = {
40 .d_delete = hostfs_d_delete,
41};
42
43
44static char *root_ino = "";
45static int append = 0;
46
47#define HOSTFS_SUPER_MAGIC 0x00c0ffee
48
49static const struct inode_operations hostfs_iops;
50static const struct inode_operations hostfs_dir_iops;
51static const struct address_space_operations hostfs_link_aops;
52
53#ifndef MODULE
54static int __init hostfs_args(char *options, int *add)
55{
56 char *ptr;
57
58 ptr = strchr(options, ',');
59 if (ptr != NULL)
60 *ptr++ = '\0';
61 if (*options != '\0')
62 root_ino = options;
63
64 options = ptr;
65 while (options) {
66 ptr = strchr(options, ',');
67 if (ptr != NULL)
68 *ptr++ = '\0';
69 if (*options != '\0') {
70 if (!strcmp(options, "append"))
71 append = 1;
72 else printf("hostfs_args - unsupported option - %s\n",
73 options);
74 }
75 options = ptr;
76 }
77 return 0;
78}
79
80__uml_setup("hostfs=", hostfs_args,
81"hostfs=<root dir>,<flags>,...\n"
82" This is used to set hostfs parameters. The root directory argument\n"
83" is used to confine all hostfs mounts to within the specified directory\n"
84" tree on the host. If this isn't specified, then a user inside UML can\n"
85" mount anything on the host that's accessible to the user that's running\n"
86" it.\n"
87" The only flag currently supported is 'append', which specifies that all\n"
88" files opened by hostfs will be opened in append mode.\n\n"
89);
90#endif
91
92static char *dentry_name(struct dentry *dentry, int extra)
93{
94 struct dentry *parent;
95 char *root, *name;
96 int len;
97
98 len = 0;
99 parent = dentry;
100 while (parent->d_parent != parent) {
101 len += parent->d_name.len + 1;
102 parent = parent->d_parent;
103 }
104
105 root = HOSTFS_I(parent->d_inode)->host_filename;
106 len += strlen(root);
107 name = kmalloc(len + extra + 1, GFP_KERNEL);
108 if (name == NULL)
109 return NULL;
110
111 name[len] = '\0';
112 parent = dentry;
113 while (parent->d_parent != parent) {
114 len -= parent->d_name.len + 1;
115 name[len] = '/';
116 strncpy(&name[len + 1], parent->d_name.name,
117 parent->d_name.len);
118 parent = parent->d_parent;
119 }
120 strncpy(name, root, strlen(root));
121 return name;
122}
123
124static char *inode_name(struct inode *ino, int extra)
125{
126 struct dentry *dentry;
127
128 dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
129 return dentry_name(dentry, extra);
130}
131
132static int read_name(struct inode *ino, char *name)
133{
134
135
136
137
138
139 int err;
140 int i_mode, i_nlink, i_blksize;
141 unsigned long long i_size;
142 unsigned long long i_ino;
143 unsigned long long i_blocks;
144
145 err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid,
146 &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime,
147 &ino->i_ctime, &i_blksize, &i_blocks, -1);
148 if (err)
149 return err;
150
151 ino->i_ino = i_ino;
152 ino->i_mode = i_mode;
153 ino->i_nlink = i_nlink;
154 ino->i_size = i_size;
155 ino->i_blocks = i_blocks;
156 return 0;
157}
158
159static char *follow_link(char *link)
160{
161 int len, n;
162 char *name, *resolved, *end;
163
164 len = 64;
165 while (1) {
166 n = -ENOMEM;
167 name = kmalloc(len, GFP_KERNEL);
168 if (name == NULL)
169 goto out;
170
171 n = hostfs_do_readlink(link, name, len);
172 if (n < len)
173 break;
174 len *= 2;
175 kfree(name);
176 }
177 if (n < 0)
178 goto out_free;
179
180 if (*name == '/')
181 return name;
182
183 end = strrchr(link, '/');
184 if (end == NULL)
185 return name;
186
187 *(end + 1) = '\0';
188 len = strlen(link) + strlen(name) + 1;
189
190 resolved = kmalloc(len, GFP_KERNEL);
191 if (resolved == NULL) {
192 n = -ENOMEM;
193 goto out_free;
194 }
195
196 sprintf(resolved, "%s%s", link, name);
197 kfree(name);
198 kfree(link);
199 return resolved;
200
201 out_free:
202 kfree(name);
203 out:
204 return ERR_PTR(n);
205}
206
207static int hostfs_read_inode(struct inode *ino)
208{
209 char *name;
210 int err = 0;
211
212
213
214
215
216 if (list_empty(&ino->i_dentry))
217 goto out;
218
219 err = -ENOMEM;
220 name = inode_name(ino, 0);
221 if (name == NULL)
222 goto out;
223
224 if (file_type(name, NULL, NULL) == OS_TYPE_SYMLINK) {
225 name = follow_link(name);
226 if (IS_ERR(name)) {
227 err = PTR_ERR(name);
228 goto out;
229 }
230 }
231
232 err = read_name(ino, name);
233 kfree(name);
234 out:
235 return err;
236}
237
238static struct inode *hostfs_iget(struct super_block *sb)
239{
240 struct inode *inode;
241 long ret;
242
243 inode = iget_locked(sb, 0);
244 if (!inode)
245 return ERR_PTR(-ENOMEM);
246 if (inode->i_state & I_NEW) {
247 ret = hostfs_read_inode(inode);
248 if (ret < 0) {
249 iget_failed(inode);
250 return ERR_PTR(ret);
251 }
252 unlock_new_inode(inode);
253 }
254 return inode;
255}
256
257int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
258{
259
260
261
262
263
264 int err;
265 long long f_blocks;
266 long long f_bfree;
267 long long f_bavail;
268 long long f_files;
269 long long f_ffree;
270
271 err = do_statfs(HOSTFS_I(dentry->d_sb->s_root->d_inode)->host_filename,
272 &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
273 &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
274 &sf->f_namelen, sf->f_spare);
275 if (err)
276 return err;
277 sf->f_blocks = f_blocks;
278 sf->f_bfree = f_bfree;
279 sf->f_bavail = f_bavail;
280 sf->f_files = f_files;
281 sf->f_ffree = f_ffree;
282 sf->f_type = HOSTFS_SUPER_MAGIC;
283 return 0;
284}
285
286static struct inode *hostfs_alloc_inode(struct super_block *sb)
287{
288 struct hostfs_inode_info *hi;
289
290 hi = kmalloc(sizeof(*hi), GFP_KERNEL);
291 if (hi == NULL)
292 return NULL;
293
294 *hi = ((struct hostfs_inode_info) { .host_filename = NULL,
295 .fd = -1,
296 .mode = 0 });
297 inode_init_once(&hi->vfs_inode);
298 return &hi->vfs_inode;
299}
300
301static void hostfs_delete_inode(struct inode *inode)
302{
303 truncate_inode_pages(&inode->i_data, 0);
304 if (HOSTFS_I(inode)->fd != -1) {
305 close_file(&HOSTFS_I(inode)->fd);
306 HOSTFS_I(inode)->fd = -1;
307 }
308 clear_inode(inode);
309}
310
311static void hostfs_destroy_inode(struct inode *inode)
312{
313 kfree(HOSTFS_I(inode)->host_filename);
314
315
316
317
318
319 if (HOSTFS_I(inode)->fd != -1) {
320 close_file(&HOSTFS_I(inode)->fd);
321 printk(KERN_DEBUG "Closing host fd in .destroy_inode\n");
322 }
323
324 kfree(HOSTFS_I(inode));
325}
326
327static int hostfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
328{
329 struct inode *root = vfs->mnt_sb->s_root->d_inode;
330 const char *root_path = HOSTFS_I(root)->host_filename;
331 size_t offset = strlen(root_ino) + 1;
332
333 if (strlen(root_path) > offset)
334 seq_printf(seq, ",%s", root_path + offset);
335
336 return 0;
337}
338
339static const struct super_operations hostfs_sbops = {
340 .alloc_inode = hostfs_alloc_inode,
341 .drop_inode = generic_delete_inode,
342 .delete_inode = hostfs_delete_inode,
343 .destroy_inode = hostfs_destroy_inode,
344 .statfs = hostfs_statfs,
345 .show_options = hostfs_show_options,
346};
347
348int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
349{
350 void *dir;
351 char *name;
352 unsigned long long next, ino;
353 int error, len;
354
355 name = dentry_name(file->f_path.dentry, 0);
356 if (name == NULL)
357 return -ENOMEM;
358 dir = open_dir(name, &error);
359 kfree(name);
360 if (dir == NULL)
361 return -error;
362 next = file->f_pos;
363 while ((name = read_dir(dir, &next, &ino, &len)) != NULL) {
364 error = (*filldir)(ent, name, len, file->f_pos,
365 ino, DT_UNKNOWN);
366 if (error) break;
367 file->f_pos = next;
368 }
369 close_dir(dir);
370 return 0;
371}
372
373int hostfs_file_open(struct inode *ino, struct file *file)
374{
375 char *name;
376 fmode_t mode = 0;
377 int r = 0, w = 0, fd;
378
379 mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
380 if ((mode & HOSTFS_I(ino)->mode) == mode)
381 return 0;
382
383
384
385
386
387 if (HOSTFS_I(ino)->fd != -1) {
388 close_file(&HOSTFS_I(ino)->fd);
389 HOSTFS_I(ino)->fd = -1;
390 }
391
392 HOSTFS_I(ino)->mode |= mode;
393 if (HOSTFS_I(ino)->mode & FMODE_READ)
394 r = 1;
395 if (HOSTFS_I(ino)->mode & FMODE_WRITE)
396 w = 1;
397 if (w)
398 r = 1;
399
400 name = dentry_name(file->f_path.dentry, 0);
401 if (name == NULL)
402 return -ENOMEM;
403
404 fd = open_file(name, r, w, append);
405 kfree(name);
406 if (fd < 0)
407 return fd;
408 FILE_HOSTFS_I(file)->fd = fd;
409
410 return 0;
411}
412
413int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
414{
415 return fsync_file(HOSTFS_I(dentry->d_inode)->fd, datasync);
416}
417
418static const struct file_operations hostfs_file_fops = {
419 .llseek = generic_file_llseek,
420 .read = do_sync_read,
421 .splice_read = generic_file_splice_read,
422 .aio_read = generic_file_aio_read,
423 .aio_write = generic_file_aio_write,
424 .write = do_sync_write,
425 .mmap = generic_file_mmap,
426 .open = hostfs_file_open,
427 .release = NULL,
428 .fsync = hostfs_fsync,
429};
430
431static const struct file_operations hostfs_dir_fops = {
432 .llseek = generic_file_llseek,
433 .readdir = hostfs_readdir,
434 .read = generic_read_dir,
435};
436
437int hostfs_writepage(struct page *page, struct writeback_control *wbc)
438{
439 struct address_space *mapping = page->mapping;
440 struct inode *inode = mapping->host;
441 char *buffer;
442 unsigned long long base;
443 int count = PAGE_CACHE_SIZE;
444 int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
445 int err;
446
447 if (page->index >= end_index)
448 count = inode->i_size & (PAGE_CACHE_SIZE-1);
449
450 buffer = kmap(page);
451 base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
452
453 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
454 if (err != count) {
455 ClearPageUptodate(page);
456 goto out;
457 }
458
459 if (base > inode->i_size)
460 inode->i_size = base;
461
462 if (PageError(page))
463 ClearPageError(page);
464 err = 0;
465
466 out:
467 kunmap(page);
468
469 unlock_page(page);
470 return err;
471}
472
473int hostfs_readpage(struct file *file, struct page *page)
474{
475 char *buffer;
476 long long start;
477 int err = 0;
478
479 start = (long long) page->index << PAGE_CACHE_SHIFT;
480 buffer = kmap(page);
481 err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
482 PAGE_CACHE_SIZE);
483 if (err < 0)
484 goto out;
485
486 memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
487
488 flush_dcache_page(page);
489 SetPageUptodate(page);
490 if (PageError(page)) ClearPageError(page);
491 err = 0;
492 out:
493 kunmap(page);
494 unlock_page(page);
495 return err;
496}
497
498int hostfs_write_begin(struct file *file, struct address_space *mapping,
499 loff_t pos, unsigned len, unsigned flags,
500 struct page **pagep, void **fsdata)
501{
502 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
503
504 *pagep = grab_cache_page_write_begin(mapping, index, flags);
505 if (!*pagep)
506 return -ENOMEM;
507 return 0;
508}
509
510int hostfs_write_end(struct file *file, struct address_space *mapping,
511 loff_t pos, unsigned len, unsigned copied,
512 struct page *page, void *fsdata)
513{
514 struct inode *inode = mapping->host;
515 void *buffer;
516 unsigned from = pos & (PAGE_CACHE_SIZE - 1);
517 int err;
518
519 buffer = kmap(page);
520 err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied);
521 kunmap(page);
522
523 if (!PageUptodate(page) && err == PAGE_CACHE_SIZE)
524 SetPageUptodate(page);
525
526
527
528
529
530 if (err > 0 && (pos > inode->i_size))
531 inode->i_size = pos;
532 unlock_page(page);
533 page_cache_release(page);
534
535 return err;
536}
537
538static const struct address_space_operations hostfs_aops = {
539 .writepage = hostfs_writepage,
540 .readpage = hostfs_readpage,
541 .set_page_dirty = __set_page_dirty_nobuffers,
542 .write_begin = hostfs_write_begin,
543 .write_end = hostfs_write_end,
544};
545
546static int init_inode(struct inode *inode, struct dentry *dentry)
547{
548 char *name;
549 int type, err = -ENOMEM;
550 int maj, min;
551 dev_t rdev = 0;
552
553 if (dentry) {
554 name = dentry_name(dentry, 0);
555 if (name == NULL)
556 goto out;
557 type = file_type(name, &maj, &min);
558
559 rdev = MKDEV(maj, min);
560 kfree(name);
561 }
562 else type = OS_TYPE_DIR;
563
564 err = 0;
565 if (type == OS_TYPE_SYMLINK)
566 inode->i_op = &page_symlink_inode_operations;
567 else if (type == OS_TYPE_DIR)
568 inode->i_op = &hostfs_dir_iops;
569 else inode->i_op = &hostfs_iops;
570
571 if (type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
572 else inode->i_fop = &hostfs_file_fops;
573
574 if (type == OS_TYPE_SYMLINK)
575 inode->i_mapping->a_ops = &hostfs_link_aops;
576 else inode->i_mapping->a_ops = &hostfs_aops;
577
578 switch (type) {
579 case OS_TYPE_CHARDEV:
580 init_special_inode(inode, S_IFCHR, rdev);
581 break;
582 case OS_TYPE_BLOCKDEV:
583 init_special_inode(inode, S_IFBLK, rdev);
584 break;
585 case OS_TYPE_FIFO:
586 init_special_inode(inode, S_IFIFO, 0);
587 break;
588 case OS_TYPE_SOCK:
589 init_special_inode(inode, S_IFSOCK, 0);
590 break;
591 }
592 out:
593 return err;
594}
595
596int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
597 struct nameidata *nd)
598{
599 struct inode *inode;
600 char *name;
601 int error, fd;
602
603 inode = hostfs_iget(dir->i_sb);
604 if (IS_ERR(inode)) {
605 error = PTR_ERR(inode);
606 goto out;
607 }
608
609 error = init_inode(inode, dentry);
610 if (error)
611 goto out_put;
612
613 error = -ENOMEM;
614 name = dentry_name(dentry, 0);
615 if (name == NULL)
616 goto out_put;
617
618 fd = file_create(name,
619 mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
620 mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
621 mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
622 if (fd < 0)
623 error = fd;
624 else error = read_name(inode, name);
625
626 kfree(name);
627 if (error)
628 goto out_put;
629
630 HOSTFS_I(inode)->fd = fd;
631 HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
632 d_instantiate(dentry, inode);
633 return 0;
634
635 out_put:
636 iput(inode);
637 out:
638 return error;
639}
640
641struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
642 struct nameidata *nd)
643{
644 struct inode *inode;
645 char *name;
646 int err;
647
648 inode = hostfs_iget(ino->i_sb);
649 if (IS_ERR(inode)) {
650 err = PTR_ERR(inode);
651 goto out;
652 }
653
654 err = init_inode(inode, dentry);
655 if (err)
656 goto out_put;
657
658 err = -ENOMEM;
659 name = dentry_name(dentry, 0);
660 if (name == NULL)
661 goto out_put;
662
663 err = read_name(inode, name);
664 kfree(name);
665 if (err == -ENOENT) {
666 iput(inode);
667 inode = NULL;
668 }
669 else if (err)
670 goto out_put;
671
672 d_add(dentry, inode);
673 dentry->d_op = &hostfs_dentry_ops;
674 return NULL;
675
676 out_put:
677 iput(inode);
678 out:
679 return ERR_PTR(err);
680}
681
682static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
683{
684 char *file;
685 int len;
686
687 file = inode_name(ino, dentry->d_name.len + 1);
688 if (file == NULL)
689 return NULL;
690 strcat(file, "/");
691 len = strlen(file);
692 strncat(file, dentry->d_name.name, dentry->d_name.len);
693 file[len + dentry->d_name.len] = '\0';
694 return file;
695}
696
697int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
698{
699 char *from_name, *to_name;
700 int err;
701
702 if ((from_name = inode_dentry_name(ino, from)) == NULL)
703 return -ENOMEM;
704 to_name = dentry_name(to, 0);
705 if (to_name == NULL) {
706 kfree(from_name);
707 return -ENOMEM;
708 }
709 err = link_file(to_name, from_name);
710 kfree(from_name);
711 kfree(to_name);
712 return err;
713}
714
715int hostfs_unlink(struct inode *ino, struct dentry *dentry)
716{
717 char *file;
718 int err;
719
720 if ((file = inode_dentry_name(ino, dentry)) == NULL)
721 return -ENOMEM;
722 if (append)
723 return -EPERM;
724
725 err = unlink_file(file);
726 kfree(file);
727 return err;
728}
729
730int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
731{
732 char *file;
733 int err;
734
735 if ((file = inode_dentry_name(ino, dentry)) == NULL)
736 return -ENOMEM;
737 err = make_symlink(file, to);
738 kfree(file);
739 return err;
740}
741
742int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
743{
744 char *file;
745 int err;
746
747 if ((file = inode_dentry_name(ino, dentry)) == NULL)
748 return -ENOMEM;
749 err = do_mkdir(file, mode);
750 kfree(file);
751 return err;
752}
753
754int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
755{
756 char *file;
757 int err;
758
759 if ((file = inode_dentry_name(ino, dentry)) == NULL)
760 return -ENOMEM;
761 err = do_rmdir(file);
762 kfree(file);
763 return err;
764}
765
766int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
767{
768 struct inode *inode;
769 char *name;
770 int err;
771
772 inode = hostfs_iget(dir->i_sb);
773 if (IS_ERR(inode)) {
774 err = PTR_ERR(inode);
775 goto out;
776 }
777
778 err = init_inode(inode, dentry);
779 if (err)
780 goto out_put;
781
782 err = -ENOMEM;
783 name = dentry_name(dentry, 0);
784 if (name == NULL)
785 goto out_put;
786
787 init_special_inode(inode, mode, dev);
788 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
789 if (err)
790 goto out_free;
791
792 err = read_name(inode, name);
793 kfree(name);
794 if (err)
795 goto out_put;
796
797 d_instantiate(dentry, inode);
798 return 0;
799
800 out_free:
801 kfree(name);
802 out_put:
803 iput(inode);
804 out:
805 return err;
806}
807
808int hostfs_rename(struct inode *from_ino, struct dentry *from,
809 struct inode *to_ino, struct dentry *to)
810{
811 char *from_name, *to_name;
812 int err;
813
814 if ((from_name = inode_dentry_name(from_ino, from)) == NULL)
815 return -ENOMEM;
816 if ((to_name = inode_dentry_name(to_ino, to)) == NULL) {
817 kfree(from_name);
818 return -ENOMEM;
819 }
820 err = rename_file(from_name, to_name);
821 kfree(from_name);
822 kfree(to_name);
823 return err;
824}
825
826int hostfs_permission(struct inode *ino, int desired)
827{
828 char *name;
829 int r = 0, w = 0, x = 0, err;
830
831 if (desired & MAY_READ) r = 1;
832 if (desired & MAY_WRITE) w = 1;
833 if (desired & MAY_EXEC) x = 1;
834 name = inode_name(ino, 0);
835 if (name == NULL)
836 return -ENOMEM;
837
838 if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
839 S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
840 err = 0;
841 else
842 err = access_file(name, r, w, x);
843 kfree(name);
844 if (!err)
845 err = generic_permission(ino, desired, NULL);
846 return err;
847}
848
849int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
850{
851 struct hostfs_iattr attrs;
852 char *name;
853 int err;
854
855 int fd = HOSTFS_I(dentry->d_inode)->fd;
856
857 err = inode_change_ok(dentry->d_inode, attr);
858 if (err)
859 return err;
860
861 if (append)
862 attr->ia_valid &= ~ATTR_SIZE;
863
864 attrs.ia_valid = 0;
865 if (attr->ia_valid & ATTR_MODE) {
866 attrs.ia_valid |= HOSTFS_ATTR_MODE;
867 attrs.ia_mode = attr->ia_mode;
868 }
869 if (attr->ia_valid & ATTR_UID) {
870 attrs.ia_valid |= HOSTFS_ATTR_UID;
871 attrs.ia_uid = attr->ia_uid;
872 }
873 if (attr->ia_valid & ATTR_GID) {
874 attrs.ia_valid |= HOSTFS_ATTR_GID;
875 attrs.ia_gid = attr->ia_gid;
876 }
877 if (attr->ia_valid & ATTR_SIZE) {
878 attrs.ia_valid |= HOSTFS_ATTR_SIZE;
879 attrs.ia_size = attr->ia_size;
880 }
881 if (attr->ia_valid & ATTR_ATIME) {
882 attrs.ia_valid |= HOSTFS_ATTR_ATIME;
883 attrs.ia_atime = attr->ia_atime;
884 }
885 if (attr->ia_valid & ATTR_MTIME) {
886 attrs.ia_valid |= HOSTFS_ATTR_MTIME;
887 attrs.ia_mtime = attr->ia_mtime;
888 }
889 if (attr->ia_valid & ATTR_CTIME) {
890 attrs.ia_valid |= HOSTFS_ATTR_CTIME;
891 attrs.ia_ctime = attr->ia_ctime;
892 }
893 if (attr->ia_valid & ATTR_ATIME_SET) {
894 attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
895 }
896 if (attr->ia_valid & ATTR_MTIME_SET) {
897 attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
898 }
899 name = dentry_name(dentry, 0);
900 if (name == NULL)
901 return -ENOMEM;
902 err = set_attr(name, &attrs, fd);
903 kfree(name);
904 if (err)
905 return err;
906
907 return inode_setattr(dentry->d_inode, attr);
908}
909
910static const struct inode_operations hostfs_iops = {
911 .create = hostfs_create,
912 .link = hostfs_link,
913 .unlink = hostfs_unlink,
914 .symlink = hostfs_symlink,
915 .mkdir = hostfs_mkdir,
916 .rmdir = hostfs_rmdir,
917 .mknod = hostfs_mknod,
918 .rename = hostfs_rename,
919 .permission = hostfs_permission,
920 .setattr = hostfs_setattr,
921};
922
923static const struct inode_operations hostfs_dir_iops = {
924 .create = hostfs_create,
925 .lookup = hostfs_lookup,
926 .link = hostfs_link,
927 .unlink = hostfs_unlink,
928 .symlink = hostfs_symlink,
929 .mkdir = hostfs_mkdir,
930 .rmdir = hostfs_rmdir,
931 .mknod = hostfs_mknod,
932 .rename = hostfs_rename,
933 .permission = hostfs_permission,
934 .setattr = hostfs_setattr,
935};
936
937int hostfs_link_readpage(struct file *file, struct page *page)
938{
939 char *buffer, *name;
940 int err;
941
942 buffer = kmap(page);
943 name = inode_name(page->mapping->host, 0);
944 if (name == NULL)
945 return -ENOMEM;
946 err = hostfs_do_readlink(name, buffer, PAGE_CACHE_SIZE);
947 kfree(name);
948 if (err == PAGE_CACHE_SIZE)
949 err = -E2BIG;
950 else if (err > 0) {
951 flush_dcache_page(page);
952 SetPageUptodate(page);
953 if (PageError(page)) ClearPageError(page);
954 err = 0;
955 }
956 kunmap(page);
957 unlock_page(page);
958 return err;
959}
960
961static const struct address_space_operations hostfs_link_aops = {
962 .readpage = hostfs_link_readpage,
963};
964
965static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
966{
967 struct inode *root_inode;
968 char *host_root_path, *req_root = d;
969 int err;
970
971 sb->s_blocksize = 1024;
972 sb->s_blocksize_bits = 10;
973 sb->s_magic = HOSTFS_SUPER_MAGIC;
974 sb->s_op = &hostfs_sbops;
975 sb->s_maxbytes = MAX_LFS_FILESIZE;
976
977
978 if (req_root == NULL)
979 req_root = "";
980
981 err = -ENOMEM;
982 host_root_path = kmalloc(strlen(root_ino) + 1
983 + strlen(req_root) + 1, GFP_KERNEL);
984 if (host_root_path == NULL)
985 goto out;
986
987 sprintf(host_root_path, "%s/%s", root_ino, req_root);
988
989 root_inode = hostfs_iget(sb);
990 if (IS_ERR(root_inode)) {
991 err = PTR_ERR(root_inode);
992 goto out_free;
993 }
994
995 err = init_inode(root_inode, NULL);
996 if (err)
997 goto out_put;
998
999 HOSTFS_I(root_inode)->host_filename = host_root_path;
1000
1001
1002
1003
1004 host_root_path = NULL;
1005
1006 err = -ENOMEM;
1007 sb->s_root = d_alloc_root(root_inode);
1008 if (sb->s_root == NULL)
1009 goto out_put;
1010
1011 err = hostfs_read_inode(root_inode);
1012 if (err) {
1013
1014 dput(sb->s_root);
1015 sb->s_root = NULL;
1016 goto out;
1017 }
1018
1019 return 0;
1020
1021out_put:
1022 iput(root_inode);
1023out_free:
1024 kfree(host_root_path);
1025out:
1026 return err;
1027}
1028
1029static int hostfs_read_sb(struct file_system_type *type,
1030 int flags, const char *dev_name,
1031 void *data, struct vfsmount *mnt)
1032{
1033 return get_sb_nodev(type, flags, data, hostfs_fill_sb_common, mnt);
1034}
1035
1036static struct file_system_type hostfs_type = {
1037 .owner = THIS_MODULE,
1038 .name = "hostfs",
1039 .get_sb = hostfs_read_sb,
1040 .kill_sb = kill_anon_super,
1041 .fs_flags = 0,
1042};
1043
1044static int __init init_hostfs(void)
1045{
1046 return register_filesystem(&hostfs_type);
1047}
1048
1049static void __exit exit_hostfs(void)
1050{
1051 unregister_filesystem(&hostfs_type);
1052}
1053
1054module_init(init_hostfs)
1055module_exit(exit_hostfs)
1056MODULE_LICENSE("GPL");
1057