blob: a33fb1d91373f873d559a26e1a8494e363ecc86c [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{
Mark Fashehfef26652005-09-09 13:01:31 -0700287 truncate_inode_pages(&inode->i_data, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 if(HOSTFS_I(inode)->fd != -1) {
289 close_file(&HOSTFS_I(inode)->fd);
290 HOSTFS_I(inode)->fd = -1;
291 }
292 clear_inode(inode);
293}
294
295static void hostfs_destroy_inode(struct inode *inode)
296{
Jesper Juhlf99d49a2005-11-07 01:01:34 -0800297 kfree(HOSTFS_I(inode)->host_filename);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298
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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
796{
797 char *name;
798 int r = 0, w = 0, x = 0, err;
799
800 if (desired & MAY_READ) r = 1;
801 if (desired & MAY_WRITE) w = 1;
802 if (desired & MAY_EXEC) x = 1;
803 name = inode_name(ino, 0);
804 if (name == NULL) return(-ENOMEM);
805
806 if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
807 S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
808 err = 0;
809 else
810 err = access_file(name, r, w, x);
811 kfree(name);
812 if(!err)
813 err = generic_permission(ino, desired, NULL);
814 return err;
815}
816
817int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
818{
819 struct hostfs_iattr attrs;
820 char *name;
821 int err;
822
823 err = inode_change_ok(dentry->d_inode, attr);
824 if (err)
825 return err;
826
827 if(append)
828 attr->ia_valid &= ~ATTR_SIZE;
829
830 attrs.ia_valid = 0;
831 if(attr->ia_valid & ATTR_MODE){
832 attrs.ia_valid |= HOSTFS_ATTR_MODE;
833 attrs.ia_mode = attr->ia_mode;
834 }
835 if(attr->ia_valid & ATTR_UID){
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 attrs.ia_valid |= HOSTFS_ATTR_UID;
837 attrs.ia_uid = attr->ia_uid;
838 }
839 if(attr->ia_valid & ATTR_GID){
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 attrs.ia_valid |= HOSTFS_ATTR_GID;
841 attrs.ia_gid = attr->ia_gid;
842 }
843 if(attr->ia_valid & ATTR_SIZE){
844 attrs.ia_valid |= HOSTFS_ATTR_SIZE;
845 attrs.ia_size = attr->ia_size;
846 }
847 if(attr->ia_valid & ATTR_ATIME){
848 attrs.ia_valid |= HOSTFS_ATTR_ATIME;
849 attrs.ia_atime = attr->ia_atime;
850 }
851 if(attr->ia_valid & ATTR_MTIME){
852 attrs.ia_valid |= HOSTFS_ATTR_MTIME;
853 attrs.ia_mtime = attr->ia_mtime;
854 }
855 if(attr->ia_valid & ATTR_CTIME){
856 attrs.ia_valid |= HOSTFS_ATTR_CTIME;
857 attrs.ia_ctime = attr->ia_ctime;
858 }
859 if(attr->ia_valid & ATTR_ATIME_SET){
860 attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
861 }
862 if(attr->ia_valid & ATTR_MTIME_SET){
863 attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
864 }
865 name = dentry_name(dentry, 0);
866 if(name == NULL) return(-ENOMEM);
867 err = set_attr(name, &attrs);
868 kfree(name);
869 if(err)
870 return(err);
871
872 return(inode_setattr(dentry->d_inode, attr));
873}
874
875int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
876 struct kstat *stat)
877{
878 generic_fillattr(dentry->d_inode, stat);
879 return(0);
880}
881
882static struct inode_operations hostfs_iops = {
883 .create = hostfs_create,
884 .link = hostfs_link,
885 .unlink = hostfs_unlink,
886 .symlink = hostfs_symlink,
887 .mkdir = hostfs_mkdir,
888 .rmdir = hostfs_rmdir,
889 .mknod = hostfs_mknod,
890 .rename = hostfs_rename,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 .permission = hostfs_permission,
892 .setattr = hostfs_setattr,
893 .getattr = hostfs_getattr,
894};
895
896static struct inode_operations hostfs_dir_iops = {
897 .create = hostfs_create,
898 .lookup = hostfs_lookup,
899 .link = hostfs_link,
900 .unlink = hostfs_unlink,
901 .symlink = hostfs_symlink,
902 .mkdir = hostfs_mkdir,
903 .rmdir = hostfs_rmdir,
904 .mknod = hostfs_mknod,
905 .rename = hostfs_rename,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 .permission = hostfs_permission,
907 .setattr = hostfs_setattr,
908 .getattr = hostfs_getattr,
909};
910
911int hostfs_link_readpage(struct file *file, struct page *page)
912{
913 char *buffer, *name;
914 long long start;
915 int err;
916
917 start = page->index << PAGE_CACHE_SHIFT;
918 buffer = kmap(page);
919 name = inode_name(page->mapping->host, 0);
920 if(name == NULL) return(-ENOMEM);
921 err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
922 kfree(name);
923 if(err == PAGE_CACHE_SIZE)
924 err = -E2BIG;
925 else if(err > 0){
926 flush_dcache_page(page);
927 SetPageUptodate(page);
928 if (PageError(page)) ClearPageError(page);
929 err = 0;
930 }
931 kunmap(page);
932 unlock_page(page);
933 return(err);
934}
935
936static struct address_space_operations hostfs_link_aops = {
937 .readpage = hostfs_link_readpage,
938};
939
940static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
941{
942 struct inode *root_inode;
943 char *name, *data = d;
944 int err;
945
946 sb->s_blocksize = 1024;
947 sb->s_blocksize_bits = 10;
948 sb->s_magic = HOSTFS_SUPER_MAGIC;
949 sb->s_op = &hostfs_sbops;
950
951 if((data == NULL) || (*data == '\0'))
952 data = root_ino;
953
954 err = -ENOMEM;
955 name = kmalloc(strlen(data) + 1, GFP_KERNEL);
956 if(name == NULL)
957 goto out;
958
959 strcpy(name, data);
960
961 root_inode = iget(sb, 0);
962 if(root_inode == NULL)
963 goto out_free;
964
965 err = init_inode(root_inode, NULL);
966 if(err)
967 goto out_put;
968
969 HOSTFS_I(root_inode)->host_filename = name;
970
971 err = -ENOMEM;
972 sb->s_root = d_alloc_root(root_inode);
973 if(sb->s_root == NULL)
974 goto out_put;
975
976 err = read_inode(root_inode);
Jeff Dike51a14112005-05-05 16:15:34 -0700977 if(err){
978 /* No iput in this case because the dput does that for us */
979 dput(sb->s_root);
980 sb->s_root = NULL;
981 goto out_free;
982 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983
984 return(0);
985
986 out_put:
Jeff Dike51a14112005-05-05 16:15:34 -0700987 iput(root_inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 out_free:
989 kfree(name);
990 out:
991 return(err);
992}
993
994static struct super_block *hostfs_read_sb(struct file_system_type *type,
995 int flags, const char *dev_name,
996 void *data)
997{
998 return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
999}
1000
1001static struct file_system_type hostfs_type = {
1002 .owner = THIS_MODULE,
1003 .name = "hostfs",
1004 .get_sb = hostfs_read_sb,
1005 .kill_sb = kill_anon_super,
1006 .fs_flags = 0,
1007};
1008
1009static int __init init_hostfs(void)
1010{
1011 return(register_filesystem(&hostfs_type));
1012}
1013
1014static void __exit exit_hostfs(void)
1015{
1016 unregister_filesystem(&hostfs_type);
1017}
1018
1019module_init(init_hostfs)
1020module_exit(exit_hostfs)
1021MODULE_LICENSE("GPL");
1022
1023/*
1024 * Overrides for Emacs so that we follow Linus's tabbing style.
1025 * Emacs will notice this stuff at the end of the file and automatically
1026 * adjust the settings for this buffer only. This must remain at the end
1027 * of the file.
1028 * ---------------------------------------------------------------------------
1029 * Local variables:
1030 * c-file-style: "linux"
1031 * End:
1032 */