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