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