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