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