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