]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/hostfs/hostfs_kern.c
vfs: push dentry_unhash on rename_dir into file systems
[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
79bf7c73
SW
686 dentry_unhash(dentry);
687
c5322220 688 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 689 return -ENOMEM;
1da177e4 690 err = do_rmdir(file);
e9193059 691 __putname(file);
f1adc05e 692 return err;
1da177e4
LT
693}
694
695int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
696{
697 struct inode *inode;
698 char *name;
0a370e5d 699 int err;
1da177e4 700
0a370e5d
DH
701 inode = hostfs_iget(dir->i_sb);
702 if (IS_ERR(inode)) {
703 err = PTR_ERR(inode);
1da177e4 704 goto out;
0a370e5d 705 }
1da177e4 706
1da177e4 707 err = -ENOMEM;
c5322220 708 name = dentry_name(dentry);
84b3db04 709 if (name == NULL)
1da177e4
LT
710 goto out_put;
711
712 init_special_inode(inode, mode, dev);
88f6cd0c 713 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
e9193059 714 if (!err)
1da177e4
LT
715 goto out_free;
716
717 err = read_name(inode, name);
e9193059 718 __putname(name);
5e2df28c
AV
719 if (err)
720 goto out_put;
84b3db04 721 if (err)
1da177e4
LT
722 goto out_put;
723
724 d_instantiate(dentry, inode);
f1adc05e 725 return 0;
1da177e4
LT
726
727 out_free:
e9193059 728 __putname(name);
1da177e4
LT
729 out_put:
730 iput(inode);
731 out:
f1adc05e 732 return err;
1da177e4
LT
733}
734
735int hostfs_rename(struct inode *from_ino, struct dentry *from,
736 struct inode *to_ino, struct dentry *to)
737{
738 char *from_name, *to_name;
739 int err;
740
e4eaac06
SW
741 if (to->d_inode && S_ISDIR(to->d_inode->i_mode))
742 dentry_unhash(to);
743
c5322220 744 if ((from_name = dentry_name(from)) == NULL)
f1adc05e 745 return -ENOMEM;
c5322220 746 if ((to_name = dentry_name(to)) == NULL) {
e9193059 747 __putname(from_name);
f1adc05e 748 return -ENOMEM;
1da177e4
LT
749 }
750 err = rename_file(from_name, to_name);
e9193059
AV
751 __putname(from_name);
752 __putname(to_name);
f1adc05e 753 return err;
1da177e4
LT
754}
755
b74c79e9 756int hostfs_permission(struct inode *ino, int desired, unsigned int flags)
1da177e4
LT
757{
758 char *name;
759 int r = 0, w = 0, x = 0, err;
760
b74c79e9
NP
761 if (flags & IPERM_FLAG_RCU)
762 return -ECHILD;
763
1da177e4
LT
764 if (desired & MAY_READ) r = 1;
765 if (desired & MAY_WRITE) w = 1;
766 if (desired & MAY_EXEC) x = 1;
c5322220 767 name = inode_name(ino);
f1adc05e
JD
768 if (name == NULL)
769 return -ENOMEM;
1da177e4
LT
770
771 if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
84b3db04 772 S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
1da177e4
LT
773 err = 0;
774 else
775 err = access_file(name, r, w, x);
e9193059 776 __putname(name);
84b3db04 777 if (!err)
b74c79e9 778 err = generic_permission(ino, desired, flags, NULL);
1da177e4
LT
779 return err;
780}
781
782int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
783{
1025774c 784 struct inode *inode = dentry->d_inode;
1da177e4
LT
785 struct hostfs_iattr attrs;
786 char *name;
787 int err;
788
1025774c 789 int fd = HOSTFS_I(inode)->fd;
5822b7fa 790
1025774c 791 err = inode_change_ok(inode, attr);
1da177e4
LT
792 if (err)
793 return err;
794
84b3db04 795 if (append)
1da177e4
LT
796 attr->ia_valid &= ~ATTR_SIZE;
797
798 attrs.ia_valid = 0;
84b3db04 799 if (attr->ia_valid & ATTR_MODE) {
1da177e4
LT
800 attrs.ia_valid |= HOSTFS_ATTR_MODE;
801 attrs.ia_mode = attr->ia_mode;
802 }
84b3db04 803 if (attr->ia_valid & ATTR_UID) {
1da177e4
LT
804 attrs.ia_valid |= HOSTFS_ATTR_UID;
805 attrs.ia_uid = attr->ia_uid;
806 }
84b3db04 807 if (attr->ia_valid & ATTR_GID) {
1da177e4
LT
808 attrs.ia_valid |= HOSTFS_ATTR_GID;
809 attrs.ia_gid = attr->ia_gid;
810 }
84b3db04 811 if (attr->ia_valid & ATTR_SIZE) {
1da177e4
LT
812 attrs.ia_valid |= HOSTFS_ATTR_SIZE;
813 attrs.ia_size = attr->ia_size;
814 }
84b3db04 815 if (attr->ia_valid & ATTR_ATIME) {
1da177e4
LT
816 attrs.ia_valid |= HOSTFS_ATTR_ATIME;
817 attrs.ia_atime = attr->ia_atime;
818 }
84b3db04 819 if (attr->ia_valid & ATTR_MTIME) {
1da177e4
LT
820 attrs.ia_valid |= HOSTFS_ATTR_MTIME;
821 attrs.ia_mtime = attr->ia_mtime;
822 }
84b3db04 823 if (attr->ia_valid & ATTR_CTIME) {
1da177e4
LT
824 attrs.ia_valid |= HOSTFS_ATTR_CTIME;
825 attrs.ia_ctime = attr->ia_ctime;
826 }
84b3db04 827 if (attr->ia_valid & ATTR_ATIME_SET) {
1da177e4
LT
828 attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
829 }
84b3db04 830 if (attr->ia_valid & ATTR_MTIME_SET) {
1da177e4
LT
831 attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
832 }
c5322220 833 name = dentry_name(dentry);
84b3db04 834 if (name == NULL)
f1adc05e 835 return -ENOMEM;
5822b7fa 836 err = set_attr(name, &attrs, fd);
e9193059 837 __putname(name);
84b3db04 838 if (err)
f1adc05e 839 return err;
1da177e4 840
1025774c
CH
841 if ((attr->ia_valid & ATTR_SIZE) &&
842 attr->ia_size != i_size_read(inode)) {
843 int error;
844
845 error = vmtruncate(inode, attr->ia_size);
846 if (err)
847 return err;
848 }
849
850 setattr_copy(inode, attr);
851 mark_inode_dirty(inode);
852 return 0;
1da177e4
LT
853}
854
92e1d5be 855static const struct inode_operations hostfs_iops = {
1da177e4
LT
856 .create = hostfs_create,
857 .link = hostfs_link,
858 .unlink = hostfs_unlink,
859 .symlink = hostfs_symlink,
860 .mkdir = hostfs_mkdir,
861 .rmdir = hostfs_rmdir,
862 .mknod = hostfs_mknod,
863 .rename = hostfs_rename,
1da177e4
LT
864 .permission = hostfs_permission,
865 .setattr = hostfs_setattr,
1da177e4
LT
866};
867
92e1d5be 868static const struct inode_operations hostfs_dir_iops = {
1da177e4
LT
869 .create = hostfs_create,
870 .lookup = hostfs_lookup,
871 .link = hostfs_link,
872 .unlink = hostfs_unlink,
873 .symlink = hostfs_symlink,
874 .mkdir = hostfs_mkdir,
875 .rmdir = hostfs_rmdir,
876 .mknod = hostfs_mknod,
877 .rename = hostfs_rename,
1da177e4
LT
878 .permission = hostfs_permission,
879 .setattr = hostfs_setattr,
1da177e4
LT
880};
881
d0352d3e
AV
882static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
883{
884 char *link = __getname();
885 if (link) {
886 char *path = dentry_name(dentry);
887 int err = -ENOMEM;
888 if (path) {
3b6036d1 889 err = hostfs_do_readlink(path, link, PATH_MAX);
d0352d3e
AV
890 if (err == PATH_MAX)
891 err = -E2BIG;
e9193059 892 __putname(path);
d0352d3e
AV
893 }
894 if (err < 0) {
895 __putname(link);
896 link = ERR_PTR(err);
897 }
898 } else {
899 link = ERR_PTR(-ENOMEM);
1da177e4 900 }
d0352d3e
AV
901
902 nd_set_link(nd, link);
903 return NULL;
904}
905
906static void hostfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
907{
908 char *s = nd_get_link(nd);
909 if (!IS_ERR(s))
910 __putname(s);
1da177e4
LT
911}
912
d0352d3e
AV
913static const struct inode_operations hostfs_link_iops = {
914 .readlink = generic_readlink,
915 .follow_link = hostfs_follow_link,
916 .put_link = hostfs_put_link,
1da177e4
LT
917};
918
919static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
920{
921 struct inode *root_inode;
75e8defb 922 char *host_root_path, *req_root = d;
1da177e4
LT
923 int err;
924
925 sb->s_blocksize = 1024;
926 sb->s_blocksize_bits = 10;
927 sb->s_magic = HOSTFS_SUPER_MAGIC;
928 sb->s_op = &hostfs_sbops;
f772c4a6 929 sb->s_d_op = &hostfs_dentry_ops;
752fa51e 930 sb->s_maxbytes = MAX_LFS_FILESIZE;
1da177e4 931
a6eb0be6 932 /* NULL is printed as <NULL> by sprintf: avoid that. */
75e8defb
PBG
933 if (req_root == NULL)
934 req_root = "";
1da177e4
LT
935
936 err = -ENOMEM;
601d2c38
AV
937 sb->s_fs_info = host_root_path =
938 kmalloc(strlen(root_ino) + strlen(req_root) + 2, GFP_KERNEL);
84b3db04 939 if (host_root_path == NULL)
1da177e4
LT
940 goto out;
941
75e8defb 942 sprintf(host_root_path, "%s/%s", root_ino, req_root);
1da177e4 943
52b209f7
AV
944 root_inode = new_inode(sb);
945 if (!root_inode)
601d2c38 946 goto out;
1da177e4 947
4754b825
AV
948 err = read_name(root_inode, host_root_path);
949 if (err)
950 goto out_put;
52b209f7 951
4754b825 952 if (S_ISLNK(root_inode->i_mode)) {
52b209f7
AV
953 char *name = follow_link(host_root_path);
954 if (IS_ERR(name))
955 err = PTR_ERR(name);
956 else
957 err = read_name(root_inode, name);
958 kfree(name);
4754b825
AV
959 if (err)
960 goto out_put;
52b209f7 961 }
1da177e4 962
1da177e4
LT
963 err = -ENOMEM;
964 sb->s_root = d_alloc_root(root_inode);
84b3db04 965 if (sb->s_root == NULL)
1da177e4
LT
966 goto out_put;
967
f1adc05e 968 return 0;
1da177e4 969
f1adc05e
JD
970out_put:
971 iput(root_inode);
f1adc05e
JD
972out:
973 return err;
1da177e4
LT
974}
975
3c26ff6e 976static struct dentry *hostfs_read_sb(struct file_system_type *type,
454e2398 977 int flags, const char *dev_name,
3c26ff6e 978 void *data)
1da177e4 979{
3c26ff6e 980 return mount_nodev(type, flags, data, hostfs_fill_sb_common);
1da177e4
LT
981}
982
601d2c38
AV
983static void hostfs_kill_sb(struct super_block *s)
984{
985 kill_anon_super(s);
986 kfree(s->s_fs_info);
987}
988
1da177e4
LT
989static struct file_system_type hostfs_type = {
990 .owner = THIS_MODULE,
991 .name = "hostfs",
3c26ff6e 992 .mount = hostfs_read_sb,
601d2c38 993 .kill_sb = hostfs_kill_sb,
1da177e4
LT
994 .fs_flags = 0,
995};
996
997static int __init init_hostfs(void)
998{
f1adc05e 999 return register_filesystem(&hostfs_type);
1da177e4
LT
1000}
1001
1002static void __exit exit_hostfs(void)
1003{
1004 unregister_filesystem(&hostfs_type);
1005}
1006
1007module_init(init_hostfs)
1008module_exit(exit_hostfs)
1009MODULE_LICENSE("GPL");