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