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