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