]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - fs/hostfs/hostfs_kern.c
Merge branch 'i2c/for-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
[mirror_ubuntu-jammy-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
08ccfc5c 246static void hostfs_free_inode(struct inode *inode)
1da177e4 247{
1da177e4
LT
248 kfree(HOSTFS_I(inode));
249}
fa0d7e3d 250
34c80b1d 251static int hostfs_show_options(struct seq_file *seq, struct dentry *root)
dd2cc4df 252{
34c80b1d 253 const char *root_path = root->d_sb->s_fs_info;
dd2cc4df
MS
254 size_t offset = strlen(root_ino) + 1;
255
256 if (strlen(root_path) > offset)
a068acf2 257 seq_show_option(seq, root_path + offset, NULL);
dd2cc4df 258
7f74a668
RW
259 if (append)
260 seq_puts(seq, ",append");
261
dd2cc4df
MS
262 return 0;
263}
264
ee9b6d61 265static const struct super_operations hostfs_sbops = {
1da177e4 266 .alloc_inode = hostfs_alloc_inode,
08ccfc5c 267 .free_inode = hostfs_free_inode,
e971a6d7 268 .evict_inode = hostfs_evict_inode,
1da177e4 269 .statfs = hostfs_statfs,
dd2cc4df 270 .show_options = hostfs_show_options,
1da177e4
LT
271};
272
9e443bc3 273static int hostfs_readdir(struct file *file, struct dir_context *ctx)
1da177e4
LT
274{
275 void *dir;
276 char *name;
277 unsigned long long next, ino;
278 int error, len;
3ee6bd8e 279 unsigned int type;
1da177e4 280
c5322220 281 name = dentry_name(file->f_path.dentry);
84b3db04 282 if (name == NULL)
f1adc05e 283 return -ENOMEM;
1da177e4 284 dir = open_dir(name, &error);
e9193059 285 __putname(name);
84b3db04 286 if (dir == NULL)
f1adc05e 287 return -error;
8e28bc7e 288 next = ctx->pos;
0c9bd636 289 seek_dir(dir, next);
3ee6bd8e 290 while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
8e28bc7e
AV
291 if (!dir_emit(ctx, name, len, ino, type))
292 break;
293 ctx->pos = next;
1da177e4
LT
294 }
295 close_dir(dir);
f1adc05e 296 return 0;
1da177e4
LT
297}
298
4c6dcafc 299static int hostfs_open(struct inode *ino, struct file *file)
1da177e4
LT
300{
301 char *name;
bd1052a2 302 fmode_t mode;
f8ad850f 303 int err;
bd1052a2 304 int r, w, fd;
1da177e4
LT
305
306 mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
84b3db04 307 if ((mode & HOSTFS_I(ino)->mode) == mode)
f1adc05e 308 return 0;
1da177e4 309
f8ad850f 310 mode |= HOSTFS_I(ino)->mode;
1da177e4 311
f8ad850f 312retry:
a9d1958b
RW
313 r = w = 0;
314
f8ad850f 315 if (mode & FMODE_READ)
1da177e4 316 r = 1;
f8ad850f 317 if (mode & FMODE_WRITE)
112a5da7 318 r = w = 1;
1da177e4 319
c5322220 320 name = dentry_name(file->f_path.dentry);
84b3db04 321 if (name == NULL)
f1adc05e 322 return -ENOMEM;
1da177e4
LT
323
324 fd = open_file(name, r, w, append);
e9193059 325 __putname(name);
84b3db04 326 if (fd < 0)
f1adc05e 327 return fd;
f8ad850f 328
69886e67 329 mutex_lock(&HOSTFS_I(ino)->open_mutex);
f8ad850f
AV
330 /* somebody else had handled it first? */
331 if ((mode & HOSTFS_I(ino)->mode) == mode) {
69886e67 332 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
af955658 333 close_file(&fd);
f8ad850f
AV
334 return 0;
335 }
336 if ((mode | HOSTFS_I(ino)->mode) != mode) {
337 mode |= HOSTFS_I(ino)->mode;
69886e67 338 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
f8ad850f
AV
339 close_file(&fd);
340 goto retry;
341 }
342 if (HOSTFS_I(ino)->fd == -1) {
343 HOSTFS_I(ino)->fd = fd;
344 } else {
345 err = replace_file(fd, HOSTFS_I(ino)->fd);
346 close_file(&fd);
347 if (err < 0) {
69886e67 348 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
f8ad850f
AV
349 return err;
350 }
351 }
352 HOSTFS_I(ino)->mode = mode;
69886e67 353 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
1da177e4 354
f1adc05e 355 return 0;
1da177e4
LT
356}
357
65984ff9
RW
358static int hostfs_file_release(struct inode *inode, struct file *file)
359{
360 filemap_write_and_wait(inode->i_mapping);
361
362 return 0;
363}
364
9e443bc3
JH
365static int hostfs_fsync(struct file *file, loff_t start, loff_t end,
366 int datasync)
1da177e4 367{
02c24a82
JB
368 struct inode *inode = file->f_mapping->host;
369 int ret;
370
3b49c9a1 371 ret = file_write_and_wait_range(file, start, end);
02c24a82
JB
372 if (ret)
373 return ret;
374
5955102c 375 inode_lock(inode);
02c24a82 376 ret = fsync_file(HOSTFS_I(inode)->fd, datasync);
5955102c 377 inode_unlock(inode);
02c24a82
JB
378
379 return ret;
1da177e4
LT
380}
381
4b6f5d20 382static const struct file_operations hostfs_file_fops = {
1da177e4 383 .llseek = generic_file_llseek,
5ffc4ef4 384 .splice_read = generic_file_splice_read,
aad4f8bb 385 .read_iter = generic_file_read_iter,
8174202b 386 .write_iter = generic_file_write_iter,
1da177e4 387 .mmap = generic_file_mmap,
4c6dcafc 388 .open = hostfs_open,
65984ff9 389 .release = hostfs_file_release,
1da177e4
LT
390 .fsync = hostfs_fsync,
391};
392
4b6f5d20 393static const struct file_operations hostfs_dir_fops = {
1da177e4 394 .llseek = generic_file_llseek,
552a9d48 395 .iterate_shared = hostfs_readdir,
1da177e4 396 .read = generic_read_dir,
4c6dcafc
RW
397 .open = hostfs_open,
398 .fsync = hostfs_fsync,
1da177e4
LT
399};
400
9e443bc3 401static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
1da177e4
LT
402{
403 struct address_space *mapping = page->mapping;
404 struct inode *inode = mapping->host;
405 char *buffer;
af6aa1b9 406 loff_t base = page_offset(page);
09cbfeaf
KS
407 int count = PAGE_SIZE;
408 int end_index = inode->i_size >> PAGE_SHIFT;
1da177e4
LT
409 int err;
410
411 if (page->index >= end_index)
09cbfeaf 412 count = inode->i_size & (PAGE_SIZE-1);
1da177e4
LT
413
414 buffer = kmap(page);
1da177e4
LT
415
416 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
84b3db04 417 if (err != count) {
1da177e4
LT
418 ClearPageUptodate(page);
419 goto out;
420 }
421
422 if (base > inode->i_size)
423 inode->i_size = base;
424
425 if (PageError(page))
426 ClearPageError(page);
427 err = 0;
428
429 out:
430 kunmap(page);
431
432 unlock_page(page);
433 return err;
434}
435
9e443bc3 436static int hostfs_readpage(struct file *file, struct page *page)
1da177e4
LT
437{
438 char *buffer;
af6aa1b9 439 loff_t start = page_offset(page);
b86b413a 440 int bytes_read, ret = 0;
1da177e4 441
1da177e4 442 buffer = kmap(page);
41761ddf 443 bytes_read = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
09cbfeaf 444 PAGE_SIZE);
41761ddf 445 if (bytes_read < 0) {
b86b413a
RW
446 ClearPageUptodate(page);
447 SetPageError(page);
41761ddf 448 ret = bytes_read;
84b3db04 449 goto out;
41761ddf 450 }
1da177e4 451
09cbfeaf 452 memset(buffer + bytes_read, 0, PAGE_SIZE - bytes_read);
1da177e4 453
b86b413a 454 ClearPageError(page);
1da177e4 455 SetPageUptodate(page);
b86b413a 456
1da177e4 457 out:
b86b413a 458 flush_dcache_page(page);
1da177e4
LT
459 kunmap(page);
460 unlock_page(page);
41761ddf 461 return ret;
1da177e4
LT
462}
463
9e443bc3
JH
464static int hostfs_write_begin(struct file *file, struct address_space *mapping,
465 loff_t pos, unsigned len, unsigned flags,
466 struct page **pagep, void **fsdata)
1da177e4 467{
09cbfeaf 468 pgoff_t index = pos >> PAGE_SHIFT;
1da177e4 469
54566b2c 470 *pagep = grab_cache_page_write_begin(mapping, index, flags);
ae361ff4
NP
471 if (!*pagep)
472 return -ENOMEM;
473 return 0;
1da177e4
LT
474}
475
9e443bc3
JH
476static int hostfs_write_end(struct file *file, struct address_space *mapping,
477 loff_t pos, unsigned len, unsigned copied,
478 struct page *page, void *fsdata)
1da177e4 479{
1da177e4 480 struct inode *inode = mapping->host;
ae361ff4 481 void *buffer;
09cbfeaf 482 unsigned from = pos & (PAGE_SIZE - 1);
ae361ff4 483 int err;
1da177e4 484
1da177e4 485 buffer = kmap(page);
ae361ff4
NP
486 err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied);
487 kunmap(page);
30f04a4e 488
09cbfeaf 489 if (!PageUptodate(page) && err == PAGE_SIZE)
ae361ff4 490 SetPageUptodate(page);
30f04a4e 491
84b3db04
JD
492 /*
493 * If err > 0, write_file has added err to pos, so we are comparing
ae361ff4
NP
494 * i_size against the last byte written.
495 */
496 if (err > 0 && (pos > inode->i_size))
497 inode->i_size = pos;
498 unlock_page(page);
09cbfeaf 499 put_page(page);
1da177e4 500
f1adc05e 501 return err;
1da177e4
LT
502}
503
f5e54d6e 504static const struct address_space_operations hostfs_aops = {
1da177e4
LT
505 .writepage = hostfs_writepage,
506 .readpage = hostfs_readpage,
ffa0aea6 507 .set_page_dirty = __set_page_dirty_nobuffers,
ae361ff4
NP
508 .write_begin = hostfs_write_begin,
509 .write_end = hostfs_write_end,
1da177e4
LT
510};
511
4754b825 512static int read_name(struct inode *ino, char *name)
1da177e4 513{
4754b825
AV
514 dev_t rdev;
515 struct hostfs_stat st;
516 int err = stat_file(name, &st, -1);
517 if (err)
518 return err;
1da177e4 519
5e2df28c 520 /* Reencode maj and min with the kernel encoding.*/
4754b825 521 rdev = MKDEV(st.maj, st.min);
1da177e4 522
4754b825
AV
523 switch (st.mode & S_IFMT) {
524 case S_IFLNK:
d0352d3e 525 ino->i_op = &hostfs_link_iops;
1da177e4 526 break;
4754b825
AV
527 case S_IFDIR:
528 ino->i_op = &hostfs_dir_iops;
529 ino->i_fop = &hostfs_dir_fops;
1da177e4 530 break;
4754b825
AV
531 case S_IFCHR:
532 case S_IFBLK:
533 case S_IFIFO:
534 case S_IFSOCK:
535 init_special_inode(ino, st.mode & S_IFMT, rdev);
536 ino->i_op = &hostfs_iops;
1da177e4 537 break;
2ad2dca6 538 case S_IFREG:
4754b825
AV
539 ino->i_op = &hostfs_iops;
540 ino->i_fop = &hostfs_file_fops;
541 ino->i_mapping->a_ops = &hostfs_aops;
2ad2dca6
RW
542 break;
543 default:
544 return -EIO;
1da177e4 545 }
4754b825
AV
546
547 ino->i_ino = st.ino;
548 ino->i_mode = st.mode;
bfe86848 549 set_nlink(ino, st.nlink);
29f82ae5
EB
550 i_uid_write(ino, st.uid);
551 i_gid_write(ino, st.gid);
95582b00
DD
552 ino->i_atime = timespec_to_timespec64(st.atime);
553 ino->i_mtime = timespec_to_timespec64(st.mtime);
554 ino->i_ctime = timespec_to_timespec64(st.ctime);
4754b825
AV
555 ino->i_size = st.size;
556 ino->i_blocks = st.blocks;
557 return 0;
1da177e4
LT
558}
559
9e443bc3
JH
560static int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
561 bool excl)
1da177e4
LT
562{
563 struct inode *inode;
564 char *name;
565 int error, fd;
566
0a370e5d
DH
567 inode = hostfs_iget(dir->i_sb);
568 if (IS_ERR(inode)) {
569 error = PTR_ERR(inode);
84b3db04 570 goto out;
0a370e5d 571 }
1da177e4 572
1da177e4 573 error = -ENOMEM;
c5322220 574 name = dentry_name(dentry);
84b3db04 575 if (name == NULL)
1da177e4
LT
576 goto out_put;
577
a718c922 578 fd = file_create(name, mode & 0777);
4754b825 579 if (fd < 0)
1da177e4 580 error = fd;
4754b825 581 else
5e2df28c 582 error = read_name(inode, name);
1da177e4 583
e9193059 584 __putname(name);
84b3db04 585 if (error)
1da177e4
LT
586 goto out_put;
587
588 HOSTFS_I(inode)->fd = fd;
589 HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
590 d_instantiate(dentry, inode);
f1adc05e 591 return 0;
1da177e4
LT
592
593 out_put:
594 iput(inode);
595 out:
f1adc05e 596 return error;
1da177e4
LT
597}
598
9e443bc3
JH
599static struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
600 unsigned int flags)
1da177e4
LT
601{
602 struct inode *inode;
603 char *name;
604 int err;
605
0a370e5d 606 inode = hostfs_iget(ino->i_sb);
50f30740 607 if (IS_ERR(inode))
1da177e4
LT
608 goto out;
609
1da177e4 610 err = -ENOMEM;
c5322220 611 name = dentry_name(dentry);
50f30740
AV
612 if (name) {
613 err = read_name(inode, name);
614 __putname(name);
615 }
616 if (err) {
1da177e4 617 iput(inode);
50f30740 618 inode = (err == -ENOENT) ? NULL : ERR_PTR(err);
1da177e4 619 }
1da177e4 620 out:
50f30740 621 return d_splice_alias(inode, dentry);
1da177e4
LT
622}
623
9e443bc3
JH
624static int hostfs_link(struct dentry *to, struct inode *ino,
625 struct dentry *from)
1da177e4 626{
f1adc05e
JD
627 char *from_name, *to_name;
628 int err;
1da177e4 629
c5322220 630 if ((from_name = dentry_name(from)) == NULL)
f1adc05e 631 return -ENOMEM;
c5322220 632 to_name = dentry_name(to);
84b3db04 633 if (to_name == NULL) {
e9193059 634 __putname(from_name);
f1adc05e 635 return -ENOMEM;
1da177e4 636 }
f1adc05e 637 err = link_file(to_name, from_name);
e9193059
AV
638 __putname(from_name);
639 __putname(to_name);
f1adc05e 640 return err;
1da177e4
LT
641}
642
9e443bc3 643static int hostfs_unlink(struct inode *ino, struct dentry *dentry)
1da177e4
LT
644{
645 char *file;
646 int err;
647
84b3db04 648 if (append)
f1adc05e 649 return -EPERM;
1da177e4 650
f8d7e187
AV
651 if ((file = dentry_name(dentry)) == NULL)
652 return -ENOMEM;
653
1da177e4 654 err = unlink_file(file);
e9193059 655 __putname(file);
f1adc05e 656 return err;
1da177e4
LT
657}
658
9e443bc3
JH
659static int hostfs_symlink(struct inode *ino, struct dentry *dentry,
660 const char *to)
1da177e4
LT
661{
662 char *file;
663 int err;
664
c5322220 665 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 666 return -ENOMEM;
1da177e4 667 err = make_symlink(file, to);
e9193059 668 __putname(file);
f1adc05e 669 return err;
1da177e4
LT
670}
671
9e443bc3 672static int hostfs_mkdir(struct inode *ino, struct dentry *dentry, umode_t mode)
1da177e4
LT
673{
674 char *file;
675 int err;
676
c5322220 677 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 678 return -ENOMEM;
1da177e4 679 err = do_mkdir(file, mode);
e9193059 680 __putname(file);
f1adc05e 681 return err;
1da177e4
LT
682}
683
9e443bc3 684static int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
1da177e4
LT
685{
686 char *file;
687 int err;
688
c5322220 689 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 690 return -ENOMEM;
6380161c 691 err = hostfs_do_rmdir(file);
e9193059 692 __putname(file);
f1adc05e 693 return err;
1da177e4
LT
694}
695
1a67aafb 696static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
1da177e4
LT
697{
698 struct inode *inode;
699 char *name;
0a370e5d 700 int err;
1da177e4 701
0a370e5d
DH
702 inode = hostfs_iget(dir->i_sb);
703 if (IS_ERR(inode)) {
704 err = PTR_ERR(inode);
1da177e4 705 goto out;
0a370e5d 706 }
1da177e4 707
1da177e4 708 err = -ENOMEM;
c5322220 709 name = dentry_name(dentry);
84b3db04 710 if (name == NULL)
1da177e4
LT
711 goto out_put;
712
713 init_special_inode(inode, mode, dev);
88f6cd0c 714 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
9f2dfda2 715 if (err)
1da177e4
LT
716 goto out_free;
717
718 err = read_name(inode, name);
e9193059 719 __putname(name);
5e2df28c
AV
720 if (err)
721 goto out_put;
1da177e4
LT
722
723 d_instantiate(dentry, inode);
f1adc05e 724 return 0;
1da177e4
LT
725
726 out_free:
e9193059 727 __putname(name);
1da177e4
LT
728 out_put:
729 iput(inode);
730 out:
f1adc05e 731 return err;
1da177e4
LT
732}
733
9a423bb6
MS
734static int hostfs_rename2(struct inode *old_dir, struct dentry *old_dentry,
735 struct inode *new_dir, struct dentry *new_dentry,
736 unsigned int flags)
1da177e4 737{
9a423bb6 738 char *old_name, *new_name;
1da177e4
LT
739 int err;
740
9a423bb6
MS
741 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
742 return -EINVAL;
743
744 old_name = dentry_name(old_dentry);
745 if (old_name == NULL)
f1adc05e 746 return -ENOMEM;
9a423bb6
MS
747 new_name = dentry_name(new_dentry);
748 if (new_name == NULL) {
749 __putname(old_name);
f1adc05e 750 return -ENOMEM;
1da177e4 751 }
9a423bb6
MS
752 if (!flags)
753 err = rename_file(old_name, new_name);
754 else
755 err = rename2_file(old_name, new_name, flags);
756
757 __putname(old_name);
758 __putname(new_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{
2b0143b5 790 struct inode *inode = d_inode(dentry);
1da177e4
LT
791 struct hostfs_iattr attrs;
792 char *name;
793 int err;
794
1025774c 795 int fd = HOSTFS_I(inode)->fd;
5822b7fa 796
31051c85 797 err = setattr_prepare(dentry, 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 822 attrs.ia_valid |= HOSTFS_ATTR_ATIME;
95582b00 823 attrs.ia_atime = timespec64_to_timespec(attr->ia_atime);
1da177e4 824 }
84b3db04 825 if (attr->ia_valid & ATTR_MTIME) {
1da177e4 826 attrs.ia_valid |= HOSTFS_ATTR_MTIME;
95582b00 827 attrs.ia_mtime = timespec64_to_timespec(attr->ia_mtime);
1da177e4 828 }
84b3db04 829 if (attr->ia_valid & ATTR_CTIME) {
1da177e4 830 attrs.ia_valid |= HOSTFS_ATTR_CTIME;
95582b00 831 attrs.ia_ctime = timespec64_to_timespec(attr->ia_ctime);
1da177e4 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,
2773bf00 870 .rename = hostfs_rename2,
1da177e4
LT
871 .permission = hostfs_permission,
872 .setattr = hostfs_setattr,
1da177e4
LT
873};
874
6b255391 875static const char *hostfs_get_link(struct dentry *dentry,
fceef393
AV
876 struct inode *inode,
877 struct delayed_call *done)
d0352d3e 878{
6b255391
AV
879 char *link;
880 if (!dentry)
881 return ERR_PTR(-ECHILD);
fceef393 882 link = kmalloc(PATH_MAX, GFP_KERNEL);
d0352d3e
AV
883 if (link) {
884 char *path = dentry_name(dentry);
885 int err = -ENOMEM;
886 if (path) {
3b6036d1 887 err = hostfs_do_readlink(path, link, PATH_MAX);
d0352d3e
AV
888 if (err == PATH_MAX)
889 err = -E2BIG;
e9193059 890 __putname(path);
d0352d3e
AV
891 }
892 if (err < 0) {
fceef393 893 kfree(link);
680baacb 894 return ERR_PTR(err);
d0352d3e
AV
895 }
896 } else {
680baacb 897 return ERR_PTR(-ENOMEM);
1da177e4 898 }
d0352d3e 899
fceef393
AV
900 set_delayed_call(done, kfree_link, link);
901 return link;
1da177e4
LT
902}
903
d0352d3e 904static const struct inode_operations hostfs_link_iops = {
6b255391 905 .get_link = hostfs_get_link,
1da177e4
LT
906};
907
908static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
909{
910 struct inode *root_inode;
75e8defb 911 char *host_root_path, *req_root = d;
1da177e4
LT
912 int err;
913
914 sb->s_blocksize = 1024;
915 sb->s_blocksize_bits = 10;
916 sb->s_magic = HOSTFS_SUPER_MAGIC;
917 sb->s_op = &hostfs_sbops;
b26d4cd3 918 sb->s_d_op = &simple_dentry_operations;
752fa51e 919 sb->s_maxbytes = MAX_LFS_FILESIZE;
1da177e4 920
a6eb0be6 921 /* NULL is printed as <NULL> by sprintf: avoid that. */
75e8defb
PBG
922 if (req_root == NULL)
923 req_root = "";
1da177e4
LT
924
925 err = -ENOMEM;
601d2c38
AV
926 sb->s_fs_info = host_root_path =
927 kmalloc(strlen(root_ino) + strlen(req_root) + 2, GFP_KERNEL);
84b3db04 928 if (host_root_path == NULL)
1da177e4
LT
929 goto out;
930
75e8defb 931 sprintf(host_root_path, "%s/%s", root_ino, req_root);
1da177e4 932
52b209f7
AV
933 root_inode = new_inode(sb);
934 if (!root_inode)
601d2c38 935 goto out;
1da177e4 936
4754b825
AV
937 err = read_name(root_inode, host_root_path);
938 if (err)
939 goto out_put;
52b209f7 940
4754b825 941 if (S_ISLNK(root_inode->i_mode)) {
52b209f7 942 char *name = follow_link(host_root_path);
8a545f18 943 if (IS_ERR(name)) {
52b209f7 944 err = PTR_ERR(name);
8a545f18
DC
945 goto out_put;
946 }
947 err = read_name(root_inode, name);
52b209f7 948 kfree(name);
4754b825
AV
949 if (err)
950 goto out_put;
52b209f7 951 }
1da177e4 952
1da177e4 953 err = -ENOMEM;
48fde701 954 sb->s_root = d_make_root(root_inode);
84b3db04 955 if (sb->s_root == NULL)
48fde701 956 goto out;
1da177e4 957
f1adc05e 958 return 0;
1da177e4 959
f1adc05e
JD
960out_put:
961 iput(root_inode);
f1adc05e
JD
962out:
963 return err;
1da177e4
LT
964}
965
3c26ff6e 966static struct dentry *hostfs_read_sb(struct file_system_type *type,
454e2398 967 int flags, const char *dev_name,
3c26ff6e 968 void *data)
1da177e4 969{
3c26ff6e 970 return mount_nodev(type, flags, data, hostfs_fill_sb_common);
1da177e4
LT
971}
972
601d2c38
AV
973static void hostfs_kill_sb(struct super_block *s)
974{
975 kill_anon_super(s);
976 kfree(s->s_fs_info);
977}
978
1da177e4
LT
979static struct file_system_type hostfs_type = {
980 .owner = THIS_MODULE,
981 .name = "hostfs",
3c26ff6e 982 .mount = hostfs_read_sb,
601d2c38 983 .kill_sb = hostfs_kill_sb,
1da177e4
LT
984 .fs_flags = 0,
985};
3e64fe5b 986MODULE_ALIAS_FS("hostfs");
1da177e4
LT
987
988static int __init init_hostfs(void)
989{
f1adc05e 990 return register_filesystem(&hostfs_type);
1da177e4
LT
991}
992
993static void __exit exit_hostfs(void)
994{
995 unregister_filesystem(&hostfs_type);
996}
997
998module_init(init_hostfs)
999module_exit(exit_hostfs)
1000MODULE_LICENSE("GPL");