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