Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.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/fs.h>
10#include <linux/magic.h>
11#include <linux/module.h>
12#include <linux/mm.h>
13#include <linux/pagemap.h>
14#include <linux/statfs.h>
15#include <linux/slab.h>
16#include <linux/seq_file.h>
17#include <linux/mount.h>
18#include <linux/namei.h>
19#include "hostfs.h"
20#include <init.h>
21#include <kern.h>
22
23struct hostfs_inode_info {
24 int fd;
25 fmode_t mode;
26 struct inode vfs_inode;
27 struct mutex open_mutex;
28};
29
30static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
31{
32 return list_entry(inode, struct hostfs_inode_info, vfs_inode);
33}
34
35#define FILE_HOSTFS_I(file) HOSTFS_I(file_inode(file))
36
37/* Changed in hostfs_args before the kernel starts running */
38static char *root_ino = "";
39static int append = 0;
40
41static const struct inode_operations hostfs_iops;
42static const struct inode_operations hostfs_dir_iops;
43static const struct inode_operations hostfs_link_iops;
44
45#ifndef MODULE
46static int __init hostfs_args(char *options, int *add)
47{
48 char *ptr;
49
50 ptr = strchr(options, ',');
51 if (ptr != NULL)
52 *ptr++ = '\0';
53 if (*options != '\0')
54 root_ino = options;
55
56 options = ptr;
57 while (options) {
58 ptr = strchr(options, ',');
59 if (ptr != NULL)
60 *ptr++ = '\0';
61 if (*options != '\0') {
62 if (!strcmp(options, "append"))
63 append = 1;
64 else printf("hostfs_args - unsupported option - %s\n",
65 options);
66 }
67 options = ptr;
68 }
69 return 0;
70}
71
72__uml_setup("hostfs=", hostfs_args,
73"hostfs=<root dir>,<flags>,...\n"
74" This is used to set hostfs parameters. The root directory argument\n"
75" is used to confine all hostfs mounts to within the specified directory\n"
76" tree on the host. If this isn't specified, then a user inside UML can\n"
77" mount anything on the host that's accessible to the user that's running\n"
78" it.\n"
79" The only flag currently supported is 'append', which specifies that all\n"
80" files opened by hostfs will be opened in append mode.\n\n"
81);
82#endif
83
84static char *__dentry_name(struct dentry *dentry, char *name)
85{
86 char *p = dentry_path_raw(dentry, name, PATH_MAX);
87 char *root;
88 size_t len;
89
90 root = dentry->d_sb->s_fs_info;
91 len = strlen(root);
92 if (IS_ERR(p)) {
93 __putname(name);
94 return NULL;
95 }
96
97 /*
98 * This function relies on the fact that dentry_path_raw() will place
99 * the path name at the end of the provided buffer.
100 */
101 BUG_ON(p + strlen(p) + 1 != name + PATH_MAX);
102
103 strlcpy(name, root, PATH_MAX);
104 if (len > p - name) {
105 __putname(name);
106 return NULL;
107 }
108
109 if (p > name + len)
110 strcpy(name + len, p);
111
112 return name;
113}
114
115static char *dentry_name(struct dentry *dentry)
116{
117 char *name = __getname();
118 if (!name)
119 return NULL;
120
121 return __dentry_name(dentry, name);
122}
123
124static char *inode_name(struct inode *ino)
125{
126 struct dentry *dentry;
127 char *name;
128
129 dentry = d_find_alias(ino);
130 if (!dentry)
131 return NULL;
132
133 name = dentry_name(dentry);
134
135 dput(dentry);
136
137 return name;
138}
139
140static char *follow_link(char *link)
141{
142 int len, n;
143 char *name, *resolved, *end;
144
145 name = __getname();
146 if (!name) {
147 n = -ENOMEM;
148 goto out_free;
149 }
150
151 n = hostfs_do_readlink(link, name, PATH_MAX);
152 if (n < 0)
153 goto out_free;
154 else if (n == PATH_MAX) {
155 n = -E2BIG;
156 goto out_free;
157 }
158
159 if (*name == '/')
160 return name;
161
162 end = strrchr(link, '/');
163 if (end == NULL)
164 return name;
165
166 *(end + 1) = '\0';
167 len = strlen(link) + strlen(name) + 1;
168
169 resolved = kmalloc(len, GFP_KERNEL);
170 if (resolved == NULL) {
171 n = -ENOMEM;
172 goto out_free;
173 }
174
175 sprintf(resolved, "%s%s", link, name);
176 __putname(name);
177 kfree(link);
178 return resolved;
179
180 out_free:
181 __putname(name);
182 return ERR_PTR(n);
183}
184
185static struct inode *hostfs_iget(struct super_block *sb)
186{
187 struct inode *inode = new_inode(sb);
188 if (!inode)
189 return ERR_PTR(-ENOMEM);
190 return inode;
191}
192
193static int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
194{
195 /*
196 * do_statfs uses struct statfs64 internally, but the linux kernel
197 * struct statfs still has 32-bit versions for most of these fields,
198 * so we convert them here
199 */
200 int err;
201 long long f_blocks;
202 long long f_bfree;
203 long long f_bavail;
204 long long f_files;
205 long long f_ffree;
206
207 err = do_statfs(dentry->d_sb->s_fs_info,
208 &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
209 &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
210 &sf->f_namelen);
211 if (err)
212 return err;
213 sf->f_blocks = f_blocks;
214 sf->f_bfree = f_bfree;
215 sf->f_bavail = f_bavail;
216 sf->f_files = f_files;
217 sf->f_ffree = f_ffree;
218 sf->f_type = HOSTFS_SUPER_MAGIC;
219 return 0;
220}
221
222static struct inode *hostfs_alloc_inode(struct super_block *sb)
223{
224 struct hostfs_inode_info *hi;
225
226 hi = kmalloc(sizeof(*hi), GFP_KERNEL);
227 if (hi == NULL)
228 return NULL;
229 hi->fd = -1;
230 hi->mode = 0;
231 inode_init_once(&hi->vfs_inode);
232 mutex_init(&hi->open_mutex);
233 return &hi->vfs_inode;
234}
235
236static void hostfs_evict_inode(struct inode *inode)
237{
238 truncate_inode_pages_final(&inode->i_data);
239 clear_inode(inode);
240 if (HOSTFS_I(inode)->fd != -1) {
241 close_file(&HOSTFS_I(inode)->fd);
242 HOSTFS_I(inode)->fd = -1;
243 }
244}
245
246static void hostfs_i_callback(struct rcu_head *head)
247{
248 struct inode *inode = container_of(head, struct inode, i_rcu);
249 kfree(HOSTFS_I(inode));
250}
251
252static void hostfs_destroy_inode(struct inode *inode)
253{
254 call_rcu(&inode->i_rcu, hostfs_i_callback);
255}
256
257static int hostfs_show_options(struct seq_file *seq, struct dentry *root)
258{
259 const char *root_path = root->d_sb->s_fs_info;
260 size_t offset = strlen(root_ino) + 1;
261
262 if (strlen(root_path) > offset)
263 seq_printf(seq, ",%s", root_path + offset);
264
265 if (append)
266 seq_puts(seq, ",append");
267
268 return 0;
269}
270
271static const struct super_operations hostfs_sbops = {
272 .alloc_inode = hostfs_alloc_inode,
273 .destroy_inode = hostfs_destroy_inode,
274 .evict_inode = hostfs_evict_inode,
275 .statfs = hostfs_statfs,
276 .show_options = hostfs_show_options,
277};
278
279static int hostfs_readdir(struct file *file, struct dir_context *ctx)
280{
281 void *dir;
282 char *name;
283 unsigned long long next, ino;
284 int error, len;
285 unsigned int type;
286
287 name = dentry_name(file->f_path.dentry);
288 if (name == NULL)
289 return -ENOMEM;
290 dir = open_dir(name, &error);
291 __putname(name);
292 if (dir == NULL)
293 return -error;
294 next = ctx->pos;
295 seek_dir(dir, next);
296 while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
297 if (!dir_emit(ctx, name, len, ino, type))
298 break;
299 ctx->pos = next;
300 }
301 close_dir(dir);
302 return 0;
303}
304
305static int hostfs_open(struct inode *ino, struct file *file)
306{
307 char *name;
308 fmode_t mode;
309 int err;
310 int r, w, fd;
311
312 mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
313 if ((mode & HOSTFS_I(ino)->mode) == mode)
314 return 0;
315
316 mode |= HOSTFS_I(ino)->mode;
317
318retry:
319 r = w = 0;
320
321 if (mode & FMODE_READ)
322 r = 1;
323 if (mode & FMODE_WRITE)
324 r = w = 1;
325
326 name = dentry_name(file->f_path.dentry);
327 if (name == NULL)
328 return -ENOMEM;
329
330 fd = open_file(name, r, w, append);
331 __putname(name);
332 if (fd < 0)
333 return fd;
334
335 mutex_lock(&HOSTFS_I(ino)->open_mutex);
336 /* somebody else had handled it first? */
337 if ((mode & HOSTFS_I(ino)->mode) == mode) {
338 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
339 close_file(&fd);
340 return 0;
341 }
342 if ((mode | HOSTFS_I(ino)->mode) != mode) {
343 mode |= HOSTFS_I(ino)->mode;
344 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
345 close_file(&fd);
346 goto retry;
347 }
348 if (HOSTFS_I(ino)->fd == -1) {
349 HOSTFS_I(ino)->fd = fd;
350 } else {
351 err = replace_file(fd, HOSTFS_I(ino)->fd);
352 close_file(&fd);
353 if (err < 0) {
354 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
355 return err;
356 }
357 }
358 HOSTFS_I(ino)->mode = mode;
359 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
360
361 return 0;
362}
363
364static int hostfs_file_release(struct inode *inode, struct file *file)
365{
366 filemap_write_and_wait(inode->i_mapping);
367
368 return 0;
369}
370
371static int hostfs_fsync(struct file *file, loff_t start, loff_t end,
372 int datasync)
373{
374 struct inode *inode = file->f_mapping->host;
375 int ret;
376
377 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
378 if (ret)
379 return ret;
380
381 mutex_lock(&inode->i_mutex);
382 ret = fsync_file(HOSTFS_I(inode)->fd, datasync);
383 mutex_unlock(&inode->i_mutex);
384
385 return ret;
386}
387
388static const struct file_operations hostfs_file_fops = {
389 .llseek = generic_file_llseek,
390 .splice_read = generic_file_splice_read,
391 .read_iter = generic_file_read_iter,
392 .write_iter = generic_file_write_iter,
393 .mmap = generic_file_mmap,
394 .open = hostfs_open,
395 .release = hostfs_file_release,
396 .fsync = hostfs_fsync,
397};
398
399static const struct file_operations hostfs_dir_fops = {
400 .llseek = generic_file_llseek,
401 .iterate = hostfs_readdir,
402 .read = generic_read_dir,
403 .open = hostfs_open,
404 .fsync = hostfs_fsync,
405};
406
407static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
408{
409 struct address_space *mapping = page->mapping;
410 struct inode *inode = mapping->host;
411 char *buffer;
412 loff_t base = page_offset(page);
413 int count = PAGE_CACHE_SIZE;
414 int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
415 int err;
416
417 if (page->index >= end_index)
418 count = inode->i_size & (PAGE_CACHE_SIZE-1);
419
420 buffer = kmap(page);
421
422 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
423 if (err != count) {
424 ClearPageUptodate(page);
425 goto out;
426 }
427
428 if (base > inode->i_size)
429 inode->i_size = base;
430
431 if (PageError(page))
432 ClearPageError(page);
433 err = 0;
434
435 out:
436 kunmap(page);
437
438 unlock_page(page);
439 return err;
440}
441
442static int hostfs_readpage(struct file *file, struct page *page)
443{
444 char *buffer;
445 loff_t start = page_offset(page);
446 int bytes_read, ret = 0;
447
448 buffer = kmap(page);
449 bytes_read = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
450 PAGE_CACHE_SIZE);
451 if (bytes_read < 0) {
452 ClearPageUptodate(page);
453 SetPageError(page);
454 ret = bytes_read;
455 goto out;
456 }
457
458 memset(buffer + bytes_read, 0, PAGE_CACHE_SIZE - bytes_read);
459
460 ClearPageError(page);
461 SetPageUptodate(page);
462
463 out:
464 flush_dcache_page(page);
465 kunmap(page);
466 unlock_page(page);
467 return ret;
468}
469
470static int hostfs_write_begin(struct file *file, struct address_space *mapping,
471 loff_t pos, unsigned len, unsigned flags,
472 struct page **pagep, void **fsdata)
473{
474 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
475
476 *pagep = grab_cache_page_write_begin(mapping, index, flags);
477 if (!*pagep)
478 return -ENOMEM;
479 return 0;
480}
481
482static int hostfs_write_end(struct file *file, struct address_space *mapping,
483 loff_t pos, unsigned len, unsigned copied,
484 struct page *page, void *fsdata)
485{
486 struct inode *inode = mapping->host;
487 void *buffer;
488 unsigned from = pos & (PAGE_CACHE_SIZE - 1);
489 int err;
490
491 buffer = kmap(page);
492 err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied);
493 kunmap(page);
494
495 if (!PageUptodate(page) && err == PAGE_CACHE_SIZE)
496 SetPageUptodate(page);
497
498 /*
499 * If err > 0, write_file has added err to pos, so we are comparing
500 * i_size against the last byte written.
501 */
502 if (err > 0 && (pos > inode->i_size))
503 inode->i_size = pos;
504 unlock_page(page);
505 page_cache_release(page);
506
507 return err;
508}
509
510static const struct address_space_operations hostfs_aops = {
511 .writepage = hostfs_writepage,
512 .readpage = hostfs_readpage,
513 .set_page_dirty = __set_page_dirty_nobuffers,
514 .write_begin = hostfs_write_begin,
515 .write_end = hostfs_write_end,
516};
517
518static int read_name(struct inode *ino, char *name)
519{
520 dev_t rdev;
521 struct hostfs_stat st;
522 int err = stat_file(name, &st, -1);
523 if (err)
524 return err;
525
526 /* Reencode maj and min with the kernel encoding.*/
527 rdev = MKDEV(st.maj, st.min);
528
529 switch (st.mode & S_IFMT) {
530 case S_IFLNK:
531 ino->i_op = &hostfs_link_iops;
532 break;
533 case S_IFDIR:
534 ino->i_op = &hostfs_dir_iops;
535 ino->i_fop = &hostfs_dir_fops;
536 break;
537 case S_IFCHR:
538 case S_IFBLK:
539 case S_IFIFO:
540 case S_IFSOCK:
541 init_special_inode(ino, st.mode & S_IFMT, rdev);
542 ino->i_op = &hostfs_iops;
543 break;
544 case S_IFREG:
545 ino->i_op = &hostfs_iops;
546 ino->i_fop = &hostfs_file_fops;
547 ino->i_mapping->a_ops = &hostfs_aops;
548 break;
549 default:
550 return -EIO;
551 }
552
553 ino->i_ino = st.ino;
554 ino->i_mode = st.mode;
555 set_nlink(ino, st.nlink);
556 i_uid_write(ino, st.uid);
557 i_gid_write(ino, st.gid);
558 ino->i_atime = st.atime;
559 ino->i_mtime = st.mtime;
560 ino->i_ctime = st.ctime;
561 ino->i_size = st.size;
562 ino->i_blocks = st.blocks;
563 return 0;
564}
565
566static int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
567 bool excl)
568{
569 struct inode *inode;
570 char *name;
571 int error, fd;
572
573 inode = hostfs_iget(dir->i_sb);
574 if (IS_ERR(inode)) {
575 error = PTR_ERR(inode);
576 goto out;
577 }
578
579 error = -ENOMEM;
580 name = dentry_name(dentry);
581 if (name == NULL)
582 goto out_put;
583
584 fd = file_create(name, mode & 0777);
585 if (fd < 0)
586 error = fd;
587 else
588 error = read_name(inode, name);
589
590 __putname(name);
591 if (error)
592 goto out_put;
593
594 HOSTFS_I(inode)->fd = fd;
595 HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
596 d_instantiate(dentry, inode);
597 return 0;
598
599 out_put:
600 iput(inode);
601 out:
602 return error;
603}
604
605static struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
606 unsigned int flags)
607{
608 struct inode *inode;
609 char *name;
610 int err;
611
612 inode = hostfs_iget(ino->i_sb);
613 if (IS_ERR(inode)) {
614 err = PTR_ERR(inode);
615 goto out;
616 }
617
618 err = -ENOMEM;
619 name = dentry_name(dentry);
620 if (name == NULL)
621 goto out_put;
622
623 err = read_name(inode, name);
624
625 __putname(name);
626 if (err == -ENOENT) {
627 iput(inode);
628 inode = NULL;
629 }
630 else if (err)
631 goto out_put;
632
633 d_add(dentry, inode);
634 return NULL;
635
636 out_put:
637 iput(inode);
638 out:
639 return ERR_PTR(err);
640}
641
642static int hostfs_link(struct dentry *to, struct inode *ino,
643 struct dentry *from)
644{
645 char *from_name, *to_name;
646 int err;
647
648 if ((from_name = dentry_name(from)) == NULL)
649 return -ENOMEM;
650 to_name = dentry_name(to);
651 if (to_name == NULL) {
652 __putname(from_name);
653 return -ENOMEM;
654 }
655 err = link_file(to_name, from_name);
656 __putname(from_name);
657 __putname(to_name);
658 return err;
659}
660
661static int hostfs_unlink(struct inode *ino, struct dentry *dentry)
662{
663 char *file;
664 int err;
665
666 if (append)
667 return -EPERM;
668
669 if ((file = dentry_name(dentry)) == NULL)
670 return -ENOMEM;
671
672 err = unlink_file(file);
673 __putname(file);
674 return err;
675}
676
677static int hostfs_symlink(struct inode *ino, struct dentry *dentry,
678 const char *to)
679{
680 char *file;
681 int err;
682
683 if ((file = dentry_name(dentry)) == NULL)
684 return -ENOMEM;
685 err = make_symlink(file, to);
686 __putname(file);
687 return err;
688}
689
690static int hostfs_mkdir(struct inode *ino, struct dentry *dentry, umode_t mode)
691{
692 char *file;
693 int err;
694
695 if ((file = dentry_name(dentry)) == NULL)
696 return -ENOMEM;
697 err = do_mkdir(file, mode);
698 __putname(file);
699 return err;
700}
701
702static int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
703{
704 char *file;
705 int err;
706
707 if ((file = dentry_name(dentry)) == NULL)
708 return -ENOMEM;
709 err = do_rmdir(file);
710 __putname(file);
711 return err;
712}
713
714static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
715{
716 struct inode *inode;
717 char *name;
718 int err;
719
720 inode = hostfs_iget(dir->i_sb);
721 if (IS_ERR(inode)) {
722 err = PTR_ERR(inode);
723 goto out;
724 }
725
726 err = -ENOMEM;
727 name = dentry_name(dentry);
728 if (name == NULL)
729 goto out_put;
730
731 init_special_inode(inode, mode, dev);
732 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
733 if (!err)
734 goto out_free;
735
736 err = read_name(inode, name);
737 __putname(name);
738 if (err)
739 goto out_put;
740 if (err)
741 goto out_put;
742
743 d_instantiate(dentry, inode);
744 return 0;
745
746 out_free:
747 __putname(name);
748 out_put:
749 iput(inode);
750 out:
751 return err;
752}
753
754static int hostfs_rename2(struct inode *old_dir, struct dentry *old_dentry,
755 struct inode *new_dir, struct dentry *new_dentry,
756 unsigned int flags)
757{
758 char *old_name, *new_name;
759 int err;
760
761 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
762 return -EINVAL;
763
764 old_name = dentry_name(old_dentry);
765 if (old_name == NULL)
766 return -ENOMEM;
767 new_name = dentry_name(new_dentry);
768 if (new_name == NULL) {
769 __putname(old_name);
770 return -ENOMEM;
771 }
772 if (!flags)
773 err = rename_file(old_name, new_name);
774 else
775 err = rename2_file(old_name, new_name, flags);
776
777 __putname(old_name);
778 __putname(new_name);
779 return err;
780}
781
782static int hostfs_permission(struct inode *ino, int desired)
783{
784 char *name;
785 int r = 0, w = 0, x = 0, err;
786
787 if (desired & MAY_NOT_BLOCK)
788 return -ECHILD;
789
790 if (desired & MAY_READ) r = 1;
791 if (desired & MAY_WRITE) w = 1;
792 if (desired & MAY_EXEC) x = 1;
793 name = inode_name(ino);
794 if (name == NULL)
795 return -ENOMEM;
796
797 if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
798 S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
799 err = 0;
800 else
801 err = access_file(name, r, w, x);
802 __putname(name);
803 if (!err)
804 err = generic_permission(ino, desired);
805 return err;
806}
807
808static int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
809{
810 struct inode *inode = d_inode(dentry);
811 struct hostfs_iattr attrs;
812 char *name;
813 int err;
814
815 int fd = HOSTFS_I(inode)->fd;
816
817 err = inode_change_ok(inode, attr);
818 if (err)
819 return err;
820
821 if (append)
822 attr->ia_valid &= ~ATTR_SIZE;
823
824 attrs.ia_valid = 0;
825 if (attr->ia_valid & ATTR_MODE) {
826 attrs.ia_valid |= HOSTFS_ATTR_MODE;
827 attrs.ia_mode = attr->ia_mode;
828 }
829 if (attr->ia_valid & ATTR_UID) {
830 attrs.ia_valid |= HOSTFS_ATTR_UID;
831 attrs.ia_uid = from_kuid(&init_user_ns, attr->ia_uid);
832 }
833 if (attr->ia_valid & ATTR_GID) {
834 attrs.ia_valid |= HOSTFS_ATTR_GID;
835 attrs.ia_gid = from_kgid(&init_user_ns, attr->ia_gid);
836 }
837 if (attr->ia_valid & ATTR_SIZE) {
838 attrs.ia_valid |= HOSTFS_ATTR_SIZE;
839 attrs.ia_size = attr->ia_size;
840 }
841 if (attr->ia_valid & ATTR_ATIME) {
842 attrs.ia_valid |= HOSTFS_ATTR_ATIME;
843 attrs.ia_atime = attr->ia_atime;
844 }
845 if (attr->ia_valid & ATTR_MTIME) {
846 attrs.ia_valid |= HOSTFS_ATTR_MTIME;
847 attrs.ia_mtime = attr->ia_mtime;
848 }
849 if (attr->ia_valid & ATTR_CTIME) {
850 attrs.ia_valid |= HOSTFS_ATTR_CTIME;
851 attrs.ia_ctime = attr->ia_ctime;
852 }
853 if (attr->ia_valid & ATTR_ATIME_SET) {
854 attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
855 }
856 if (attr->ia_valid & ATTR_MTIME_SET) {
857 attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
858 }
859 name = dentry_name(dentry);
860 if (name == NULL)
861 return -ENOMEM;
862 err = set_attr(name, &attrs, fd);
863 __putname(name);
864 if (err)
865 return err;
866
867 if ((attr->ia_valid & ATTR_SIZE) &&
868 attr->ia_size != i_size_read(inode))
869 truncate_setsize(inode, attr->ia_size);
870
871 setattr_copy(inode, attr);
872 mark_inode_dirty(inode);
873 return 0;
874}
875
876static const struct inode_operations hostfs_iops = {
877 .permission = hostfs_permission,
878 .setattr = hostfs_setattr,
879};
880
881static const struct inode_operations hostfs_dir_iops = {
882 .create = hostfs_create,
883 .lookup = hostfs_lookup,
884 .link = hostfs_link,
885 .unlink = hostfs_unlink,
886 .symlink = hostfs_symlink,
887 .mkdir = hostfs_mkdir,
888 .rmdir = hostfs_rmdir,
889 .mknod = hostfs_mknod,
890 .rename2 = hostfs_rename2,
891 .permission = hostfs_permission,
892 .setattr = hostfs_setattr,
893};
894
895static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
896{
897 char *link = __getname();
898 if (link) {
899 char *path = dentry_name(dentry);
900 int err = -ENOMEM;
901 if (path) {
902 err = hostfs_do_readlink(path, link, PATH_MAX);
903 if (err == PATH_MAX)
904 err = -E2BIG;
905 __putname(path);
906 }
907 if (err < 0) {
908 __putname(link);
909 link = ERR_PTR(err);
910 }
911 } else {
912 link = ERR_PTR(-ENOMEM);
913 }
914
915 nd_set_link(nd, link);
916 return NULL;
917}
918
919static void hostfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
920{
921 char *s = nd_get_link(nd);
922 if (!IS_ERR(s))
923 __putname(s);
924}
925
926static const struct inode_operations hostfs_link_iops = {
927 .readlink = generic_readlink,
928 .follow_link = hostfs_follow_link,
929 .put_link = hostfs_put_link,
930};
931
932static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
933{
934 struct inode *root_inode;
935 char *host_root_path, *req_root = d;
936 int err;
937
938 sb->s_blocksize = 1024;
939 sb->s_blocksize_bits = 10;
940 sb->s_magic = HOSTFS_SUPER_MAGIC;
941 sb->s_op = &hostfs_sbops;
942 sb->s_d_op = &simple_dentry_operations;
943 sb->s_maxbytes = MAX_LFS_FILESIZE;
944
945 /* NULL is printed as <NULL> by sprintf: avoid that. */
946 if (req_root == NULL)
947 req_root = "";
948
949 err = -ENOMEM;
950 sb->s_fs_info = host_root_path =
951 kmalloc(strlen(root_ino) + strlen(req_root) + 2, GFP_KERNEL);
952 if (host_root_path == NULL)
953 goto out;
954
955 sprintf(host_root_path, "%s/%s", root_ino, req_root);
956
957 root_inode = new_inode(sb);
958 if (!root_inode)
959 goto out;
960
961 err = read_name(root_inode, host_root_path);
962 if (err)
963 goto out_put;
964
965 if (S_ISLNK(root_inode->i_mode)) {
966 char *name = follow_link(host_root_path);
967 if (IS_ERR(name))
968 err = PTR_ERR(name);
969 else
970 err = read_name(root_inode, name);
971 kfree(name);
972 if (err)
973 goto out_put;
974 }
975
976 err = -ENOMEM;
977 sb->s_root = d_make_root(root_inode);
978 if (sb->s_root == NULL)
979 goto out;
980
981 return 0;
982
983out_put:
984 iput(root_inode);
985out:
986 return err;
987}
988
989static struct dentry *hostfs_read_sb(struct file_system_type *type,
990 int flags, const char *dev_name,
991 void *data)
992{
993 return mount_nodev(type, flags, data, hostfs_fill_sb_common);
994}
995
996static void hostfs_kill_sb(struct super_block *s)
997{
998 kill_anon_super(s);
999 kfree(s->s_fs_info);
1000}
1001
1002static struct file_system_type hostfs_type = {
1003 .owner = THIS_MODULE,
1004 .name = "hostfs",
1005 .mount = hostfs_read_sb,
1006 .kill_sb = hostfs_kill_sb,
1007 .fs_flags = 0,
1008};
1009MODULE_ALIAS_FS("hostfs");
1010
1011static int __init init_hostfs(void)
1012{
1013 return register_filesystem(&hostfs_type);
1014}
1015
1016static void __exit exit_hostfs(void)
1017{
1018 unregister_filesystem(&hostfs_type);
1019}
1020
1021module_init(init_hostfs)
1022module_exit(exit_hostfs)
1023MODULE_LICENSE("GPL");