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