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