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