hostfs: Allow fsync on directories
[deliverable/linux.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
4c6dcafc 298static int hostfs_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 388 .mmap = generic_file_mmap,
4c6dcafc 389 .open = hostfs_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 397 .read = generic_read_dir,
4c6dcafc
RW
398 .open = hostfs_open,
399 .fsync = hostfs_fsync,
1da177e4
LT
400};
401
9e443bc3 402static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
1da177e4
LT
403{
404 struct address_space *mapping = page->mapping;
405 struct inode *inode = mapping->host;
406 char *buffer;
407 unsigned long long base;
408 int count = PAGE_CACHE_SIZE;
409 int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
410 int err;
411
412 if (page->index >= end_index)
413 count = inode->i_size & (PAGE_CACHE_SIZE-1);
414
415 buffer = kmap(page);
416 base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
417
418 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
84b3db04 419 if (err != count) {
1da177e4
LT
420 ClearPageUptodate(page);
421 goto out;
422 }
423
424 if (base > inode->i_size)
425 inode->i_size = base;
426
427 if (PageError(page))
428 ClearPageError(page);
429 err = 0;
430
431 out:
432 kunmap(page);
433
434 unlock_page(page);
435 return err;
436}
437
9e443bc3 438static int hostfs_readpage(struct file *file, struct page *page)
1da177e4
LT
439{
440 char *buffer;
441 long long start;
442 int err = 0;
443
444 start = (long long) page->index << PAGE_CACHE_SHIFT;
445 buffer = kmap(page);
446 err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
447 PAGE_CACHE_SIZE);
84b3db04
JD
448 if (err < 0)
449 goto out;
1da177e4
LT
450
451 memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
452
453 flush_dcache_page(page);
454 SetPageUptodate(page);
455 if (PageError(page)) ClearPageError(page);
456 err = 0;
457 out:
458 kunmap(page);
459 unlock_page(page);
f1adc05e 460 return err;
1da177e4
LT
461}
462
9e443bc3
JH
463static int hostfs_write_begin(struct file *file, struct address_space *mapping,
464 loff_t pos, unsigned len, unsigned flags,
465 struct page **pagep, void **fsdata)
1da177e4 466{
ae361ff4 467 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
1da177e4 468
54566b2c 469 *pagep = grab_cache_page_write_begin(mapping, index, flags);
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
NP
480 void *buffer;
481 unsigned from = pos & (PAGE_CACHE_SIZE - 1);
482 int err;
1da177e4 483
1da177e4 484 buffer = kmap(page);
ae361ff4
NP
485 err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied);
486 kunmap(page);
30f04a4e 487
ae361ff4
NP
488 if (!PageUptodate(page) && err == PAGE_CACHE_SIZE)
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);
498 page_cache_release(page);
1da177e4 499
f1adc05e 500 return err;
1da177e4
LT
501}
502
f5e54d6e 503static const struct address_space_operations hostfs_aops = {
1da177e4
LT
504 .writepage = hostfs_writepage,
505 .readpage = hostfs_readpage,
ffa0aea6 506 .set_page_dirty = __set_page_dirty_nobuffers,
ae361ff4
NP
507 .write_begin = hostfs_write_begin,
508 .write_end = hostfs_write_end,
1da177e4
LT
509};
510
4754b825 511static int read_name(struct inode *ino, char *name)
1da177e4 512{
4754b825
AV
513 dev_t rdev;
514 struct hostfs_stat st;
515 int err = stat_file(name, &st, -1);
516 if (err)
517 return err;
1da177e4 518
5e2df28c 519 /* Reencode maj and min with the kernel encoding.*/
4754b825 520 rdev = MKDEV(st.maj, st.min);
1da177e4 521
4754b825
AV
522 switch (st.mode & S_IFMT) {
523 case S_IFLNK:
d0352d3e 524 ino->i_op = &hostfs_link_iops;
1da177e4 525 break;
4754b825
AV
526 case S_IFDIR:
527 ino->i_op = &hostfs_dir_iops;
528 ino->i_fop = &hostfs_dir_fops;
1da177e4 529 break;
4754b825
AV
530 case S_IFCHR:
531 case S_IFBLK:
532 case S_IFIFO:
533 case S_IFSOCK:
534 init_special_inode(ino, st.mode & S_IFMT, rdev);
535 ino->i_op = &hostfs_iops;
1da177e4 536 break;
4754b825
AV
537
538 default:
539 ino->i_op = &hostfs_iops;
540 ino->i_fop = &hostfs_file_fops;
541 ino->i_mapping->a_ops = &hostfs_aops;
1da177e4 542 }
4754b825
AV
543
544 ino->i_ino = st.ino;
545 ino->i_mode = st.mode;
bfe86848 546 set_nlink(ino, st.nlink);
29f82ae5
EB
547 i_uid_write(ino, st.uid);
548 i_gid_write(ino, st.gid);
4754b825
AV
549 ino->i_atime = st.atime;
550 ino->i_mtime = st.mtime;
551 ino->i_ctime = st.ctime;
552 ino->i_size = st.size;
553 ino->i_blocks = st.blocks;
554 return 0;
1da177e4
LT
555}
556
9e443bc3
JH
557static int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
558 bool excl)
1da177e4
LT
559{
560 struct inode *inode;
561 char *name;
562 int error, fd;
563
0a370e5d
DH
564 inode = hostfs_iget(dir->i_sb);
565 if (IS_ERR(inode)) {
566 error = PTR_ERR(inode);
84b3db04 567 goto out;
0a370e5d 568 }
1da177e4 569
1da177e4 570 error = -ENOMEM;
c5322220 571 name = dentry_name(dentry);
84b3db04 572 if (name == NULL)
1da177e4
LT
573 goto out_put;
574
575 fd = file_create(name,
576 mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
577 mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
578 mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
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
DH
606 inode = hostfs_iget(ino->i_sb);
607 if (IS_ERR(inode)) {
608 err = PTR_ERR(inode);
1da177e4 609 goto out;
0a370e5d 610 }
1da177e4 611
1da177e4 612 err = -ENOMEM;
c5322220 613 name = dentry_name(dentry);
84b3db04 614 if (name == NULL)
1da177e4
LT
615 goto out_put;
616
617 err = read_name(inode, name);
5e2df28c 618
e9193059 619 __putname(name);
84b3db04 620 if (err == -ENOENT) {
1da177e4
LT
621 iput(inode);
622 inode = NULL;
623 }
84b3db04 624 else if (err)
1da177e4
LT
625 goto out_put;
626
627 d_add(dentry, inode);
f1adc05e 628 return NULL;
1da177e4
LT
629
630 out_put:
631 iput(inode);
632 out:
f1adc05e 633 return ERR_PTR(err);
1da177e4
LT
634}
635
9e443bc3
JH
636static int hostfs_link(struct dentry *to, struct inode *ino,
637 struct dentry *from)
1da177e4 638{
f1adc05e
JD
639 char *from_name, *to_name;
640 int err;
1da177e4 641
c5322220 642 if ((from_name = dentry_name(from)) == NULL)
f1adc05e 643 return -ENOMEM;
c5322220 644 to_name = dentry_name(to);
84b3db04 645 if (to_name == NULL) {
e9193059 646 __putname(from_name);
f1adc05e 647 return -ENOMEM;
1da177e4 648 }
f1adc05e 649 err = link_file(to_name, from_name);
e9193059
AV
650 __putname(from_name);
651 __putname(to_name);
f1adc05e 652 return err;
1da177e4
LT
653}
654
9e443bc3 655static int hostfs_unlink(struct inode *ino, struct dentry *dentry)
1da177e4
LT
656{
657 char *file;
658 int err;
659
84b3db04 660 if (append)
f1adc05e 661 return -EPERM;
1da177e4 662
f8d7e187
AV
663 if ((file = dentry_name(dentry)) == NULL)
664 return -ENOMEM;
665
1da177e4 666 err = unlink_file(file);
e9193059 667 __putname(file);
f1adc05e 668 return err;
1da177e4
LT
669}
670
9e443bc3
JH
671static int hostfs_symlink(struct inode *ino, struct dentry *dentry,
672 const char *to)
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 = make_symlink(file, to);
e9193059 680 __putname(file);
f1adc05e 681 return err;
1da177e4
LT
682}
683
9e443bc3 684static int hostfs_mkdir(struct inode *ino, struct dentry *dentry, umode_t mode)
1da177e4
LT
685{
686 char *file;
687 int err;
688
c5322220 689 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 690 return -ENOMEM;
1da177e4 691 err = do_mkdir(file, mode);
e9193059 692 __putname(file);
f1adc05e 693 return err;
1da177e4
LT
694}
695
9e443bc3 696static int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
1da177e4
LT
697{
698 char *file;
699 int err;
700
c5322220 701 if ((file = dentry_name(dentry)) == NULL)
f1adc05e 702 return -ENOMEM;
1da177e4 703 err = do_rmdir(file);
e9193059 704 __putname(file);
f1adc05e 705 return err;
1da177e4
LT
706}
707
1a67aafb 708static int hostfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
1da177e4
LT
709{
710 struct inode *inode;
711 char *name;
0a370e5d 712 int err;
1da177e4 713
0a370e5d
DH
714 inode = hostfs_iget(dir->i_sb);
715 if (IS_ERR(inode)) {
716 err = PTR_ERR(inode);
1da177e4 717 goto out;
0a370e5d 718 }
1da177e4 719
1da177e4 720 err = -ENOMEM;
c5322220 721 name = dentry_name(dentry);
84b3db04 722 if (name == NULL)
1da177e4
LT
723 goto out_put;
724
725 init_special_inode(inode, mode, dev);
88f6cd0c 726 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
e9193059 727 if (!err)
1da177e4
LT
728 goto out_free;
729
730 err = read_name(inode, name);
e9193059 731 __putname(name);
5e2df28c
AV
732 if (err)
733 goto out_put;
84b3db04 734 if (err)
1da177e4
LT
735 goto out_put;
736
737 d_instantiate(dentry, inode);
f1adc05e 738 return 0;
1da177e4
LT
739
740 out_free:
e9193059 741 __putname(name);
1da177e4
LT
742 out_put:
743 iput(inode);
744 out:
f1adc05e 745 return err;
1da177e4
LT
746}
747
9a423bb6
MS
748static int hostfs_rename2(struct inode *old_dir, struct dentry *old_dentry,
749 struct inode *new_dir, struct dentry *new_dentry,
750 unsigned int flags)
1da177e4 751{
9a423bb6 752 char *old_name, *new_name;
1da177e4
LT
753 int err;
754
9a423bb6
MS
755 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
756 return -EINVAL;
757
758 old_name = dentry_name(old_dentry);
759 if (old_name == NULL)
f1adc05e 760 return -ENOMEM;
9a423bb6
MS
761 new_name = dentry_name(new_dentry);
762 if (new_name == NULL) {
763 __putname(old_name);
f1adc05e 764 return -ENOMEM;
1da177e4 765 }
9a423bb6
MS
766 if (!flags)
767 err = rename_file(old_name, new_name);
768 else
769 err = rename2_file(old_name, new_name, flags);
770
771 __putname(old_name);
772 __putname(new_name);
f1adc05e 773 return err;
1da177e4
LT
774}
775
9e443bc3 776static int hostfs_permission(struct inode *ino, int desired)
1da177e4
LT
777{
778 char *name;
779 int r = 0, w = 0, x = 0, err;
780
10556cb2 781 if (desired & MAY_NOT_BLOCK)
b74c79e9
NP
782 return -ECHILD;
783
1da177e4
LT
784 if (desired & MAY_READ) r = 1;
785 if (desired & MAY_WRITE) w = 1;
786 if (desired & MAY_EXEC) x = 1;
c5322220 787 name = inode_name(ino);
f1adc05e
JD
788 if (name == NULL)
789 return -ENOMEM;
1da177e4
LT
790
791 if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
84b3db04 792 S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
1da177e4
LT
793 err = 0;
794 else
795 err = access_file(name, r, w, x);
e9193059 796 __putname(name);
84b3db04 797 if (!err)
2830ba7f 798 err = generic_permission(ino, desired);
1da177e4
LT
799 return err;
800}
801
9e443bc3 802static int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
1da177e4 803{
1025774c 804 struct inode *inode = dentry->d_inode;
1da177e4
LT
805 struct hostfs_iattr attrs;
806 char *name;
807 int err;
808
1025774c 809 int fd = HOSTFS_I(inode)->fd;
5822b7fa 810
1025774c 811 err = inode_change_ok(inode, 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
LT
836 attrs.ia_valid |= HOSTFS_ATTR_ATIME;
837 attrs.ia_atime = attr->ia_atime;
838 }
84b3db04 839 if (attr->ia_valid & ATTR_MTIME) {
1da177e4
LT
840 attrs.ia_valid |= HOSTFS_ATTR_MTIME;
841 attrs.ia_mtime = attr->ia_mtime;
842 }
84b3db04 843 if (attr->ia_valid & ATTR_CTIME) {
1da177e4
LT
844 attrs.ia_valid |= HOSTFS_ATTR_CTIME;
845 attrs.ia_ctime = attr->ia_ctime;
846 }
84b3db04 847 if (attr->ia_valid & ATTR_ATIME_SET) {
1da177e4
LT
848 attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
849 }
84b3db04 850 if (attr->ia_valid & ATTR_MTIME_SET) {
1da177e4
LT
851 attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
852 }
c5322220 853 name = dentry_name(dentry);
84b3db04 854 if (name == NULL)
f1adc05e 855 return -ENOMEM;
5822b7fa 856 err = set_attr(name, &attrs, fd);
e9193059 857 __putname(name);
84b3db04 858 if (err)
f1adc05e 859 return err;
1da177e4 860
1025774c 861 if ((attr->ia_valid & ATTR_SIZE) &&
bc077320 862 attr->ia_size != i_size_read(inode))
3be2be0a 863 truncate_setsize(inode, attr->ia_size);
1025774c
CH
864
865 setattr_copy(inode, attr);
866 mark_inode_dirty(inode);
867 return 0;
1da177e4
LT
868}
869
92e1d5be 870static const struct inode_operations hostfs_iops = {
1da177e4
LT
871 .permission = hostfs_permission,
872 .setattr = hostfs_setattr,
1da177e4
LT
873};
874
92e1d5be 875static const struct inode_operations hostfs_dir_iops = {
1da177e4
LT
876 .create = hostfs_create,
877 .lookup = hostfs_lookup,
878 .link = hostfs_link,
879 .unlink = hostfs_unlink,
880 .symlink = hostfs_symlink,
881 .mkdir = hostfs_mkdir,
882 .rmdir = hostfs_rmdir,
883 .mknod = hostfs_mknod,
9a423bb6 884 .rename2 = hostfs_rename2,
1da177e4
LT
885 .permission = hostfs_permission,
886 .setattr = hostfs_setattr,
1da177e4
LT
887};
888
d0352d3e
AV
889static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
890{
891 char *link = __getname();
892 if (link) {
893 char *path = dentry_name(dentry);
894 int err = -ENOMEM;
895 if (path) {
3b6036d1 896 err = hostfs_do_readlink(path, link, PATH_MAX);
d0352d3e
AV
897 if (err == PATH_MAX)
898 err = -E2BIG;
e9193059 899 __putname(path);
d0352d3e
AV
900 }
901 if (err < 0) {
902 __putname(link);
903 link = ERR_PTR(err);
904 }
905 } else {
906 link = ERR_PTR(-ENOMEM);
1da177e4 907 }
d0352d3e
AV
908
909 nd_set_link(nd, link);
910 return NULL;
911}
912
913static void hostfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
914{
915 char *s = nd_get_link(nd);
916 if (!IS_ERR(s))
917 __putname(s);
1da177e4
LT
918}
919
d0352d3e
AV
920static const struct inode_operations hostfs_link_iops = {
921 .readlink = generic_readlink,
922 .follow_link = hostfs_follow_link,
923 .put_link = hostfs_put_link,
1da177e4
LT
924};
925
926static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
927{
928 struct inode *root_inode;
75e8defb 929 char *host_root_path, *req_root = d;
1da177e4
LT
930 int err;
931
932 sb->s_blocksize = 1024;
933 sb->s_blocksize_bits = 10;
934 sb->s_magic = HOSTFS_SUPER_MAGIC;
935 sb->s_op = &hostfs_sbops;
b26d4cd3 936 sb->s_d_op = &simple_dentry_operations;
752fa51e 937 sb->s_maxbytes = MAX_LFS_FILESIZE;
1da177e4 938
a6eb0be6 939 /* NULL is printed as <NULL> by sprintf: avoid that. */
75e8defb
PBG
940 if (req_root == NULL)
941 req_root = "";
1da177e4
LT
942
943 err = -ENOMEM;
601d2c38
AV
944 sb->s_fs_info = host_root_path =
945 kmalloc(strlen(root_ino) + strlen(req_root) + 2, GFP_KERNEL);
84b3db04 946 if (host_root_path == NULL)
1da177e4
LT
947 goto out;
948
75e8defb 949 sprintf(host_root_path, "%s/%s", root_ino, req_root);
1da177e4 950
52b209f7
AV
951 root_inode = new_inode(sb);
952 if (!root_inode)
601d2c38 953 goto out;
1da177e4 954
4754b825
AV
955 err = read_name(root_inode, host_root_path);
956 if (err)
957 goto out_put;
52b209f7 958
4754b825 959 if (S_ISLNK(root_inode->i_mode)) {
52b209f7
AV
960 char *name = follow_link(host_root_path);
961 if (IS_ERR(name))
962 err = PTR_ERR(name);
963 else
964 err = read_name(root_inode, name);
965 kfree(name);
4754b825
AV
966 if (err)
967 goto out_put;
52b209f7 968 }
1da177e4 969
1da177e4 970 err = -ENOMEM;
48fde701 971 sb->s_root = d_make_root(root_inode);
84b3db04 972 if (sb->s_root == NULL)
48fde701 973 goto out;
1da177e4 974
f1adc05e 975 return 0;
1da177e4 976
f1adc05e
JD
977out_put:
978 iput(root_inode);
f1adc05e
JD
979out:
980 return err;
1da177e4
LT
981}
982
3c26ff6e 983static struct dentry *hostfs_read_sb(struct file_system_type *type,
454e2398 984 int flags, const char *dev_name,
3c26ff6e 985 void *data)
1da177e4 986{
3c26ff6e 987 return mount_nodev(type, flags, data, hostfs_fill_sb_common);
1da177e4
LT
988}
989
601d2c38
AV
990static void hostfs_kill_sb(struct super_block *s)
991{
992 kill_anon_super(s);
993 kfree(s->s_fs_info);
994}
995
1da177e4
LT
996static struct file_system_type hostfs_type = {
997 .owner = THIS_MODULE,
998 .name = "hostfs",
3c26ff6e 999 .mount = hostfs_read_sb,
601d2c38 1000 .kill_sb = hostfs_kill_sb,
1da177e4
LT
1001 .fs_flags = 0,
1002};
3e64fe5b 1003MODULE_ALIAS_FS("hostfs");
1da177e4
LT
1004
1005static int __init init_hostfs(void)
1006{
f1adc05e 1007 return register_filesystem(&hostfs_type);
1da177e4
LT
1008}
1009
1010static void __exit exit_hostfs(void)
1011{
1012 unregister_filesystem(&hostfs_type);
1013}
1014
1015module_init(init_hostfs)
1016module_exit(exit_hostfs)
1017MODULE_LICENSE("GPL");
This page took 0.809866 seconds and 5 git commands to generate.