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