blob: dd7113106269992822e97e4bbf07ad2bc5ab5eca [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{
297 if(HOSTFS_I(inode)->host_filename)
298 kfree(HOSTFS_I(inode)->host_filename);
299
300 /*XXX: This should not happen, probably. The check is here for
301 * additional safety.*/
302 if(HOSTFS_I(inode)->fd != -1) {
303 close_file(&HOSTFS_I(inode)->fd);
304 printk(KERN_DEBUG "Closing host fd in .destroy_inode\n");
305 }
306
307 kfree(HOSTFS_I(inode));
308}
309
310static void hostfs_read_inode(struct inode *inode)
311{
312 read_inode(inode);
313}
314
315static struct super_operations hostfs_sbops = {
316 .alloc_inode = hostfs_alloc_inode,
317 .drop_inode = generic_delete_inode,
318 .delete_inode = hostfs_delete_inode,
319 .destroy_inode = hostfs_destroy_inode,
320 .read_inode = hostfs_read_inode,
321 .statfs = hostfs_statfs,
322};
323
324int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
325{
326 void *dir;
327 char *name;
328 unsigned long long next, ino;
329 int error, len;
330
331 name = dentry_name(file->f_dentry, 0);
332 if(name == NULL) return(-ENOMEM);
333 dir = open_dir(name, &error);
334 kfree(name);
335 if(dir == NULL) 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_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) return(fd);
379 FILE_HOSTFS_I(file)->fd = fd;
380
381 return(0);
382}
383
384int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
385{
Paolo 'Blaisorblade' Giarrussoa2d76bd2005-07-28 21:16:15 -0700386 return fsync_file(HOSTFS_I(dentry->d_inode)->fd, datasync);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387}
388
389static struct file_operations hostfs_file_fops = {
390 .llseek = generic_file_llseek,
391 .read = generic_file_read,
392 .sendfile = generic_file_sendfile,
393 .aio_read = generic_file_aio_read,
394 .aio_write = generic_file_aio_write,
395 .readv = generic_file_readv,
396 .writev = generic_file_writev,
397 .write = generic_file_write,
398 .mmap = generic_file_mmap,
399 .open = hostfs_file_open,
400 .release = NULL,
401 .fsync = hostfs_fsync,
402};
403
404static struct file_operations hostfs_dir_fops = {
405 .llseek = generic_file_llseek,
406 .readdir = hostfs_readdir,
407 .read = generic_read_dir,
408};
409
410int hostfs_writepage(struct page *page, struct writeback_control *wbc)
411{
412 struct address_space *mapping = page->mapping;
413 struct inode *inode = mapping->host;
414 char *buffer;
415 unsigned long long base;
416 int count = PAGE_CACHE_SIZE;
417 int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
418 int err;
419
420 if (page->index >= end_index)
421 count = inode->i_size & (PAGE_CACHE_SIZE-1);
422
423 buffer = kmap(page);
424 base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
425
426 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
427 if(err != count){
428 ClearPageUptodate(page);
429 goto out;
430 }
431
432 if (base > inode->i_size)
433 inode->i_size = base;
434
435 if (PageError(page))
436 ClearPageError(page);
437 err = 0;
438
439 out:
440 kunmap(page);
441
442 unlock_page(page);
443 return err;
444}
445
446int hostfs_readpage(struct file *file, struct page *page)
447{
448 char *buffer;
449 long long start;
450 int err = 0;
451
452 start = (long long) page->index << PAGE_CACHE_SHIFT;
453 buffer = kmap(page);
454 err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
455 PAGE_CACHE_SIZE);
456 if(err < 0) goto out;
457
458 memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
459
460 flush_dcache_page(page);
461 SetPageUptodate(page);
462 if (PageError(page)) ClearPageError(page);
463 err = 0;
464 out:
465 kunmap(page);
466 unlock_page(page);
467 return(err);
468}
469
470int hostfs_prepare_write(struct file *file, struct page *page,
471 unsigned int from, unsigned int to)
472{
473 char *buffer;
474 long long start, tmp;
475 int err;
476
477 start = (long long) page->index << PAGE_CACHE_SHIFT;
478 buffer = kmap(page);
479 if(from != 0){
480 tmp = start;
481 err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
482 from);
483 if(err < 0) goto out;
484 }
485 if(to != PAGE_CACHE_SIZE){
486 start += to;
487 err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
488 PAGE_CACHE_SIZE - to);
489 if(err < 0) goto out;
490 }
491 err = 0;
492 out:
493 kunmap(page);
494 return(err);
495}
496
497int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
498 unsigned to)
499{
500 struct address_space *mapping = page->mapping;
501 struct inode *inode = mapping->host;
502 char *buffer;
503 long long start;
504 int err = 0;
505
506 start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
507 buffer = kmap(page);
508 err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from,
509 to - from);
510 if(err > 0) err = 0;
511 if(!err && (start > inode->i_size))
512 inode->i_size = start;
513
514 kunmap(page);
515 return(err);
516}
517
518static struct address_space_operations hostfs_aops = {
519 .writepage = hostfs_writepage,
520 .readpage = hostfs_readpage,
Paolo 'Blaisorblade' Giarrussoffa0aea2005-05-01 08:58:56 -0700521 .set_page_dirty = __set_page_dirty_nobuffers,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 .prepare_write = hostfs_prepare_write,
523 .commit_write = hostfs_commit_write
524};
525
526static int init_inode(struct inode *inode, struct dentry *dentry)
527{
528 char *name;
529 int type, err = -ENOMEM;
530 int maj, min;
531 dev_t rdev = 0;
532
533 if(dentry){
534 name = dentry_name(dentry, 0);
535 if(name == NULL)
536 goto out;
537 type = file_type(name, &maj, &min);
538 /*Reencode maj and min with the kernel encoding.*/
539 rdev = MKDEV(maj, min);
540 kfree(name);
541 }
542 else type = OS_TYPE_DIR;
543
544 err = 0;
545 if(type == OS_TYPE_SYMLINK)
546 inode->i_op = &page_symlink_inode_operations;
547 else if(type == OS_TYPE_DIR)
548 inode->i_op = &hostfs_dir_iops;
549 else inode->i_op = &hostfs_iops;
550
551 if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
552 else inode->i_fop = &hostfs_file_fops;
553
554 if(type == OS_TYPE_SYMLINK)
555 inode->i_mapping->a_ops = &hostfs_link_aops;
556 else inode->i_mapping->a_ops = &hostfs_aops;
557
558 switch (type) {
559 case OS_TYPE_CHARDEV:
560 init_special_inode(inode, S_IFCHR, rdev);
561 break;
562 case OS_TYPE_BLOCKDEV:
563 init_special_inode(inode, S_IFBLK, rdev);
564 break;
565 case OS_TYPE_FIFO:
566 init_special_inode(inode, S_IFIFO, 0);
567 break;
568 case OS_TYPE_SOCK:
569 init_special_inode(inode, S_IFSOCK, 0);
570 break;
571 }
572 out:
573 return(err);
574}
575
576int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
577 struct nameidata *nd)
578{
579 struct inode *inode;
580 char *name;
581 int error, fd;
582
583 error = -ENOMEM;
584 inode = iget(dir->i_sb, 0);
585 if(inode == NULL) goto out;
586
587 error = init_inode(inode, dentry);
588 if(error)
589 goto out_put;
590
591 error = -ENOMEM;
592 name = dentry_name(dentry, 0);
593 if(name == NULL)
594 goto out_put;
595
596 fd = file_create(name,
597 mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
598 mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
599 mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
600 if(fd < 0)
601 error = fd;
602 else error = read_name(inode, name);
603
604 kfree(name);
605 if(error)
606 goto out_put;
607
608 HOSTFS_I(inode)->fd = fd;
609 HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
610 d_instantiate(dentry, inode);
611 return(0);
612
613 out_put:
614 iput(inode);
615 out:
616 return(error);
617}
618
619struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
620 struct nameidata *nd)
621{
622 struct inode *inode;
623 char *name;
624 int err;
625
626 err = -ENOMEM;
627 inode = iget(ino->i_sb, 0);
628 if(inode == NULL)
629 goto out;
630
631 err = init_inode(inode, dentry);
632 if(err)
633 goto out_put;
634
635 err = -ENOMEM;
636 name = dentry_name(dentry, 0);
637 if(name == NULL)
638 goto out_put;
639
640 err = read_name(inode, name);
641 kfree(name);
642 if(err == -ENOENT){
643 iput(inode);
644 inode = NULL;
645 }
646 else if(err)
647 goto out_put;
648
649 d_add(dentry, inode);
650 dentry->d_op = &hostfs_dentry_ops;
651 return(NULL);
652
653 out_put:
654 iput(inode);
655 out:
656 return(ERR_PTR(err));
657}
658
659static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
660{
661 char *file;
662 int len;
663
664 file = inode_name(ino, dentry->d_name.len + 1);
665 if(file == NULL) return(NULL);
666 strcat(file, "/");
667 len = strlen(file);
668 strncat(file, dentry->d_name.name, dentry->d_name.len);
669 file[len + dentry->d_name.len] = '\0';
670 return(file);
671}
672
673int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
674{
675 char *from_name, *to_name;
676 int err;
677
678 if((from_name = inode_dentry_name(ino, from)) == NULL)
679 return(-ENOMEM);
680 to_name = dentry_name(to, 0);
681 if(to_name == NULL){
682 kfree(from_name);
683 return(-ENOMEM);
684 }
685 err = link_file(to_name, from_name);
686 kfree(from_name);
687 kfree(to_name);
688 return(err);
689}
690
691int hostfs_unlink(struct inode *ino, struct dentry *dentry)
692{
693 char *file;
694 int err;
695
696 if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
697 if(append)
698 return(-EPERM);
699
700 err = unlink_file(file);
701 kfree(file);
702 return(err);
703}
704
705int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
706{
707 char *file;
708 int err;
709
710 if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
711 err = make_symlink(file, to);
712 kfree(file);
713 return(err);
714}
715
716int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
717{
718 char *file;
719 int err;
720
721 if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
722 err = do_mkdir(file, mode);
723 kfree(file);
724 return(err);
725}
726
727int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
728{
729 char *file;
730 int err;
731
732 if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
733 err = do_rmdir(file);
734 kfree(file);
735 return(err);
736}
737
738int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
739{
740 struct inode *inode;
741 char *name;
742 int err = -ENOMEM;
743
744 inode = iget(dir->i_sb, 0);
745 if(inode == NULL)
746 goto out;
747
748 err = init_inode(inode, dentry);
749 if(err)
750 goto out_put;
751
752 err = -ENOMEM;
753 name = dentry_name(dentry, 0);
754 if(name == NULL)
755 goto out_put;
756
757 init_special_inode(inode, mode, dev);
758 err = do_mknod(name, mode, dev);
759 if(err)
760 goto out_free;
761
762 err = read_name(inode, name);
763 kfree(name);
764 if(err)
765 goto out_put;
766
767 d_instantiate(dentry, inode);
768 return(0);
769
770 out_free:
771 kfree(name);
772 out_put:
773 iput(inode);
774 out:
775 return(err);
776}
777
778int hostfs_rename(struct inode *from_ino, struct dentry *from,
779 struct inode *to_ino, struct dentry *to)
780{
781 char *from_name, *to_name;
782 int err;
783
784 if((from_name = inode_dentry_name(from_ino, from)) == NULL)
785 return(-ENOMEM);
786 if((to_name = inode_dentry_name(to_ino, to)) == NULL){
787 kfree(from_name);
788 return(-ENOMEM);
789 }
790 err = rename_file(from_name, to_name);
791 kfree(from_name);
792 kfree(to_name);
793 return(err);
794}
795
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
797{
798 char *name;
799 int r = 0, w = 0, x = 0, err;
800
801 if (desired & MAY_READ) r = 1;
802 if (desired & MAY_WRITE) w = 1;
803 if (desired & MAY_EXEC) x = 1;
804 name = inode_name(ino, 0);
805 if (name == NULL) return(-ENOMEM);
806
807 if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
808 S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
809 err = 0;
810 else
811 err = access_file(name, r, w, x);
812 kfree(name);
813 if(!err)
814 err = generic_permission(ino, desired, NULL);
815 return err;
816}
817
818int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
819{
820 struct hostfs_iattr attrs;
821 char *name;
822 int err;
823
824 err = inode_change_ok(dentry->d_inode, attr);
825 if (err)
826 return err;
827
828 if(append)
829 attr->ia_valid &= ~ATTR_SIZE;
830
831 attrs.ia_valid = 0;
832 if(attr->ia_valid & ATTR_MODE){
833 attrs.ia_valid |= HOSTFS_ATTR_MODE;
834 attrs.ia_mode = attr->ia_mode;
835 }
836 if(attr->ia_valid & ATTR_UID){
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 attrs.ia_valid |= HOSTFS_ATTR_UID;
838 attrs.ia_uid = attr->ia_uid;
839 }
840 if(attr->ia_valid & ATTR_GID){
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 attrs.ia_valid |= HOSTFS_ATTR_GID;
842 attrs.ia_gid = attr->ia_gid;
843 }
844 if(attr->ia_valid & ATTR_SIZE){
845 attrs.ia_valid |= HOSTFS_ATTR_SIZE;
846 attrs.ia_size = attr->ia_size;
847 }
848 if(attr->ia_valid & ATTR_ATIME){
849 attrs.ia_valid |= HOSTFS_ATTR_ATIME;
850 attrs.ia_atime = attr->ia_atime;
851 }
852 if(attr->ia_valid & ATTR_MTIME){
853 attrs.ia_valid |= HOSTFS_ATTR_MTIME;
854 attrs.ia_mtime = attr->ia_mtime;
855 }
856 if(attr->ia_valid & ATTR_CTIME){
857 attrs.ia_valid |= HOSTFS_ATTR_CTIME;
858 attrs.ia_ctime = attr->ia_ctime;
859 }
860 if(attr->ia_valid & ATTR_ATIME_SET){
861 attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
862 }
863 if(attr->ia_valid & ATTR_MTIME_SET){
864 attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
865 }
866 name = dentry_name(dentry, 0);
867 if(name == NULL) return(-ENOMEM);
868 err = set_attr(name, &attrs);
869 kfree(name);
870 if(err)
871 return(err);
872
873 return(inode_setattr(dentry->d_inode, attr));
874}
875
876int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
877 struct kstat *stat)
878{
879 generic_fillattr(dentry->d_inode, stat);
880 return(0);
881}
882
883static struct inode_operations hostfs_iops = {
884 .create = hostfs_create,
885 .link = hostfs_link,
886 .unlink = hostfs_unlink,
887 .symlink = hostfs_symlink,
888 .mkdir = hostfs_mkdir,
889 .rmdir = hostfs_rmdir,
890 .mknod = hostfs_mknod,
891 .rename = hostfs_rename,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 .permission = hostfs_permission,
893 .setattr = hostfs_setattr,
894 .getattr = hostfs_getattr,
895};
896
897static struct inode_operations hostfs_dir_iops = {
898 .create = hostfs_create,
899 .lookup = hostfs_lookup,
900 .link = hostfs_link,
901 .unlink = hostfs_unlink,
902 .symlink = hostfs_symlink,
903 .mkdir = hostfs_mkdir,
904 .rmdir = hostfs_rmdir,
905 .mknod = hostfs_mknod,
906 .rename = hostfs_rename,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 .permission = hostfs_permission,
908 .setattr = hostfs_setattr,
909 .getattr = hostfs_getattr,
910};
911
912int hostfs_link_readpage(struct file *file, struct page *page)
913{
914 char *buffer, *name;
915 long long start;
916 int err;
917
918 start = page->index << PAGE_CACHE_SHIFT;
919 buffer = kmap(page);
920 name = inode_name(page->mapping->host, 0);
921 if(name == NULL) return(-ENOMEM);
922 err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
923 kfree(name);
924 if(err == PAGE_CACHE_SIZE)
925 err = -E2BIG;
926 else if(err > 0){
927 flush_dcache_page(page);
928 SetPageUptodate(page);
929 if (PageError(page)) ClearPageError(page);
930 err = 0;
931 }
932 kunmap(page);
933 unlock_page(page);
934 return(err);
935}
936
937static struct address_space_operations hostfs_link_aops = {
938 .readpage = hostfs_link_readpage,
939};
940
941static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
942{
943 struct inode *root_inode;
944 char *name, *data = d;
945 int err;
946
947 sb->s_blocksize = 1024;
948 sb->s_blocksize_bits = 10;
949 sb->s_magic = HOSTFS_SUPER_MAGIC;
950 sb->s_op = &hostfs_sbops;
951
952 if((data == NULL) || (*data == '\0'))
953 data = root_ino;
954
955 err = -ENOMEM;
956 name = kmalloc(strlen(data) + 1, GFP_KERNEL);
957 if(name == NULL)
958 goto out;
959
960 strcpy(name, data);
961
962 root_inode = iget(sb, 0);
963 if(root_inode == NULL)
964 goto out_free;
965
966 err = init_inode(root_inode, NULL);
967 if(err)
968 goto out_put;
969
970 HOSTFS_I(root_inode)->host_filename = name;
971
972 err = -ENOMEM;
973 sb->s_root = d_alloc_root(root_inode);
974 if(sb->s_root == NULL)
975 goto out_put;
976
977 err = read_inode(root_inode);
Jeff Dike51a14112005-05-05 16:15:34 -0700978 if(err){
979 /* No iput in this case because the dput does that for us */
980 dput(sb->s_root);
981 sb->s_root = NULL;
982 goto out_free;
983 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984
985 return(0);
986
987 out_put:
Jeff Dike51a14112005-05-05 16:15:34 -0700988 iput(root_inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 out_free:
990 kfree(name);
991 out:
992 return(err);
993}
994
995static struct super_block *hostfs_read_sb(struct file_system_type *type,
996 int flags, const char *dev_name,
997 void *data)
998{
999 return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
1000}
1001
1002static struct file_system_type hostfs_type = {
1003 .owner = THIS_MODULE,
1004 .name = "hostfs",
1005 .get_sb = hostfs_read_sb,
1006 .kill_sb = kill_anon_super,
1007 .fs_flags = 0,
1008};
1009
1010static int __init init_hostfs(void)
1011{
1012 return(register_filesystem(&hostfs_type));
1013}
1014
1015static void __exit exit_hostfs(void)
1016{
1017 unregister_filesystem(&hostfs_type);
1018}
1019
1020module_init(init_hostfs)
1021module_exit(exit_hostfs)
1022MODULE_LICENSE("GPL");
1023
1024/*
1025 * Overrides for Emacs so that we follow Linus's tabbing style.
1026 * Emacs will notice this stuff at the end of the file and automatically
1027 * adjust the settings for this buffer only. This must remain at the end
1028 * of the file.
1029 * ---------------------------------------------------------------------------
1030 * Local variables:
1031 * c-file-style: "linux"
1032 * End:
1033 */