linux/fs/libfs.c
<<
>>
Prefs
   1/*
   2 *      fs/libfs.c
   3 *      Library for filesystems writers.
   4 */
   5
   6#include <linux/module.h>
   7#include <linux/pagemap.h>
   8#include <linux/mount.h>
   9#include <linux/vfs.h>
  10#include <linux/mutex.h>
  11#include <linux/exportfs.h>
  12
  13#include <asm/uaccess.h>
  14
  15int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
  16                   struct kstat *stat)
  17{
  18        struct inode *inode = dentry->d_inode;
  19        generic_fillattr(inode, stat);
  20        stat->blocks = inode->i_mapping->nrpages << (PAGE_CACHE_SHIFT - 9);
  21        return 0;
  22}
  23
  24int simple_statfs(struct dentry *dentry, struct kstatfs *buf)
  25{
  26        buf->f_type = dentry->d_sb->s_magic;
  27        buf->f_bsize = PAGE_CACHE_SIZE;
  28        buf->f_namelen = NAME_MAX;
  29        return 0;
  30}
  31
  32/*
  33 * Retaining negative dentries for an in-memory filesystem just wastes
  34 * memory and lookup time: arrange for them to be deleted immediately.
  35 */
  36static int simple_delete_dentry(struct dentry *dentry)
  37{
  38        return 1;
  39}
  40
  41/*
  42 * Lookup the data. This is trivial - if the dentry didn't already
  43 * exist, we know it is negative.  Set d_op to delete negative dentries.
  44 */
  45struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
  46{
  47        static struct dentry_operations simple_dentry_operations = {
  48                .d_delete = simple_delete_dentry,
  49        };
  50
  51        if (dentry->d_name.len > NAME_MAX)
  52                return ERR_PTR(-ENAMETOOLONG);
  53        dentry->d_op = &simple_dentry_operations;
  54        d_add(dentry, NULL);
  55        return NULL;
  56}
  57
  58int simple_sync_file(struct file * file, struct dentry *dentry, int datasync)
  59{
  60        return 0;
  61}
  62 
  63int dcache_dir_open(struct inode *inode, struct file *file)
  64{
  65        static struct qstr cursor_name = {.len = 1, .name = "."};
  66
  67        file->private_data = d_alloc(file->f_path.dentry, &cursor_name);
  68
  69        return file->private_data ? 0 : -ENOMEM;
  70}
  71
  72int dcache_dir_close(struct inode *inode, struct file *file)
  73{
  74        dput(file->private_data);
  75        return 0;
  76}
  77
  78loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
  79{
  80        mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
  81        switch (origin) {
  82                case 1:
  83                        offset += file->f_pos;
  84                case 0:
  85                        if (offset >= 0)
  86                                break;
  87                default:
  88                        mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
  89                        return -EINVAL;
  90        }
  91        if (offset != file->f_pos) {
  92                file->f_pos = offset;
  93                if (file->f_pos >= 2) {
  94                        struct list_head *p;
  95                        struct dentry *cursor = file->private_data;
  96                        loff_t n = file->f_pos - 2;
  97
  98                        spin_lock(&dcache_lock);
  99                        list_del(&cursor->d_u.d_child);
 100                        p = file->f_path.dentry->d_subdirs.next;
 101                        while (n && p != &file->f_path.dentry->d_subdirs) {
 102                                struct dentry *next;
 103                                next = list_entry(p, struct dentry, d_u.d_child);
 104                                if (!d_unhashed(next) && next->d_inode)
 105                                        n--;
 106                                p = p->next;
 107                        }
 108                        list_add_tail(&cursor->d_u.d_child, p);
 109                        spin_unlock(&dcache_lock);
 110                }
 111        }
 112        mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
 113        return offset;
 114}
 115
 116/* Relationship between i_mode and the DT_xxx types */
 117static inline unsigned char dt_type(struct inode *inode)
 118{
 119        return (inode->i_mode >> 12) & 15;
 120}
 121
 122/*
 123 * Directory is locked and all positive dentries in it are safe, since
 124 * for ramfs-type trees they can't go away without unlink() or rmdir(),
 125 * both impossible due to the lock on directory.
 126 */
 127
 128int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
 129{
 130        struct dentry *dentry = filp->f_path.dentry;
 131        struct dentry *cursor = filp->private_data;
 132        struct list_head *p, *q = &cursor->d_u.d_child;
 133        ino_t ino;
 134        int i = filp->f_pos;
 135
 136        switch (i) {
 137                case 0:
 138                        ino = dentry->d_inode->i_ino;
 139                        if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
 140                                break;
 141                        filp->f_pos++;
 142                        i++;
 143                        /* fallthrough */
 144                case 1:
 145                        ino = parent_ino(dentry);
 146                        if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
 147                                break;
 148                        filp->f_pos++;
 149                        i++;
 150                        /* fallthrough */
 151                default:
 152                        spin_lock(&dcache_lock);
 153                        if (filp->f_pos == 2)
 154                                list_move(q, &dentry->d_subdirs);
 155
 156                        for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
 157                                struct dentry *next;
 158                                next = list_entry(p, struct dentry, d_u.d_child);
 159                                if (d_unhashed(next) || !next->d_inode)
 160                                        continue;
 161
 162                                spin_unlock(&dcache_lock);
 163                                if (filldir(dirent, next->d_name.name, 
 164                                            next->d_name.len, filp->f_pos, 
 165                                            next->d_inode->i_ino, 
 166                                            dt_type(next->d_inode)) < 0)
 167                                        return 0;
 168                                spin_lock(&dcache_lock);
 169                                /* next is still alive */
 170                                list_move(q, p);
 171                                p = q;
 172                                filp->f_pos++;
 173                        }
 174                        spin_unlock(&dcache_lock);
 175        }
 176        return 0;
 177}
 178
 179ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
 180{
 181        return -EISDIR;
 182}
 183
 184const struct file_operations simple_dir_operations = {
 185        .open           = dcache_dir_open,
 186        .release        = dcache_dir_close,
 187        .llseek         = dcache_dir_lseek,
 188        .read           = generic_read_dir,
 189        .readdir        = dcache_readdir,
 190        .fsync          = simple_sync_file,
 191};
 192
 193const struct inode_operations simple_dir_inode_operations = {
 194        .lookup         = simple_lookup,
 195};
 196
 197static const struct super_operations simple_super_operations = {
 198        .statfs         = simple_statfs,
 199};
 200
 201/*
 202 * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that
 203 * will never be mountable)
 204 */
 205int get_sb_pseudo(struct file_system_type *fs_type, char *name,
 206        const struct super_operations *ops, unsigned long magic,
 207        struct vfsmount *mnt)
 208{
 209        struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
 210        struct dentry *dentry;
 211        struct inode *root;
 212        struct qstr d_name = {.name = name, .len = strlen(name)};
 213
 214        if (IS_ERR(s))
 215                return PTR_ERR(s);
 216
 217        s->s_flags = MS_NOUSER;
 218        s->s_maxbytes = ~0ULL;
 219        s->s_blocksize = PAGE_SIZE;
 220        s->s_blocksize_bits = PAGE_SHIFT;
 221        s->s_magic = magic;
 222        s->s_op = ops ? ops : &simple_super_operations;
 223        s->s_time_gran = 1;
 224        root = new_inode(s);
 225        if (!root)
 226                goto Enomem;
 227        /*
 228         * since this is the first inode, make it number 1. New inodes created
 229         * after this must take care not to collide with it (by passing
 230         * max_reserved of 1 to iunique).
 231         */
 232        root->i_ino = 1;
 233        root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
 234        root->i_uid = root->i_gid = 0;
 235        root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
 236        dentry = d_alloc(NULL, &d_name);
 237        if (!dentry) {
 238                iput(root);
 239                goto Enomem;
 240        }
 241        dentry->d_sb = s;
 242        dentry->d_parent = dentry;
 243        d_instantiate(dentry, root);
 244        s->s_root = dentry;
 245        s->s_flags |= MS_ACTIVE;
 246        return simple_set_mnt(mnt, s);
 247
 248Enomem:
 249        up_write(&s->s_umount);
 250        deactivate_super(s);
 251        return -ENOMEM;
 252}
 253
 254int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
 255{
 256        struct inode *inode = old_dentry->d_inode;
 257
 258        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 259        inc_nlink(inode);
 260        atomic_inc(&inode->i_count);
 261        dget(dentry);
 262        d_instantiate(dentry, inode);
 263        return 0;
 264}
 265
 266static inline int simple_positive(struct dentry *dentry)
 267{
 268        return dentry->d_inode && !d_unhashed(dentry);
 269}
 270
 271int simple_empty(struct dentry *dentry)
 272{
 273        struct dentry *child;
 274        int ret = 0;
 275
 276        spin_lock(&dcache_lock);
 277        list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
 278                if (simple_positive(child))
 279                        goto out;
 280        ret = 1;
 281out:
 282        spin_unlock(&dcache_lock);
 283        return ret;
 284}
 285
 286int simple_unlink(struct inode *dir, struct dentry *dentry)
 287{
 288        struct inode *inode = dentry->d_inode;
 289
 290        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 291        drop_nlink(inode);
 292        dput(dentry);
 293        return 0;
 294}
 295
 296int simple_rmdir(struct inode *dir, struct dentry *dentry)
 297{
 298        if (!simple_empty(dentry))
 299                return -ENOTEMPTY;
 300
 301        drop_nlink(dentry->d_inode);
 302        simple_unlink(dir, dentry);
 303        drop_nlink(dir);
 304        return 0;
 305}
 306
 307int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
 308                struct inode *new_dir, struct dentry *new_dentry)
 309{
 310        struct inode *inode = old_dentry->d_inode;
 311        int they_are_dirs = S_ISDIR(old_dentry->d_inode->i_mode);
 312
 313        if (!simple_empty(new_dentry))
 314                return -ENOTEMPTY;
 315
 316        if (new_dentry->d_inode) {
 317                simple_unlink(new_dir, new_dentry);
 318                if (they_are_dirs)
 319                        drop_nlink(old_dir);
 320        } else if (they_are_dirs) {
 321                drop_nlink(old_dir);
 322                inc_nlink(new_dir);
 323        }
 324
 325        old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime =
 326                new_dir->i_mtime = inode->i_ctime = CURRENT_TIME;
 327
 328        return 0;
 329}
 330
 331int simple_readpage(struct file *file, struct page *page)
 332{
 333        clear_highpage(page);
 334        flush_dcache_page(page);
 335        SetPageUptodate(page);
 336        unlock_page(page);
 337        return 0;
 338}
 339
 340int simple_prepare_write(struct file *file, struct page *page,
 341                        unsigned from, unsigned to)
 342{
 343        if (!PageUptodate(page)) {
 344                if (to - from != PAGE_CACHE_SIZE)
 345                        zero_user_segments(page,
 346                                0, from,
 347                                to, PAGE_CACHE_SIZE);
 348        }
 349        return 0;
 350}
 351
 352int simple_write_begin(struct file *file, struct address_space *mapping,
 353                        loff_t pos, unsigned len, unsigned flags,
 354                        struct page **pagep, void **fsdata)
 355{
 356        struct page *page;
 357        pgoff_t index;
 358        unsigned from;
 359
 360        index = pos >> PAGE_CACHE_SHIFT;
 361        from = pos & (PAGE_CACHE_SIZE - 1);
 362
 363        page = grab_cache_page_write_begin(mapping, index, flags);
 364        if (!page)
 365                return -ENOMEM;
 366
 367        *pagep = page;
 368
 369        return simple_prepare_write(file, page, from, from+len);
 370}
 371
 372static int simple_commit_write(struct file *file, struct page *page,
 373                               unsigned from, unsigned to)
 374{
 375        struct inode *inode = page->mapping->host;
 376        loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
 377
 378        if (!PageUptodate(page))
 379                SetPageUptodate(page);
 380        /*
 381         * No need to use i_size_read() here, the i_size
 382         * cannot change under us because we hold the i_mutex.
 383         */
 384        if (pos > inode->i_size)
 385                i_size_write(inode, pos);
 386        set_page_dirty(page);
 387        return 0;
 388}
 389
 390int simple_write_end(struct file *file, struct address_space *mapping,
 391                        loff_t pos, unsigned len, unsigned copied,
 392                        struct page *page, void *fsdata)
 393{
 394        unsigned from = pos & (PAGE_CACHE_SIZE - 1);
 395
 396        /* zero the stale part of the page if we did a short copy */
 397        if (copied < len) {
 398                void *kaddr = kmap_atomic(page, KM_USER0);
 399                memset(kaddr + from + copied, 0, len - copied);
 400                flush_dcache_page(page);
 401                kunmap_atomic(kaddr, KM_USER0);
 402        }
 403
 404        simple_commit_write(file, page, from, from+copied);
 405
 406        unlock_page(page);
 407        page_cache_release(page);
 408
 409        return copied;
 410}
 411
 412/*
 413 * the inodes created here are not hashed. If you use iunique to generate
 414 * unique inode values later for this filesystem, then you must take care
 415 * to pass it an appropriate max_reserved value to avoid collisions.
 416 */
 417int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files)
 418{
 419        struct inode *inode;
 420        struct dentry *root;
 421        struct dentry *dentry;
 422        int i;
 423
 424        s->s_blocksize = PAGE_CACHE_SIZE;
 425        s->s_blocksize_bits = PAGE_CACHE_SHIFT;
 426        s->s_magic = magic;
 427        s->s_op = &simple_super_operations;
 428        s->s_time_gran = 1;
 429
 430        inode = new_inode(s);
 431        if (!inode)
 432                return -ENOMEM;
 433        /*
 434         * because the root inode is 1, the files array must not contain an
 435         * entry at index 1
 436         */
 437        inode->i_ino = 1;
 438        inode->i_mode = S_IFDIR | 0755;
 439        inode->i_uid = inode->i_gid = 0;
 440        inode->i_blocks = 0;
 441        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 442        inode->i_op = &simple_dir_inode_operations;
 443        inode->i_fop = &simple_dir_operations;
 444        inode->i_nlink = 2;
 445        root = d_alloc_root(inode);
 446        if (!root) {
 447                iput(inode);
 448                return -ENOMEM;
 449        }
 450        for (i = 0; !files->name || files->name[0]; i++, files++) {
 451                if (!files->name)
 452                        continue;
 453
 454                /* warn if it tries to conflict with the root inode */
 455                if (unlikely(i == 1))
 456                        printk(KERN_WARNING "%s: %s passed in a files array"
 457                                "with an index of 1!\n", __func__,
 458                                s->s_type->name);
 459
 460                dentry = d_alloc_name(root, files->name);
 461                if (!dentry)
 462                        goto out;
 463                inode = new_inode(s);
 464                if (!inode)
 465                        goto out;
 466                inode->i_mode = S_IFREG | files->mode;
 467                inode->i_uid = inode->i_gid = 0;
 468                inode->i_blocks = 0;
 469                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 470                inode->i_fop = files->ops;
 471                inode->i_ino = i;
 472                d_add(dentry, inode);
 473        }
 474        s->s_root = root;
 475        return 0;
 476out:
 477        d_genocide(root);
 478        dput(root);
 479        return -ENOMEM;
 480}
 481
 482static DEFINE_SPINLOCK(pin_fs_lock);
 483
 484int simple_pin_fs(struct file_system_type *type, struct vfsmount **mount, int *count)
 485{
 486        struct vfsmount *mnt = NULL;
 487        spin_lock(&pin_fs_lock);
 488        if (unlikely(!*mount)) {
 489                spin_unlock(&pin_fs_lock);
 490                mnt = vfs_kern_mount(type, 0, type->name, NULL);
 491                if (IS_ERR(mnt))
 492                        return PTR_ERR(mnt);
 493                spin_lock(&pin_fs_lock);
 494                if (!*mount)
 495                        *mount = mnt;
 496        }
 497        mntget(*mount);
 498        ++*count;
 499        spin_unlock(&pin_fs_lock);
 500        mntput(mnt);
 501        return 0;
 502}
 503
 504void simple_release_fs(struct vfsmount **mount, int *count)
 505{
 506        struct vfsmount *mnt;
 507        spin_lock(&pin_fs_lock);
 508        mnt = *mount;
 509        if (!--*count)
 510                *mount = NULL;
 511        spin_unlock(&pin_fs_lock);
 512        mntput(mnt);
 513}
 514
 515/**
 516 * simple_read_from_buffer - copy data from the buffer to user space
 517 * @to: the user space buffer to read to
 518 * @count: the maximum number of bytes to read
 519 * @ppos: the current position in the buffer
 520 * @from: the buffer to read from
 521 * @available: the size of the buffer
 522 *
 523 * The simple_read_from_buffer() function reads up to @count bytes from the
 524 * buffer @from at offset @ppos into the user space address starting at @to.
 525 *
 526 * On success, the number of bytes read is returned and the offset @ppos is
 527 * advanced by this number, or negative value is returned on error.
 528 **/
 529ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos,
 530                                const void *from, size_t available)
 531{
 532        loff_t pos = *ppos;
 533        if (pos < 0)
 534                return -EINVAL;
 535        if (pos >= available)
 536                return 0;
 537        if (count > available - pos)
 538                count = available - pos;
 539        if (copy_to_user(to, from + pos, count))
 540                return -EFAULT;
 541        *ppos = pos + count;
 542        return count;
 543}
 544
 545/**
 546 * memory_read_from_buffer - copy data from the buffer
 547 * @to: the kernel space buffer to read to
 548 * @count: the maximum number of bytes to read
 549 * @ppos: the current position in the buffer
 550 * @from: the buffer to read from
 551 * @available: the size of the buffer
 552 *
 553 * The memory_read_from_buffer() function reads up to @count bytes from the
 554 * buffer @from at offset @ppos into the kernel space address starting at @to.
 555 *
 556 * On success, the number of bytes read is returned and the offset @ppos is
 557 * advanced by this number, or negative value is returned on error.
 558 **/
 559ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
 560                                const void *from, size_t available)
 561{
 562        loff_t pos = *ppos;
 563
 564        if (pos < 0)
 565                return -EINVAL;
 566        if (pos >= available)
 567                return 0;
 568        if (count > available - pos)
 569                count = available - pos;
 570        memcpy(to, from + pos, count);
 571        *ppos = pos + count;
 572
 573        return count;
 574}
 575
 576/*
 577 * Transaction based IO.
 578 * The file expects a single write which triggers the transaction, and then
 579 * possibly a read which collects the result - which is stored in a
 580 * file-local buffer.
 581 */
 582char *simple_transaction_get(struct file *file, const char __user *buf, size_t size)
 583{
 584        struct simple_transaction_argresp *ar;
 585        static DEFINE_SPINLOCK(simple_transaction_lock);
 586
 587        if (size > SIMPLE_TRANSACTION_LIMIT - 1)
 588                return ERR_PTR(-EFBIG);
 589
 590        ar = (struct simple_transaction_argresp *)get_zeroed_page(GFP_KERNEL);
 591        if (!ar)
 592                return ERR_PTR(-ENOMEM);
 593
 594        spin_lock(&simple_transaction_lock);
 595
 596        /* only one write allowed per open */
 597        if (file->private_data) {
 598                spin_unlock(&simple_transaction_lock);
 599                free_page((unsigned long)ar);
 600                return ERR_PTR(-EBUSY);
 601        }
 602
 603        file->private_data = ar;
 604
 605        spin_unlock(&simple_transaction_lock);
 606
 607        if (copy_from_user(ar->data, buf, size))
 608                return ERR_PTR(-EFAULT);
 609
 610        return ar->data;
 611}
 612
 613ssize_t simple_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
 614{
 615        struct simple_transaction_argresp *ar = file->private_data;
 616
 617        if (!ar)
 618                return 0;
 619        return simple_read_from_buffer(buf, size, pos, ar->data, ar->size);
 620}
 621
 622int simple_transaction_release(struct inode *inode, struct file *file)
 623{
 624        free_page((unsigned long)file->private_data);
 625        return 0;
 626}
 627
 628/* Simple attribute files */
 629
 630struct simple_attr {
 631        int (*get)(void *, u64 *);
 632        int (*set)(void *, u64);
 633        char get_buf[24];       /* enough to store a u64 and "\n\0" */
 634        char set_buf[24];
 635        void *data;
 636        const char *fmt;        /* format for read operation */
 637        struct mutex mutex;     /* protects access to these buffers */
 638};
 639
 640/* simple_attr_open is called by an actual attribute open file operation
 641 * to set the attribute specific access operations. */
 642int simple_attr_open(struct inode *inode, struct file *file,
 643                     int (*get)(void *, u64 *), int (*set)(void *, u64),
 644                     const char *fmt)
 645{
 646        struct simple_attr *attr;
 647
 648        attr = kmalloc(sizeof(*attr), GFP_KERNEL);
 649        if (!attr)
 650                return -ENOMEM;
 651
 652        attr->get = get;
 653        attr->set = set;
 654        attr->data = inode->i_private;
 655        attr->fmt = fmt;
 656        mutex_init(&attr->mutex);
 657
 658        file->private_data = attr;
 659
 660        return nonseekable_open(inode, file);
 661}
 662
 663int simple_attr_release(struct inode *inode, struct file *file)
 664{
 665        kfree(file->private_data);
 666        return 0;
 667}
 668
 669/* read from the buffer that is filled with the get function */
 670ssize_t simple_attr_read(struct file *file, char __user *buf,
 671                         size_t len, loff_t *ppos)
 672{
 673        struct simple_attr *attr;
 674        size_t size;
 675        ssize_t ret;
 676
 677        attr = file->private_data;
 678
 679        if (!attr->get)
 680                return -EACCES;
 681
 682        ret = mutex_lock_interruptible(&attr->mutex);
 683        if (ret)
 684                return ret;
 685
 686        if (*ppos) {            /* continued read */
 687                size = strlen(attr->get_buf);
 688        } else {                /* first read */
 689                u64 val;
 690                ret = attr->get(attr->data, &val);
 691                if (ret)
 692                        goto out;
 693
 694                size = scnprintf(attr->get_buf, sizeof(attr->get_buf),
 695                                 attr->fmt, (unsigned long long)val);
 696        }
 697
 698        ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
 699out:
 700        mutex_unlock(&attr->mutex);
 701        return ret;
 702}
 703
 704/* interpret the buffer as a number to call the set function with */
 705ssize_t simple_attr_write(struct file *file, const char __user *buf,
 706                          size_t len, loff_t *ppos)
 707{
 708        struct simple_attr *attr;
 709        u64 val;
 710        size_t size;
 711        ssize_t ret;
 712
 713        attr = file->private_data;
 714        if (!attr->set)
 715                return -EACCES;
 716
 717        ret = mutex_lock_interruptible(&attr->mutex);
 718        if (ret)
 719                return ret;
 720
 721        ret = -EFAULT;
 722        size = min(sizeof(attr->set_buf) - 1, len);
 723        if (copy_from_user(attr->set_buf, buf, size))
 724                goto out;
 725
 726        ret = len; /* claim we got the whole input */
 727        attr->set_buf[size] = '\0';
 728        val = simple_strtol(attr->set_buf, NULL, 0);
 729        attr->set(attr->data, val);
 730out:
 731        mutex_unlock(&attr->mutex);
 732        return ret;
 733}
 734
 735/**
 736 * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
 737 * @sb:         filesystem to do the file handle conversion on
 738 * @fid:        file handle to convert
 739 * @fh_len:     length of the file handle in bytes
 740 * @fh_type:    type of file handle
 741 * @get_inode:  filesystem callback to retrieve inode
 742 *
 743 * This function decodes @fid as long as it has one of the well-known
 744 * Linux filehandle types and calls @get_inode on it to retrieve the
 745 * inode for the object specified in the file handle.
 746 */
 747struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,
 748                int fh_len, int fh_type, struct inode *(*get_inode)
 749                        (struct super_block *sb, u64 ino, u32 gen))
 750{
 751        struct inode *inode = NULL;
 752
 753        if (fh_len < 2)
 754                return NULL;
 755
 756        switch (fh_type) {
 757        case FILEID_INO32_GEN:
 758        case FILEID_INO32_GEN_PARENT:
 759                inode = get_inode(sb, fid->i32.ino, fid->i32.gen);
 760                break;
 761        }
 762
 763        return d_obtain_alias(inode);
 764}
 765EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
 766
 767/**
 768 * generic_fh_to_dentry - generic helper for the fh_to_parent export operation
 769 * @sb:         filesystem to do the file handle conversion on
 770 * @fid:        file handle to convert
 771 * @fh_len:     length of the file handle in bytes
 772 * @fh_type:    type of file handle
 773 * @get_inode:  filesystem callback to retrieve inode
 774 *
 775 * This function decodes @fid as long as it has one of the well-known
 776 * Linux filehandle types and calls @get_inode on it to retrieve the
 777 * inode for the _parent_ object specified in the file handle if it
 778 * is specified in the file handle, or NULL otherwise.
 779 */
 780struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
 781                int fh_len, int fh_type, struct inode *(*get_inode)
 782                        (struct super_block *sb, u64 ino, u32 gen))
 783{
 784        struct inode *inode = NULL;
 785
 786        if (fh_len <= 2)
 787                return NULL;
 788
 789        switch (fh_type) {
 790        case FILEID_INO32_GEN_PARENT:
 791                inode = get_inode(sb, fid->i32.parent_ino,
 792                                  (fh_len > 3 ? fid->i32.parent_gen : 0));
 793                break;
 794        }
 795
 796        return d_obtain_alias(inode);
 797}
 798EXPORT_SYMBOL_GPL(generic_fh_to_parent);
 799
 800EXPORT_SYMBOL(dcache_dir_close);
 801EXPORT_SYMBOL(dcache_dir_lseek);
 802EXPORT_SYMBOL(dcache_dir_open);
 803EXPORT_SYMBOL(dcache_readdir);
 804EXPORT_SYMBOL(generic_read_dir);
 805EXPORT_SYMBOL(get_sb_pseudo);
 806EXPORT_SYMBOL(simple_write_begin);
 807EXPORT_SYMBOL(simple_write_end);
 808EXPORT_SYMBOL(simple_dir_inode_operations);
 809EXPORT_SYMBOL(simple_dir_operations);
 810EXPORT_SYMBOL(simple_empty);
 811EXPORT_SYMBOL(d_alloc_name);
 812EXPORT_SYMBOL(simple_fill_super);
 813EXPORT_SYMBOL(simple_getattr);
 814EXPORT_SYMBOL(simple_link);
 815EXPORT_SYMBOL(simple_lookup);
 816EXPORT_SYMBOL(simple_pin_fs);
 817EXPORT_UNUSED_SYMBOL(simple_prepare_write);
 818EXPORT_SYMBOL(simple_readpage);
 819EXPORT_SYMBOL(simple_release_fs);
 820EXPORT_SYMBOL(simple_rename);
 821EXPORT_SYMBOL(simple_rmdir);
 822EXPORT_SYMBOL(simple_statfs);
 823EXPORT_SYMBOL(simple_sync_file);
 824EXPORT_SYMBOL(simple_unlink);
 825EXPORT_SYMBOL(simple_read_from_buffer);
 826EXPORT_SYMBOL(memory_read_from_buffer);
 827EXPORT_SYMBOL(simple_transaction_get);
 828EXPORT_SYMBOL(simple_transaction_read);
 829EXPORT_SYMBOL(simple_transaction_release);
 830EXPORT_SYMBOL_GPL(simple_attr_open);
 831EXPORT_SYMBOL_GPL(simple_attr_release);
 832EXPORT_SYMBOL_GPL(simple_attr_read);
 833EXPORT_SYMBOL_GPL(simple_attr_write);
 834
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.