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