Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.22 1039 lines 22 kB view raw
1/* 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 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> 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> 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" 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{ 34 return list_entry(inode, struct hostfs_inode_info, vfs_inode); 35} 36 37#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode) 38 39int hostfs_d_delete(struct dentry *dentry) 40{ 41 return 1; 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 */ 49static char *root_ino = ""; 50static int append = 0; 51 52#define HOSTFS_SUPER_MAGIC 0x00c0ffee 53 54static const struct inode_operations hostfs_iops; 55static const struct inode_operations hostfs_dir_iops; 56static const struct address_space_operations hostfs_link_aops; 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 } 82 return 0; 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); 113 if(name == NULL) 114 return NULL; 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)); 126 return name; 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); 134 return dentry_name(dentry, extra); 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, 151 &ino->i_ctime, &i_blksize, &i_blocks, -1); 152 if(err) 153 return err; 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; 159 ino->i_blocks = i_blocks; 160 return 0; 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 == '/') 185 return name; 186 187 end = strrchr(link, '/'); 188 if(end == NULL) 189 return name; 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); 203 return resolved; 204 205 out_free: 206 kfree(name); 207 out: 208 return ERR_PTR(n); 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: 238 return err; 239} 240 241int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf) 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 254 err = do_statfs(HOSTFS_I(dentry->d_sb->s_root->d_inode)->host_filename, 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); 258 if(err) 259 return err; 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; 266 return 0; 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) 275 return NULL; 276 277 *hi = ((struct hostfs_inode_info) { .host_filename = NULL, 278 .fd = -1, 279 .mode = 0 }); 280 inode_init_once(&hi->vfs_inode); 281 return &hi->vfs_inode; 282} 283 284static void hostfs_delete_inode(struct inode *inode) 285{ 286 truncate_inode_pages(&inode->i_data, 0); 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{ 296 kfree(HOSTFS_I(inode)->host_filename); 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 313static const struct super_operations hostfs_sbops = { 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 329 name = dentry_name(file->f_path.dentry, 0); 330 if(name == NULL) 331 return -ENOMEM; 332 dir = open_dir(name, &error); 333 kfree(name); 334 if(dir == NULL) 335 return -error; 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); 344 return 0; 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) 354 return 0; 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 372 name = dentry_name(file->f_path.dentry, 0); 373 if(name == NULL) 374 return -ENOMEM; 375 376 fd = open_file(name, r, w, append); 377 kfree(name); 378 if(fd < 0) 379 return fd; 380 FILE_HOSTFS_I(file)->fd = fd; 381 382 return 0; 383} 384 385int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) 386{ 387 return fsync_file(HOSTFS_I(dentry->d_inode)->fd, datasync); 388} 389 390static const struct file_operations hostfs_file_fops = { 391 .llseek = generic_file_llseek, 392 .read = do_sync_read, 393 .sendfile = generic_file_sendfile, 394 .aio_read = generic_file_aio_read, 395 .aio_write = generic_file_aio_write, 396 .write = do_sync_write, 397 .mmap = generic_file_mmap, 398 .open = hostfs_file_open, 399 .release = NULL, 400 .fsync = hostfs_fsync, 401}; 402 403static const struct file_operations hostfs_dir_fops = { 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); 466 return err; 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); 493 return err; 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 505 start = (((long long) page->index) << PAGE_CACHE_SHIFT) + from; 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; 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 515 if(!err && (start > inode->i_size)) 516 inode->i_size = start; 517 518 kunmap(page); 519 return err; 520} 521 522static const struct address_space_operations hostfs_aops = { 523 .writepage = hostfs_writepage, 524 .readpage = hostfs_readpage, 525 .set_page_dirty = __set_page_dirty_nobuffers, 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: 577 return err; 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); 615 return 0; 616 617 out_put: 618 iput(inode); 619 out: 620 return error; 621} 622 623struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, 624 struct nameidata *nd) 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; 655 return NULL; 656 657 out_put: 658 iput(inode); 659 out: 660 return ERR_PTR(err); 661} 662 663static char *inode_dentry_name(struct inode *ino, struct dentry *dentry) 664{ 665 char *file; 666 int len; 667 668 file = inode_name(ino, dentry->d_name.len + 1); 669 if(file == NULL) 670 return NULL; 671 strcat(file, "/"); 672 len = strlen(file); 673 strncat(file, dentry->d_name.name, dentry->d_name.len); 674 file[len + dentry->d_name.len] = '\0'; 675 return file; 676} 677 678int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from) 679{ 680 char *from_name, *to_name; 681 int err; 682 683 if((from_name = inode_dentry_name(ino, from)) == NULL) 684 return -ENOMEM; 685 to_name = dentry_name(to, 0); 686 if(to_name == NULL){ 687 kfree(from_name); 688 return -ENOMEM; 689 } 690 err = link_file(to_name, from_name); 691 kfree(from_name); 692 kfree(to_name); 693 return err; 694} 695 696int hostfs_unlink(struct inode *ino, struct dentry *dentry) 697{ 698 char *file; 699 int err; 700 701 if((file = inode_dentry_name(ino, dentry)) == NULL) 702 return -ENOMEM; 703 if(append) 704 return -EPERM; 705 706 err = unlink_file(file); 707 kfree(file); 708 return err; 709} 710 711int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to) 712{ 713 char *file; 714 int err; 715 716 if((file = inode_dentry_name(ino, dentry)) == NULL) 717 return -ENOMEM; 718 err = make_symlink(file, to); 719 kfree(file); 720 return err; 721} 722 723int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode) 724{ 725 char *file; 726 int err; 727 728 if((file = inode_dentry_name(ino, dentry)) == NULL) 729 return -ENOMEM; 730 err = do_mkdir(file, mode); 731 kfree(file); 732 return err; 733} 734 735int hostfs_rmdir(struct inode *ino, struct dentry *dentry) 736{ 737 char *file; 738 int err; 739 740 if((file = inode_dentry_name(ino, dentry)) == NULL) 741 return -ENOMEM; 742 err = do_rmdir(file); 743 kfree(file); 744 return err; 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); 767 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev)); 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); 777 return 0; 778 779 out_free: 780 kfree(name); 781 out_put: 782 iput(inode); 783 out: 784 return err; 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) 794 return -ENOMEM; 795 if((to_name = inode_dentry_name(to_ino, to)) == NULL){ 796 kfree(from_name); 797 return -ENOMEM; 798 } 799 err = rename_file(from_name, to_name); 800 kfree(from_name); 801 kfree(to_name); 802 return err; 803} 804 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); 814 if (name == NULL) 815 return -ENOMEM; 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 834 int fd = HOSTFS_I(dentry->d_inode)->fd; 835 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){ 849 attrs.ia_valid |= HOSTFS_ATTR_UID; 850 attrs.ia_uid = attr->ia_uid; 851 } 852 if(attr->ia_valid & ATTR_GID){ 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); 879 if(name == NULL) 880 return -ENOMEM; 881 err = set_attr(name, &attrs, fd); 882 kfree(name); 883 if(err) 884 return err; 885 886 return inode_setattr(dentry->d_inode, attr); 887} 888 889int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 890 struct kstat *stat) 891{ 892 generic_fillattr(dentry->d_inode, stat); 893 return 0; 894} 895 896static const struct inode_operations hostfs_iops = { 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, 905 .permission = hostfs_permission, 906 .setattr = hostfs_setattr, 907 .getattr = hostfs_getattr, 908}; 909 910static const struct inode_operations hostfs_dir_iops = { 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, 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; 928 int err; 929 930 buffer = kmap(page); 931 name = inode_name(page->mapping->host, 0); 932 if(name == NULL) 933 return -ENOMEM; 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); 946 return err; 947} 948 949static const struct address_space_operations hostfs_link_aops = { 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; 956 char *host_root_path, *req_root = d; 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 964 /* NULL is printed as <NULL> by sprintf: avoid that. */ 965 if (req_root == NULL) 966 req_root = ""; 967 968 err = -ENOMEM; 969 host_root_path = kmalloc(strlen(root_ino) + 1 970 + strlen(req_root) + 1, GFP_KERNEL); 971 if(host_root_path == NULL) 972 goto out; 973 974 sprintf(host_root_path, "%s/%s", root_ino, req_root); 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 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; 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); 995 if(err){ 996 /* No iput in this case because the dput does that for us */ 997 dput(sb->s_root); 998 sb->s_root = NULL; 999 goto out; 1000 } 1001 1002 return 0; 1003 1004out_put: 1005 iput(root_inode); 1006out_free: 1007 kfree(host_root_path); 1008out: 1009 return err; 1010} 1011 1012static int hostfs_read_sb(struct file_system_type *type, 1013 int flags, const char *dev_name, 1014 void *data, struct vfsmount *mnt) 1015{ 1016 return get_sb_nodev(type, flags, data, hostfs_fill_sb_common, mnt); 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{ 1029 return register_filesystem(&hostfs_type); 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");