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