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

source code of linux/fs/hostfs/hostfs_kern.c