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