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