]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/hostfs/hostfs_kern.c
hostfs: Set page flags in hostfs_readpage() correctly
[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
371fdab1 226 hi = kmalloc(sizeof(*hi), GFP_KERNEL);
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)
263 seq_printf(seq, ",%s", root_path + offset);
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;
3ee6bd8e 295 while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
8e28bc7e
AV
296 if (!dir_emit(ctx, name, len, ino, type))
297 break;
298 ctx->pos = next;
1da177e4
LT
299 }
300 close_dir(dir);
f1adc05e 301 return 0;
1da177e4
LT
302}
303
4c6dcafc 304static int hostfs_open(struct inode *ino, struct file *file)
1da177e4
LT
305{
306 char *name;
bd1052a2 307 fmode_t mode;
f8ad850f 308 int err;
bd1052a2 309 int r, w, fd;
1da177e4
LT
310
311 mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
84b3db04 312 if ((mode & HOSTFS_I(ino)->mode) == mode)
f1adc05e 313 return 0;
1da177e4 314
f8ad850f 315 mode |= HOSTFS_I(ino)->mode;
1da177e4 316
f8ad850f 317retry:
a9d1958b
RW
318 r = w = 0;
319
f8ad850f 320 if (mode & FMODE_READ)
1da177e4 321 r = 1;
f8ad850f 322 if (mode & FMODE_WRITE)
112a5da7 323 r = w = 1;
1da177e4 324
c5322220 325 name = dentry_name(file->f_path.dentry);
84b3db04 326 if (name == NULL)
f1adc05e 327 return -ENOMEM;
1da177e4
LT
328
329 fd = open_file(name, r, w, append);
e9193059 330 __putname(name);
84b3db04 331 if (fd < 0)
f1adc05e 332 return fd;
f8ad850f 333
69886e67 334 mutex_lock(&HOSTFS_I(ino)->open_mutex);
f8ad850f
AV
335 /* somebody else had handled it first? */
336 if ((mode & HOSTFS_I(ino)->mode) == mode) {
69886e67 337 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
af955658 338 close_file(&fd);
f8ad850f
AV
339 return 0;
340 }
341 if ((mode | HOSTFS_I(ino)->mode) != mode) {
342 mode |= HOSTFS_I(ino)->mode;
69886e67 343 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
f8ad850f
AV
344 close_file(&fd);
345 goto retry;
346 }
347 if (HOSTFS_I(ino)->fd == -1) {
348 HOSTFS_I(ino)->fd = fd;
349 } else {
350 err = replace_file(fd, HOSTFS_I(ino)->fd);
351 close_file(&fd);
352 if (err < 0) {
69886e67 353 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
f8ad850f
AV
354 return err;
355 }
356 }
357 HOSTFS_I(ino)->mode = mode;
69886e67 358 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
1da177e4 359
f1adc05e 360 return 0;
1da177e4
LT
361}
362
65984ff9
RW
363static int hostfs_file_release(struct inode *inode, struct file *file)
364{
365 filemap_write_and_wait(inode->i_mapping);
366
367 return 0;
368}
369
9e443bc3
JH
370static int hostfs_fsync(struct file *file, loff_t start, loff_t end,
371 int datasync)
1da177e4 372{
02c24a82
JB
373 struct inode *inode = file->f_mapping->host;
374 int ret;
375
376 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
377 if (ret)
378 return ret;
379
380 mutex_lock(&inode->i_mutex);
381 ret = fsync_file(HOSTFS_I(inode)->fd, datasync);
382 mutex_unlock(&inode->i_mutex);
383
384 return ret;
1da177e4
LT
385}
386
4b6f5d20 387static const struct file_operations hostfs_file_fops = {
1da177e4 388 .llseek = generic_file_llseek,
aad4f8bb 389 .read = new_sync_read,
5ffc4ef4 390 .splice_read = generic_file_splice_read,
aad4f8bb 391 .read_iter = generic_file_read_iter,
8174202b
AV
392 .write_iter = generic_file_write_iter,
393 .write = new_sync_write,
1da177e4 394 .mmap = generic_file_mmap,
4c6dcafc 395 .open = hostfs_open,
65984ff9 396 .release = hostfs_file_release,
1da177e4
LT
397 .fsync = hostfs_fsync,
398};
399
4b6f5d20 400static const struct file_operations hostfs_dir_fops = {
1da177e4 401 .llseek = generic_file_llseek,
8e28bc7e 402 .iterate = hostfs_readdir,
1da177e4 403 .read = generic_read_dir,
4c6dcafc
RW
404 .open = hostfs_open,
405 .fsync = hostfs_fsync,
1da177e4
LT
406};
407
9e443bc3 408static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
1da177e4
LT
409{
410 struct address_space *mapping = page->mapping;
411 struct inode *inode = mapping->host;
412 char *buffer;
413 unsigned long long base;
414 int count = PAGE_CACHE_SIZE;
415 int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
416 int err;
417
418 if (page->index >= end_index)
419 count = inode->i_size & (PAGE_CACHE_SIZE-1);
420
421 buffer = kmap(page);
422 base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
423
424 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
84b3db04 425 if (err != count) {
1da177e4
LT
426 ClearPageUptodate(page);
427 goto out;
428 }
429
430 if (base > inode->i_size)
431 inode->i_size = base;
432
433 if (PageError(page))
434 ClearPageError(page);
435 err = 0;
436
437 out:
438 kunmap(page);
439
440 unlock_page(page);
441 return err;
442}
443
9e443bc3 444static int hostfs_readpage(struct file *file, struct page *page)
1da177e4
LT
445{
446 char *buffer;
447 long long start;
b86b413a 448 int bytes_read, ret = 0;
1da177e4
LT
449
450 start = (long long) page->index << PAGE_CACHE_SHIFT;
451 buffer = kmap(page);
41761ddf 452 bytes_read = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
1da177e4 453 PAGE_CACHE_SIZE);
41761ddf 454 if (bytes_read < 0) {
b86b413a
RW
455 ClearPageUptodate(page);
456 SetPageError(page);
41761ddf 457 ret = bytes_read;
84b3db04 458 goto out;
41761ddf 459 }
1da177e4 460
41761ddf 461 memset(buffer + bytes_read, 0, PAGE_CACHE_SIZE - bytes_read);
1da177e4 462
b86b413a 463 ClearPageError(page);
1da177e4 464 SetPageUptodate(page);
b86b413a 465
1da177e4 466 out:
b86b413a 467 flush_dcache_page(page);
1da177e4
LT
468 kunmap(page);
469 unlock_page(page);
41761ddf 470 return ret;
1da177e4
LT
471}
472
9e443bc3
JH
473static int hostfs_write_begin(struct file *file, struct address_space *mapping,
474 loff_t pos, unsigned len, unsigned flags,
475 struct page **pagep, void **fsdata)
1da177e4 476{
ae361ff4 477 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
1da177e4 478
54566b2c 479 *pagep = grab_cache_page_write_begin(mapping, index, flags);
ae361ff4
NP
480 if (!*pagep)
481 return -ENOMEM;
482 return 0;
1da177e4
LT
483}
484
9e443bc3
JH
485static int hostfs_write_end(struct file *file, struct address_space *mapping,
486 loff_t pos, unsigned len, unsigned copied,
487 struct page *page, void *fsdata)
1da177e4 488{
1da177e4 489 struct inode *inode = mapping->host;
ae361ff4
NP
490 void *buffer;
491 unsigned from = pos & (PAGE_CACHE_SIZE - 1);
492 int err;
1da177e4 493
1da177e4 494 buffer = kmap(page);
ae361ff4
NP
495 err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied);
496 kunmap(page);
30f04a4e 497
ae361ff4
NP
498 if (!PageUptodate(page) && err == PAGE_CACHE_SIZE)
499 SetPageUptodate(page);
30f04a4e 500
84b3db04
JD
501 /*
502 * If err > 0, write_file has added err to pos, so we are comparing
ae361ff4
NP
503 * i_size against the last byte written.
504 */
505 if (err > 0 && (pos > inode->i_size))
506 inode->i_size = pos;
507 unlock_page(page);
508 page_cache_release(page);
1da177e4 509
f1adc05e 510 return err;
1da177e4
LT
511}
512
f5e54d6e 513static const struct address_space_operations hostfs_aops = {
1da177e4
LT
514 .writepage = hostfs_writepage,
515 .readpage = hostfs_readpage,
ffa0aea6 516 .set_page_dirty = __set_page_dirty_nobuffers,
ae361ff4
NP
517 .write_begin = hostfs_write_begin,
518 .write_end = hostfs_write_end,
1da177e4
LT
519};
520
4754b825 521static int read_name(struct inode *ino, char *name)
1da177e4 522{
4754b825
AV
523 dev_t rdev;
524 struct hostfs_stat st;
525 int err = stat_file(name, &st, -1);
526 if (err)
527 return err;
1da177e4 528
5e2df28c 529 /* Reencode maj and min with the kernel encoding.*/
4754b825 530 rdev = MKDEV(st.maj, st.min);
1da177e4 531
4754b825
AV
532 switch (st.mode & S_IFMT) {
533 case S_IFLNK:
d0352d3e 534 ino->i_op = &hostfs_link_iops;
1da177e4 535 break;
4754b825
AV
536 case S_IFDIR:
537 ino->i_op = &hostfs_dir_iops;
538 ino->i_fop = &hostfs_dir_fops;
1da177e4 539 break;
4754b825
AV
540 case S_IFCHR:
541 case S_IFBLK:
542 case S_IFIFO:
543 case S_IFSOCK:
544 init_special_inode(ino, st.mode & S_IFMT, rdev);
545 ino->i_op = &hostfs_iops;
1da177e4 546 break;
2ad2dca6 547 case S_IFREG:
4754b825
AV
548 ino->i_op = &hostfs_iops;
549 ino->i_fop = &hostfs_file_fops;
550 ino->i_mapping->a_ops = &hostfs_aops;
2ad2dca6
RW
551 break;
552 default:
553 return -EIO;
1da177e4 554 }
4754b825
AV
555
556 ino->i_ino = st.ino;
557 ino->i_mode = st.mode;
bfe86848 558 set_nlink(ino, st.nlink);
29f82ae5
EB
559 i_uid_write(ino, st.uid);
560 i_gid_write(ino, st.gid);
4754b825
AV
561 ino->i_atime = st.atime;
562 ino->i_mtime = st.mtime;
563 ino->i_ctime = st.ctime;
564 ino->i_size = st.size;
565 ino->i_blocks = st.blocks;
566 return 0;
1da177e4
LT
567}
568
9e443bc3
JH
569static int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
570 bool excl)
1da177e4
LT
571{
572 struct inode *inode;
573 char *name;
574 int error, fd;
575
0a370e5d
DH
576 inode = hostfs_iget(dir->i_sb);
577 if (IS_ERR(inode)) {
578 error = PTR_ERR(inode);
84b3db04 579 goto out;
0a370e5d 580 }
1da177e4 581
1da177e4 582 error = -ENOMEM;
c5322220 583 name = dentry_name(dentry);
84b3db04 584 if (name == NULL)
1da177e4
LT
585 goto out_put;
586
587 fd = file_create(name,
588 mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
589 mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
590 mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
4754b825 591 if (fd < 0)
1da177e4 592 error = fd;
4754b825 593 else
5e2df28c 594 error = read_name(inode, name);
1da177e4 595
e9193059 596 __putname(name);
84b3db04 597 if (error)
1da177e4
LT
598 goto out_put;
599
600 HOSTFS_I(inode)->fd = fd;
601 HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
602 d_instantiate(dentry, inode);
f1adc05e 603 return 0;
1da177e4
LT
604
605 out_put:
606 iput(inode);
607 out:
f1adc05e 608 return error;
1da177e4
LT
609}
610
9e443bc3
JH
611static struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
612 unsigned int flags)
1da177e4
LT
613{
614 struct inode *inode;
615 char *name;
616 int err;
617
0a370e5d
DH
618 inode = hostfs_iget(ino->i_sb);
619 if (IS_ERR(inode)) {
620 err = PTR_ERR(inode);
1da177e4 621 goto out;
0a370e5d 622 }
1da177e4 623
1da177e4 624 err = -ENOMEM;
c5322220 625 name = dentry_name(dentry);
84b3db04 626 if (name == NULL)
1da177e4
LT
627 goto out_put;
628
629 err = read_name(inode, name);
5e2df28c 630
e9193059 631 __putname(name);
84b3db04 632 if (err == -ENOENT) {
1da177e4
LT
633 iput(inode);
634 inode = NULL;
635 }
84b3db04 636 else if (err)
1da177e4
LT
637 goto out_put;
638
639 d_add(dentry, inode);
f1adc05e 640 return NULL;
1da177e4
LT
641
642 out_put:
643 iput(inode);
644 out:
f1adc05e 645 return ERR_PTR(err);
1da177e4
LT
646}
647
9e443bc3
JH
648static int hostfs_link(struct dentry *to, struct inode *ino,
649 struct dentry *from)
1da177e4 650{
f1adc05e
JD
651 char *from_name, *to_name;
652 int err;
1da177e4 653
c5322220 654 if ((from_name = dentry_name(from)) == NULL)
f1adc05e 655 return -ENOMEM;
c5322220 656 to_name = dentry_name(to);
84b3db04 657 if (to_name == NULL) {
e9193059 658 __putname(from_name);
f1adc05e 659 return -ENOMEM;
1da177e4 660 }
f1adc05e 661 err = link_file(to_name, from_name);
e9193059
AV
662 __putname(from_name);
663 __putname(to_name);
f1adc05e 664 return err;
1da177e4
LT
665}
666
9e443bc3 667static int hostfs_unlink(struct inode *ino, struct dentry *dentry)
1da177e4
LT
668{
669 char *file;
670 int err;
671
84b3db04 672 if (append)
f1adc05e 673 return -EPERM;
1da177e4 674
f8d7e187
AV
675 if ((file = dentry_name(dentry)) == NULL)
676 return -ENOMEM;
677
1da177e4 678 err = unlink_file(file);
e9193059 679 __putname(file);
f1adc05e 680 return err;
1da177e4
LT
681}
682
9e443bc3
JH
683static int hostfs_symlink(struct inode *ino, struct dentry *dentry,
684 const char *to)
1da177e4
LT
685{
686 char *file;
687 int err;
688
c5322220 689 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 690 return -ENOMEM;
1da177e4 691 err = make_symlink(file, to);
e9193059 692 __putname(file);
f1adc05e 693 return err;
1da177e4
LT
694}
695
9e443bc3 696static int hostfs_mkdir(struct inode *ino, struct dentry *dentry, umode_t mode)
1da177e4
LT
697{
698 char *file;
699 int err;
700
c5322220 701 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 702 return -ENOMEM;
1da177e4 703 err = do_mkdir(file, mode);
e9193059 704 __putname(file);
f1adc05e 705 return err;
1da177e4
LT
706}
707
9e443bc3 708static int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
1da177e4
LT
709{
710 char *file;
711 int err;
712
c5322220 713 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 714 return -ENOMEM;
1da177e4 715 err = do_rmdir(file);
e9193059 716 __putname(file);
f1adc05e 717 return err;
1da177e4
LT
718}
719
1a67aafb 720static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
1da177e4
LT
721{
722 struct inode *inode;
723 char *name;
0a370e5d 724 int err;
1da177e4 725
0a370e5d
DH
726 inode = hostfs_iget(dir->i_sb);
727 if (IS_ERR(inode)) {
728 err = PTR_ERR(inode);
1da177e4 729 goto out;
0a370e5d 730 }
1da177e4 731
1da177e4 732 err = -ENOMEM;
c5322220 733 name = dentry_name(dentry);
84b3db04 734 if (name == NULL)
1da177e4
LT
735 goto out_put;
736
737 init_special_inode(inode, mode, dev);
88f6cd0c 738 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
e9193059 739 if (!err)
1da177e4
LT
740 goto out_free;
741
742 err = read_name(inode, name);
e9193059 743 __putname(name);
5e2df28c
AV
744 if (err)
745 goto out_put;
84b3db04 746 if (err)
1da177e4
LT
747 goto out_put;
748
749 d_instantiate(dentry, inode);
f1adc05e 750 return 0;
1da177e4
LT
751
752 out_free:
e9193059 753 __putname(name);
1da177e4
LT
754 out_put:
755 iput(inode);
756 out:
f1adc05e 757 return err;
1da177e4
LT
758}
759
9a423bb6
MS
760static int hostfs_rename2(struct inode *old_dir, struct dentry *old_dentry,
761 struct inode *new_dir, struct dentry *new_dentry,
762 unsigned int flags)
1da177e4 763{
9a423bb6 764 char *old_name, *new_name;
1da177e4
LT
765 int err;
766
9a423bb6
MS
767 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
768 return -EINVAL;
769
770 old_name = dentry_name(old_dentry);
771 if (old_name == NULL)
f1adc05e 772 return -ENOMEM;
9a423bb6
MS
773 new_name = dentry_name(new_dentry);
774 if (new_name == NULL) {
775 __putname(old_name);
f1adc05e 776 return -ENOMEM;
1da177e4 777 }
9a423bb6
MS
778 if (!flags)
779 err = rename_file(old_name, new_name);
780 else
781 err = rename2_file(old_name, new_name, flags);
782
783 __putname(old_name);
784 __putname(new_name);
f1adc05e 785 return err;
1da177e4
LT
786}
787
9e443bc3 788static int hostfs_permission(struct inode *ino, int desired)
1da177e4
LT
789{
790 char *name;
791 int r = 0, w = 0, x = 0, err;
792
10556cb2 793 if (desired & MAY_NOT_BLOCK)
b74c79e9
NP
794 return -ECHILD;
795
1da177e4
LT
796 if (desired & MAY_READ) r = 1;
797 if (desired & MAY_WRITE) w = 1;
798 if (desired & MAY_EXEC) x = 1;
c5322220 799 name = inode_name(ino);
f1adc05e
JD
800 if (name == NULL)
801 return -ENOMEM;
1da177e4
LT
802
803 if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
84b3db04 804 S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
1da177e4
LT
805 err = 0;
806 else
807 err = access_file(name, r, w, x);
e9193059 808 __putname(name);
84b3db04 809 if (!err)
2830ba7f 810 err = generic_permission(ino, desired);
1da177e4
LT
811 return err;
812}
813
9e443bc3 814static int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
1da177e4 815{
1025774c 816 struct inode *inode = dentry->d_inode;
1da177e4
LT
817 struct hostfs_iattr attrs;
818 char *name;
819 int err;
820
1025774c 821 int fd = HOSTFS_I(inode)->fd;
5822b7fa 822
1025774c 823 err = inode_change_ok(inode, attr);
1da177e4
LT
824 if (err)
825 return err;
826
84b3db04 827 if (append)
1da177e4
LT
828 attr->ia_valid &= ~ATTR_SIZE;
829
830 attrs.ia_valid = 0;
84b3db04 831 if (attr->ia_valid & ATTR_MODE) {
1da177e4
LT
832 attrs.ia_valid |= HOSTFS_ATTR_MODE;
833 attrs.ia_mode = attr->ia_mode;
834 }
84b3db04 835 if (attr->ia_valid & ATTR_UID) {
1da177e4 836 attrs.ia_valid |= HOSTFS_ATTR_UID;
29f82ae5 837 attrs.ia_uid = from_kuid(&init_user_ns, attr->ia_uid);
1da177e4 838 }
84b3db04 839 if (attr->ia_valid & ATTR_GID) {
1da177e4 840 attrs.ia_valid |= HOSTFS_ATTR_GID;
29f82ae5 841 attrs.ia_gid = from_kgid(&init_user_ns, attr->ia_gid);
1da177e4 842 }
84b3db04 843 if (attr->ia_valid & ATTR_SIZE) {
1da177e4
LT
844 attrs.ia_valid |= HOSTFS_ATTR_SIZE;
845 attrs.ia_size = attr->ia_size;
846 }
84b3db04 847 if (attr->ia_valid & ATTR_ATIME) {
1da177e4
LT
848 attrs.ia_valid |= HOSTFS_ATTR_ATIME;
849 attrs.ia_atime = attr->ia_atime;
850 }
84b3db04 851 if (attr->ia_valid & ATTR_MTIME) {
1da177e4
LT
852 attrs.ia_valid |= HOSTFS_ATTR_MTIME;
853 attrs.ia_mtime = attr->ia_mtime;
854 }
84b3db04 855 if (attr->ia_valid & ATTR_CTIME) {
1da177e4
LT
856 attrs.ia_valid |= HOSTFS_ATTR_CTIME;
857 attrs.ia_ctime = attr->ia_ctime;
858 }
84b3db04 859 if (attr->ia_valid & ATTR_ATIME_SET) {
1da177e4
LT
860 attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
861 }
84b3db04 862 if (attr->ia_valid & ATTR_MTIME_SET) {
1da177e4
LT
863 attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
864 }
c5322220 865 name = dentry_name(dentry);
84b3db04 866 if (name == NULL)
f1adc05e 867 return -ENOMEM;
5822b7fa 868 err = set_attr(name, &attrs, fd);
e9193059 869 __putname(name);
84b3db04 870 if (err)
f1adc05e 871 return err;
1da177e4 872
1025774c 873 if ((attr->ia_valid & ATTR_SIZE) &&
bc077320 874 attr->ia_size != i_size_read(inode))
3be2be0a 875 truncate_setsize(inode, attr->ia_size);
1025774c
CH
876
877 setattr_copy(inode, attr);
878 mark_inode_dirty(inode);
879 return 0;
1da177e4
LT
880}
881
92e1d5be 882static const struct inode_operations hostfs_iops = {
1da177e4
LT
883 .permission = hostfs_permission,
884 .setattr = hostfs_setattr,
1da177e4
LT
885};
886
92e1d5be 887static const struct inode_operations hostfs_dir_iops = {
1da177e4
LT
888 .create = hostfs_create,
889 .lookup = hostfs_lookup,
890 .link = hostfs_link,
891 .unlink = hostfs_unlink,
892 .symlink = hostfs_symlink,
893 .mkdir = hostfs_mkdir,
894 .rmdir = hostfs_rmdir,
895 .mknod = hostfs_mknod,
9a423bb6 896 .rename2 = hostfs_rename2,
1da177e4
LT
897 .permission = hostfs_permission,
898 .setattr = hostfs_setattr,
1da177e4
LT
899};
900
d0352d3e
AV
901static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
902{
903 char *link = __getname();
904 if (link) {
905 char *path = dentry_name(dentry);
906 int err = -ENOMEM;
907 if (path) {
3b6036d1 908 err = hostfs_do_readlink(path, link, PATH_MAX);
d0352d3e
AV
909 if (err == PATH_MAX)
910 err = -E2BIG;
e9193059 911 __putname(path);
d0352d3e
AV
912 }
913 if (err < 0) {
914 __putname(link);
915 link = ERR_PTR(err);
916 }
917 } else {
918 link = ERR_PTR(-ENOMEM);
1da177e4 919 }
d0352d3e
AV
920
921 nd_set_link(nd, link);
922 return NULL;
923}
924
925static void hostfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
926{
927 char *s = nd_get_link(nd);
928 if (!IS_ERR(s))
929 __putname(s);
1da177e4
LT
930}
931
d0352d3e
AV
932static const struct inode_operations hostfs_link_iops = {
933 .readlink = generic_readlink,
934 .follow_link = hostfs_follow_link,
935 .put_link = hostfs_put_link,
1da177e4
LT
936};
937
938static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
939{
940 struct inode *root_inode;
75e8defb 941 char *host_root_path, *req_root = d;
1da177e4
LT
942 int err;
943
944 sb->s_blocksize = 1024;
945 sb->s_blocksize_bits = 10;
946 sb->s_magic = HOSTFS_SUPER_MAGIC;
947 sb->s_op = &hostfs_sbops;
b26d4cd3 948 sb->s_d_op = &simple_dentry_operations;
752fa51e 949 sb->s_maxbytes = MAX_LFS_FILESIZE;
1da177e4 950
a6eb0be6 951 /* NULL is printed as <NULL> by sprintf: avoid that. */
75e8defb
PBG
952 if (req_root == NULL)
953 req_root = "";
1da177e4
LT
954
955 err = -ENOMEM;
601d2c38
AV
956 sb->s_fs_info = host_root_path =
957 kmalloc(strlen(root_ino) + strlen(req_root) + 2, GFP_KERNEL);
84b3db04 958 if (host_root_path == NULL)
1da177e4
LT
959 goto out;
960
75e8defb 961 sprintf(host_root_path, "%s/%s", root_ino, req_root);
1da177e4 962
52b209f7
AV
963 root_inode = new_inode(sb);
964 if (!root_inode)
601d2c38 965 goto out;
1da177e4 966
4754b825
AV
967 err = read_name(root_inode, host_root_path);
968 if (err)
969 goto out_put;
52b209f7 970
4754b825 971 if (S_ISLNK(root_inode->i_mode)) {
52b209f7
AV
972 char *name = follow_link(host_root_path);
973 if (IS_ERR(name))
974 err = PTR_ERR(name);
975 else
976 err = read_name(root_inode, name);
977 kfree(name);
4754b825
AV
978 if (err)
979 goto out_put;
52b209f7 980 }
1da177e4 981
1da177e4 982 err = -ENOMEM;
48fde701 983 sb->s_root = d_make_root(root_inode);
84b3db04 984 if (sb->s_root == NULL)
48fde701 985 goto out;
1da177e4 986
f1adc05e 987 return 0;
1da177e4 988
f1adc05e
JD
989out_put:
990 iput(root_inode);
f1adc05e
JD
991out:
992 return err;
1da177e4
LT
993}
994
3c26ff6e 995static struct dentry *hostfs_read_sb(struct file_system_type *type,
454e2398 996 int flags, const char *dev_name,
3c26ff6e 997 void *data)
1da177e4 998{
3c26ff6e 999 return mount_nodev(type, flags, data, hostfs_fill_sb_common);
1da177e4
LT
1000}
1001
601d2c38
AV
1002static void hostfs_kill_sb(struct super_block *s)
1003{
1004 kill_anon_super(s);
1005 kfree(s->s_fs_info);
1006}
1007
1da177e4
LT
1008static struct file_system_type hostfs_type = {
1009 .owner = THIS_MODULE,
1010 .name = "hostfs",
3c26ff6e 1011 .mount = hostfs_read_sb,
601d2c38 1012 .kill_sb = hostfs_kill_sb,
1da177e4
LT
1013 .fs_flags = 0,
1014};
3e64fe5b 1015MODULE_ALIAS_FS("hostfs");
1da177e4
LT
1016
1017static int __init init_hostfs(void)
1018{
f1adc05e 1019 return register_filesystem(&hostfs_type);
1da177e4
LT
1020}
1021
1022static void __exit exit_hostfs(void)
1023{
1024 unregister_filesystem(&hostfs_type);
1025}
1026
1027module_init(init_hostfs)
1028module_exit(exit_hostfs)
1029MODULE_LICENSE("GPL");