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