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