linux/drivers/staging/pohmelfs/netfs.h
<<
>>
Prefs
   1/*
   2 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
   3 * All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2 of the License, or
   8 * (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 */
  15
  16#ifndef __NETFS_H
  17#define __NETFS_H
  18
  19#include <linux/types.h>
  20#include <linux/connector.h>
  21#include <linux/backing-dev.h>
  22
  23#define POHMELFS_CN_IDX                 5
  24#define POHMELFS_CN_VAL                 0
  25
  26#define POHMELFS_CTLINFO_ACK            1
  27#define POHMELFS_NOINFO_ACK             2
  28
  29#define POHMELFS_NULL_IDX               65535
  30
  31/*
  32 * Network command structure.
  33 * Will be extended.
  34 */
  35struct netfs_cmd {
  36        __u16                   cmd;    /* Command number */
  37        __u16                   csize;  /* Attached crypto information size */
  38        __u16                   cpad;   /* Attached padding size */
  39        __u16                   ext;    /* External flags */
  40        __u32                   size;   /* Size of the attached data */
  41        __u32                   trans;  /* Transaction id */
  42        __u64                   id;     /* Object ID to operate on. Used for feedback.*/
  43        __u64                   start;  /* Start of the object. */
  44        __u64                   iv;     /* IV sequence */
  45        __u8                    data[0];
  46};
  47
  48static inline void netfs_convert_cmd(struct netfs_cmd *cmd)
  49{
  50        cmd->id = __be64_to_cpu(cmd->id);
  51        cmd->start = __be64_to_cpu(cmd->start);
  52        cmd->iv = __be64_to_cpu(cmd->iv);
  53        cmd->cmd = __be16_to_cpu(cmd->cmd);
  54        cmd->ext = __be16_to_cpu(cmd->ext);
  55        cmd->csize = __be16_to_cpu(cmd->csize);
  56        cmd->cpad = __be16_to_cpu(cmd->cpad);
  57        cmd->size = __be32_to_cpu(cmd->size);
  58}
  59
  60#define NETFS_TRANS_SINGLE_DST          (1<<0)
  61
  62enum {
  63        NETFS_READDIR   = 1,    /* Read directory for given inode number */
  64        NETFS_READ_PAGE,        /* Read data page from the server */
  65        NETFS_WRITE_PAGE,       /* Write data page to the server */
  66        NETFS_CREATE,           /* Create directory entry */
  67        NETFS_REMOVE,           /* Remove directory entry */
  68
  69        NETFS_LOOKUP,           /* Lookup single object */
  70        NETFS_LINK,             /* Create a link */
  71        NETFS_TRANS,            /* Transaction */
  72        NETFS_OPEN,             /* Open intent */
  73        NETFS_INODE_INFO,       /* Metadata cache coherency synchronization message */
  74
  75        NETFS_PAGE_CACHE,       /* Page cache invalidation message */
  76        NETFS_READ_PAGES,       /* Read multiple contiguous pages in one go */
  77        NETFS_RENAME,           /* Rename object */
  78        NETFS_CAPABILITIES,     /* Capabilities of the client, for example supported crypto */
  79        NETFS_LOCK,             /* Distributed lock message */
  80
  81        NETFS_XATTR_SET,        /* Set extended attribute */
  82        NETFS_XATTR_GET,        /* Get extended attribute */
  83        NETFS_CMD_MAX
  84};
  85
  86enum {
  87        POHMELFS_FLAGS_ADD = 0, /* Network state control message for ADD */
  88        POHMELFS_FLAGS_DEL,     /* Network state control message for DEL */
  89        POHMELFS_FLAGS_SHOW,    /* Network state control message for SHOW */
  90        POHMELFS_FLAGS_CRYPTO,  /* Crypto data control message */
  91        POHMELFS_FLAGS_MODIFY,  /* Network state modification message */
  92        POHMELFS_FLAGS_DUMP,    /* Network state control message for SHOW ALL */
  93        POHMELFS_FLAGS_FLUSH,   /* Network state control message for FLUSH */
  94};
  95
  96/*
  97 * Always wanted to copy it from socket headers into public one,
  98 * since they are __KERNEL__ protected there.
  99 */
 100#define _K_SS_MAXSIZE   128
 101
 102struct saddr {
 103        unsigned short          sa_family;
 104        char                    addr[_K_SS_MAXSIZE];
 105};
 106
 107enum {
 108        POHMELFS_CRYPTO_HASH = 0,
 109        POHMELFS_CRYPTO_CIPHER,
 110};
 111
 112struct pohmelfs_crypto {
 113        unsigned int            idx;            /* Config index */
 114        unsigned short          strlen;         /* Size of the attached crypto string including 0-byte
 115                                                 * "cbc(aes)" for example */
 116        unsigned short          type;           /* HMAC, cipher, both */
 117        unsigned int            keysize;        /* Key size */
 118        unsigned char           data[0];        /* Algorithm string, key and IV */
 119};
 120
 121#define POHMELFS_IO_PERM_READ           (1<<0)
 122#define POHMELFS_IO_PERM_WRITE          (1<<1)
 123
 124/*
 125 * Configuration command used to create table of different remote servers.
 126 */
 127struct pohmelfs_ctl {
 128        __u32                   idx;            /* Config index */
 129        __u32                   type;           /* Socket type */
 130        __u32                   proto;          /* Socket protocol */
 131        __u16                   addrlen;        /* Size of the address */
 132        __u16                   perm;           /* IO permission */
 133        __u16                   prio;           /* IO priority */
 134        struct saddr            addr;           /* Remote server address */
 135};
 136
 137/*
 138 * Ack for userspace about requested command.
 139 */
 140struct pohmelfs_cn_ack {
 141        struct cn_msg           msg;
 142        int                     error;
 143        int                     msg_num;
 144        int                     unused[3];
 145        struct pohmelfs_ctl     ctl;
 146};
 147
 148/*
 149 * Inode info structure used to sync with server.
 150 * Check what stat() returns.
 151 */
 152struct netfs_inode_info {
 153        unsigned int            mode;
 154        unsigned int            nlink;
 155        unsigned int            uid;
 156        unsigned int            gid;
 157        unsigned int            blocksize;
 158        unsigned int            padding;
 159        __u64                   ino;
 160        __u64                   blocks;
 161        __u64                   rdev;
 162        __u64                   size;
 163        __u64                   version;
 164};
 165
 166static inline void netfs_convert_inode_info(struct netfs_inode_info *info)
 167{
 168        info->mode = __cpu_to_be32(info->mode);
 169        info->nlink = __cpu_to_be32(info->nlink);
 170        info->uid = __cpu_to_be32(info->uid);
 171        info->gid = __cpu_to_be32(info->gid);
 172        info->blocksize = __cpu_to_be32(info->blocksize);
 173        info->blocks = __cpu_to_be64(info->blocks);
 174        info->rdev = __cpu_to_be64(info->rdev);
 175        info->size = __cpu_to_be64(info->size);
 176        info->version = __cpu_to_be64(info->version);
 177        info->ino = __cpu_to_be64(info->ino);
 178}
 179
 180/*
 181 * Cache state machine.
 182 */
 183enum {
 184        NETFS_COMMAND_PENDING = 0,      /* Command is being executed */
 185        NETFS_INODE_REMOTE_SYNCED,      /* Inode was synced to server */
 186        NETFS_INODE_REMOTE_DIR_SYNCED,  /* Inode (directory) was synced from the server */
 187        NETFS_INODE_OWNED,              /* Inode is owned by given host */
 188        NETFS_INODE_NEED_FLUSH,         /* Inode has to be flushed to the server */
 189};
 190
 191/*
 192 * POHMELFS capabilities: information about supported
 193 * crypto operations (hash/cipher, modes, key sizes and so on),
 194 * root informaion (used/available size, number of objects, permissions)
 195 */
 196enum pohmelfs_capabilities {
 197        POHMELFS_CRYPTO_CAPABILITIES = 0,
 198        POHMELFS_ROOT_CAPABILITIES,
 199};
 200
 201/* Read-only mount */
 202#define POHMELFS_FLAGS_RO               (1<<0)
 203/* Extended attributes support on/off */
 204#define POHMELFS_FLAGS_XATTR            (1<<1)
 205
 206struct netfs_root_capabilities {
 207        __u64                   nr_files;
 208        __u64                   used, avail;
 209        __u64                   flags;
 210};
 211
 212static inline void netfs_convert_root_capabilities(struct netfs_root_capabilities *cap)
 213{
 214        cap->nr_files = __cpu_to_be64(cap->nr_files);
 215        cap->used = __cpu_to_be64(cap->used);
 216        cap->avail = __cpu_to_be64(cap->avail);
 217        cap->flags = __cpu_to_be64(cap->flags);
 218}
 219
 220struct netfs_crypto_capabilities {
 221        unsigned short          hash_strlen;    /* Hash string length, like "hmac(sha1) including 0 byte "*/
 222        unsigned short          cipher_strlen;  /* Cipher string length with the same format */
 223        unsigned int            cipher_keysize; /* Cipher key size */
 224};
 225
 226static inline void netfs_convert_crypto_capabilities(struct netfs_crypto_capabilities *cap)
 227{
 228        cap->hash_strlen = __cpu_to_be16(cap->hash_strlen);
 229        cap->cipher_strlen = __cpu_to_be16(cap->cipher_strlen);
 230        cap->cipher_keysize = __cpu_to_be32(cap->cipher_keysize);
 231}
 232
 233enum pohmelfs_lock_type {
 234        POHMELFS_LOCK_GRAB      = (1<<15),
 235
 236        POHMELFS_READ_LOCK      = 0,
 237        POHMELFS_WRITE_LOCK,
 238};
 239
 240struct netfs_lock {
 241        __u64                   start;
 242        __u64                   ino;
 243        __u32                   size;
 244        __u32                   type;
 245};
 246
 247static inline void netfs_convert_lock(struct netfs_lock *lock)
 248{
 249        lock->start = __cpu_to_be64(lock->start);
 250        lock->ino = __cpu_to_be64(lock->ino);
 251        lock->size = __cpu_to_be32(lock->size);
 252        lock->type = __cpu_to_be32(lock->type);
 253}
 254
 255#ifdef __KERNEL__
 256
 257#include <linux/kernel.h>
 258#include <linux/completion.h>
 259#include <linux/rbtree.h>
 260#include <linux/net.h>
 261#include <linux/poll.h>
 262
 263/*
 264 * Private POHMELFS cache of objects in directory.
 265 */
 266struct pohmelfs_name {
 267        struct rb_node          hash_node;
 268
 269        struct list_head        sync_create_entry;
 270
 271        u64                     ino;
 272
 273        u32                     hash;
 274        u32                     mode;
 275        u32                     len;
 276
 277        char                    *data;
 278};
 279
 280/*
 281 * POHMELFS inode. Main object.
 282 */
 283struct pohmelfs_inode {
 284        struct list_head        inode_entry;            /* Entry in superblock list.
 285                                                         * Objects which are not bound to dentry require to be dropped
 286                                                         * in ->put_super()
 287                                                         */
 288        struct rb_root          hash_root;              /* The same, but indexed by name hash and len */
 289        struct mutex            offset_lock;            /* Protect both above trees */
 290
 291        struct list_head        sync_create_list;       /* List of created but not yet synced to the server children */
 292
 293        unsigned int            drop_count;
 294
 295        int                     lock_type;              /* How this inode is locked: read or write */
 296
 297        int                     error;                  /* Transaction error for given inode */
 298
 299        long                    state;                  /* State machine above */
 300
 301        u64                     ino;                    /* Inode number */
 302        u64                     total_len;              /* Total length of all children names, used to create offsets */
 303
 304        struct inode            vfs_inode;
 305};
 306
 307struct netfs_trans;
 308typedef int (*netfs_trans_complete_t)(struct page **pages, unsigned int page_num,
 309                void *private, int err);
 310
 311struct netfs_state;
 312struct pohmelfs_sb;
 313
 314struct netfs_trans {
 315        /*
 316         * Transaction header and attached contiguous data live here.
 317         */
 318        struct iovec                    iovec;
 319
 320        /*
 321         * Pages attached to transaction.
 322         */
 323        struct page                     **pages;
 324
 325        /*
 326         * List and protecting lock for transaction destination
 327         * network states.
 328         */
 329        spinlock_t                      dst_lock;
 330        struct list_head                dst_list;
 331
 332        /*
 333         * Number of users for given transaction.
 334         * For example each network state attached to transaction
 335         * via dst_list increases it.
 336         */
 337        atomic_t                        refcnt;
 338
 339        /*
 340         * Number of pages attached to given transaction.
 341         * Some slots in above page array can be NULL, since
 342         * for example page can be under writeback already,
 343         * so we skip it in this transaction.
 344         */
 345        unsigned int                    page_num;
 346
 347        /*
 348         * Transaction flags: single dst or broadcast and so on.
 349         */
 350        unsigned int                    flags;
 351
 352        /*
 353         * Size of the data, which can be placed into
 354         * iovec.iov_base area.
 355         */
 356        unsigned int                    total_size;
 357
 358        /*
 359         * Number of pages to be sent to remote server.
 360         * Usually equal to above page_num, but in case of partial
 361         * writeback it can accumulate only pages already completed
 362         * previous writeback.
 363         */
 364        unsigned int                    attached_pages;
 365
 366        /*
 367         * Attached number of bytes in all above pages.
 368         */
 369        unsigned int                    attached_size;
 370
 371        /*
 372         * Unique transacton generation number.
 373         * Used as identity in the network state tree of transactions.
 374         */
 375        unsigned int                    gen;
 376
 377        /*
 378         * Transaction completion status.
 379         */
 380        int                             result;
 381
 382        /*
 383         * Superblock this transaction belongs to
 384         */
 385        struct pohmelfs_sb              *psb;
 386
 387        /*
 388         * Crypto engine, which processed this transaction.
 389         * Can be not NULL only if crypto engine holds encrypted pages.
 390         */
 391        struct pohmelfs_crypto_engine   *eng;
 392
 393        /* Private data */
 394        void                            *private;
 395
 396        /* Completion callback, invoked just before transaction is destroyed */
 397        netfs_trans_complete_t          complete;
 398};
 399
 400static inline int netfs_trans_cur_len(struct netfs_trans *t)
 401{
 402        return (signed)(t->total_size - t->iovec.iov_len);
 403}
 404
 405static inline void *netfs_trans_current(struct netfs_trans *t)
 406{
 407        return t->iovec.iov_base + t->iovec.iov_len;
 408}
 409
 410struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
 411                unsigned int flags, unsigned int nr);
 412void netfs_trans_free(struct netfs_trans *t);
 413int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb);
 414int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb);
 415
 416static inline void netfs_trans_reset(struct netfs_trans *t)
 417{
 418        t->complete = NULL;
 419}
 420
 421struct netfs_trans_dst {
 422        struct list_head                trans_entry;
 423        struct rb_node                  state_entry;
 424
 425        unsigned long                   send_time;
 426
 427        /*
 428         * Times this transaction was resent to its old or new,
 429         * depending on flags, destinations. When it reaches maximum
 430         * allowed number, specified in superblock->trans_retries,
 431         * transaction will be freed with ETIMEDOUT error.
 432         */
 433        unsigned int                    retries;
 434
 435        struct netfs_trans              *trans;
 436        struct netfs_state              *state;
 437};
 438
 439struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen);
 440void netfs_trans_drop_dst(struct netfs_trans_dst *dst);
 441void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst);
 442void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st);
 443void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st);
 444int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb);
 445int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st);
 446
 447int netfs_trans_init(void);
 448void netfs_trans_exit(void);
 449
 450struct pohmelfs_crypto_engine {
 451        u64                             iv;             /* Crypto IV for current operation */
 452        unsigned long                   timeout;        /* Crypto waiting timeout */
 453        unsigned int                    size;           /* Size of crypto scratchpad */
 454        void                            *data;          /* Temporal crypto scratchpad */
 455        /*
 456         * Crypto operations performed on objects.
 457         */
 458        struct crypto_hash              *hash;
 459        struct crypto_ablkcipher        *cipher;
 460
 461        struct pohmelfs_crypto_thread   *thread;        /* Crypto thread which hosts this engine */
 462
 463        struct page                     **pages;
 464        unsigned int                    page_num;
 465};
 466
 467struct pohmelfs_crypto_thread {
 468        struct list_head                thread_entry;
 469
 470        struct task_struct              *thread;
 471        struct pohmelfs_sb              *psb;
 472
 473        struct pohmelfs_crypto_engine   eng;
 474
 475        struct netfs_trans              *trans;
 476
 477        wait_queue_head_t               wait;
 478        int                             error;
 479
 480        unsigned int                    size;
 481        struct page                     *page;
 482};
 483
 484void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th);
 485
 486/*
 487 * Network state, attached to one server.
 488 */
 489struct netfs_state {
 490        struct mutex            __state_lock;           /* Can not allow to use the same socket simultaneously */
 491        struct mutex            __state_send_lock;
 492        struct netfs_cmd        cmd;                    /* Cached command */
 493        struct netfs_inode_info info;                   /* Cached inode info */
 494
 495        void                    *data;                  /* Cached some data */
 496        unsigned int            size;                   /* Size of that data */
 497
 498        struct pohmelfs_sb      *psb;                   /* Superblock */
 499
 500        struct task_struct      *thread;                /* Async receiving thread */
 501
 502        /* Waiting/polling machinery */
 503        wait_queue_t            wait;
 504        wait_queue_head_t       *whead;
 505        wait_queue_head_t       thread_wait;
 506
 507        struct mutex            trans_lock;
 508        struct rb_root          trans_root;
 509
 510        struct pohmelfs_ctl     ctl;                    /* Remote peer */
 511
 512        struct socket           *socket;                /* Socket object */
 513        struct socket           *read_socket;           /* Cached pointer to socket object.
 514                                                         * Used to determine if between lock drops socket was changed.
 515                                                         * Never used to read data or any kind of access.
 516                                                         */
 517        /*
 518         * Crypto engines to process incoming data.
 519         */
 520        struct pohmelfs_crypto_engine   eng;
 521
 522        int                     need_reset;
 523};
 524
 525int netfs_state_init(struct netfs_state *st);
 526void netfs_state_exit(struct netfs_state *st);
 527
 528static inline void netfs_state_lock_send(struct netfs_state *st)
 529{
 530        mutex_lock(&st->__state_send_lock);
 531}
 532
 533static inline int netfs_state_trylock_send(struct netfs_state *st)
 534{
 535        return mutex_trylock(&st->__state_send_lock);
 536}
 537
 538static inline void netfs_state_unlock_send(struct netfs_state *st)
 539{
 540        BUG_ON(!mutex_is_locked(&st->__state_send_lock));
 541
 542        mutex_unlock(&st->__state_send_lock);
 543}
 544
 545static inline void netfs_state_lock(struct netfs_state *st)
 546{
 547        mutex_lock(&st->__state_lock);
 548}
 549
 550static inline void netfs_state_unlock(struct netfs_state *st)
 551{
 552        BUG_ON(!mutex_is_locked(&st->__state_lock));
 553
 554        mutex_unlock(&st->__state_lock);
 555}
 556
 557static inline unsigned int netfs_state_poll(struct netfs_state *st)
 558{
 559        unsigned int revents = POLLHUP | POLLERR;
 560
 561        netfs_state_lock(st);
 562        if (st->socket)
 563                revents = st->socket->ops->poll(NULL, st->socket, NULL);
 564        netfs_state_unlock(st);
 565
 566        return revents;
 567}
 568
 569struct pohmelfs_config;
 570
 571struct pohmelfs_sb {
 572        struct rb_root          mcache_root;
 573        struct mutex            mcache_lock;
 574        atomic_long_t           mcache_gen;
 575        unsigned long           mcache_timeout;
 576
 577        unsigned int            idx;
 578
 579        unsigned int            trans_retries;
 580
 581        atomic_t                trans_gen;
 582
 583        unsigned int            crypto_attached_size;
 584        unsigned int            crypto_align_size;
 585
 586        unsigned int            crypto_fail_unsupported;
 587
 588        unsigned int            crypto_thread_num;
 589        struct list_head        crypto_active_list, crypto_ready_list;
 590        struct mutex            crypto_thread_lock;
 591
 592        unsigned int            trans_max_pages;
 593        unsigned long           trans_data_size;
 594        unsigned long           trans_timeout;
 595
 596        unsigned long           drop_scan_timeout;
 597        unsigned long           trans_scan_timeout;
 598
 599        unsigned long           wait_on_page_timeout;
 600
 601        struct list_head        flush_list;
 602        struct list_head        drop_list;
 603        spinlock_t              ino_lock;
 604        u64                     ino;
 605
 606        /*
 607         * Remote nodes POHMELFS connected to.
 608         */
 609        struct list_head        state_list;
 610        struct mutex            state_lock;
 611
 612        /*
 613         * Currently active state to request data from.
 614         */
 615        struct pohmelfs_config  *active_state;
 616
 617
 618        wait_queue_head_t       wait;
 619
 620        /*
 621         * Timed checks: stale transactions, inodes to be freed and so on.
 622         */
 623        struct delayed_work     dwork;
 624        struct delayed_work     drop_dwork;
 625
 626        struct super_block      *sb;
 627
 628        struct backing_dev_info bdi;
 629
 630        /*
 631         * Algorithm strings.
 632         */
 633        char                    *hash_string;
 634        char                    *cipher_string;
 635
 636        u8                      *hash_key;
 637        u8                      *cipher_key;
 638
 639        /*
 640         * Algorithm string lengths.
 641         */
 642        unsigned int            hash_strlen;
 643        unsigned int            cipher_strlen;
 644        unsigned int            hash_keysize;
 645        unsigned int            cipher_keysize;
 646
 647        /*
 648         * Controls whether to perfrom crypto processing or not.
 649         */
 650        int                     perform_crypto;
 651
 652        /*
 653         * POHMELFS statistics.
 654         */
 655        u64                     total_size;
 656        u64                     avail_size;
 657        atomic_long_t           total_inodes;
 658
 659        /*
 660         * Xattr support, read-only and so on.
 661         */
 662        u64                     state_flags;
 663
 664        /*
 665         * Temporary storage to detect changes in the wait queue.
 666         */
 667        long                    flags;
 668};
 669
 670static inline void netfs_trans_update(struct netfs_cmd *cmd,
 671                struct netfs_trans *t, unsigned int size)
 672{
 673        unsigned int sz = ALIGN(size, t->psb->crypto_align_size);
 674
 675        t->iovec.iov_len += sizeof(struct netfs_cmd) + sz;
 676        cmd->cpad = __cpu_to_be16(sz - size);
 677}
 678
 679static inline struct pohmelfs_sb *POHMELFS_SB(struct super_block *sb)
 680{
 681        return sb->s_fs_info;
 682}
 683
 684static inline struct pohmelfs_inode *POHMELFS_I(struct inode *inode)
 685{
 686        return container_of(inode, struct pohmelfs_inode, vfs_inode);
 687}
 688
 689static inline u64 pohmelfs_new_ino(struct pohmelfs_sb *psb)
 690{
 691        u64 ino;
 692
 693        spin_lock(&psb->ino_lock);
 694        ino = psb->ino++;
 695        spin_unlock(&psb->ino_lock);
 696
 697        return ino;
 698}
 699
 700static inline void pohmelfs_put_inode(struct pohmelfs_inode *pi)
 701{
 702        struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
 703
 704        spin_lock(&psb->ino_lock);
 705        list_move_tail(&pi->inode_entry, &psb->drop_list);
 706        pi->drop_count++;
 707        spin_unlock(&psb->ino_lock);
 708}
 709
 710struct pohmelfs_config {
 711        struct list_head        config_entry;
 712
 713        struct netfs_state      state;
 714};
 715
 716struct pohmelfs_config_group {
 717        /*
 718         * Entry in the global config group list.
 719         */
 720        struct list_head        group_entry;
 721
 722        /*
 723         * Index of the current group.
 724         */
 725        unsigned int            idx;
 726        /*
 727         * Number of config_list entries in this group entry.
 728         */
 729        unsigned int            num_entry;
 730        /*
 731         * Algorithm strings.
 732         */
 733        char                    *hash_string;
 734        char                    *cipher_string;
 735
 736        /*
 737         * Algorithm string lengths.
 738         */
 739        unsigned int            hash_strlen;
 740        unsigned int            cipher_strlen;
 741
 742        /*
 743         * Key and its size.
 744         */
 745        unsigned int            hash_keysize;
 746        unsigned int            cipher_keysize;
 747        u8                      *hash_key;
 748        u8                      *cipher_key;
 749
 750        /*
 751         * List of config entries (network state info) for given idx.
 752         */
 753        struct list_head        config_list;
 754};
 755
 756int __init pohmelfs_config_init(void);
 757void pohmelfs_config_exit(void);
 758int pohmelfs_copy_config(struct pohmelfs_sb *psb);
 759int pohmelfs_copy_crypto(struct pohmelfs_sb *psb);
 760int pohmelfs_config_check(struct pohmelfs_config *config, int idx);
 761int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf);
 762
 763extern const struct file_operations pohmelfs_dir_fops;
 764extern const struct inode_operations pohmelfs_dir_inode_ops;
 765
 766int pohmelfs_state_init(struct pohmelfs_sb *psb);
 767void pohmelfs_state_exit(struct pohmelfs_sb *psb);
 768void pohmelfs_state_flush_transactions(struct netfs_state *st);
 769
 770void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info);
 771
 772void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
 773void pohmelfs_free_names(struct pohmelfs_inode *parent);
 774struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash);
 775
 776void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi);
 777
 778struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
 779        struct pohmelfs_inode *parent, struct qstr *str, u64 start, int mode);
 780
 781int pohmelfs_write_create_inode(struct pohmelfs_inode *pi);
 782
 783int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans);
 784int pohmelfs_remove_child(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
 785
 786struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
 787                struct pohmelfs_inode *parent, struct qstr *str,
 788                struct netfs_inode_info *info, int link);
 789
 790int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr);
 791int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr);
 792
 793int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
 794                netfs_trans_complete_t complete, void *priv, u64 start);
 795int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
 796                unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start);
 797
 798void pohmelfs_check_states(struct pohmelfs_sb *psb);
 799void pohmelfs_switch_active(struct pohmelfs_sb *psb);
 800
 801int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len);
 802int pohmelfs_path_length(struct pohmelfs_inode *pi);
 803
 804struct pohmelfs_crypto_completion {
 805        struct completion       complete;
 806        int                     error;
 807};
 808
 809int pohmelfs_trans_crypt(struct netfs_trans *t, struct pohmelfs_sb *psb);
 810void pohmelfs_crypto_exit(struct pohmelfs_sb *psb);
 811int pohmelfs_crypto_init(struct pohmelfs_sb *psb);
 812
 813int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb);
 814void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e);
 815
 816int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 iv,
 817                void *data, struct page *page, unsigned int size);
 818int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
 819                struct page *page, unsigned int size, u64 iv);
 820
 821static inline u64 pohmelfs_gen_iv(struct netfs_trans *t)
 822{
 823        u64 iv = t->gen;
 824
 825        iv <<= 32;
 826        iv |= ((unsigned long)t) & 0xffffffff;
 827
 828        return iv;
 829}
 830
 831int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
 832int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
 833int pohmelfs_data_lock_response(struct netfs_state *st);
 834
 835static inline int pohmelfs_need_lock(struct pohmelfs_inode *pi, int type)
 836{
 837        if (test_bit(NETFS_INODE_OWNED, &pi->state)) {
 838                if (type == pi->lock_type)
 839                        return 0;
 840                if ((type == POHMELFS_READ_LOCK) && (pi->lock_type == POHMELFS_WRITE_LOCK))
 841                        return 0;
 842        }
 843
 844        if (!test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
 845                return 0;
 846
 847        return 1;
 848}
 849
 850int __init pohmelfs_mcache_init(void);
 851void pohmelfs_mcache_exit(void);
 852
 853/* #define CONFIG_POHMELFS_DEBUG */
 854
 855#ifdef CONFIG_POHMELFS_DEBUG
 856#define dprintka(f, a...) printk(f, ##a)
 857#define dprintk(f, a...) printk("%d: " f, task_pid_vnr(current), ##a)
 858#else
 859#define dprintka(f, a...) do {} while (0)
 860#define dprintk(f, a...) do {} while (0)
 861#endif
 862
 863static inline void netfs_trans_get(struct netfs_trans *t)
 864{
 865        atomic_inc(&t->refcnt);
 866}
 867
 868static inline void netfs_trans_put(struct netfs_trans *t)
 869{
 870        if (atomic_dec_and_test(&t->refcnt)) {
 871                dprintk("%s: t: %p, gen: %u, err: %d.\n",
 872                        __func__, t, t->gen, t->result);
 873                if (t->complete)
 874                        t->complete(t->pages, t->page_num,
 875                                t->private, t->result);
 876                netfs_trans_free(t);
 877        }
 878}
 879
 880struct pohmelfs_mcache {
 881        struct rb_node                  mcache_entry;
 882        struct completion               complete;
 883
 884        atomic_t                        refcnt;
 885
 886        u64                             gen;
 887
 888        void                            *data;
 889        u64                             start;
 890        u32                             size;
 891        int                             err;
 892
 893        struct netfs_inode_info         info;
 894};
 895
 896struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
 897                unsigned int size, void *data);
 898void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
 899struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen);
 900void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
 901
 902static inline void pohmelfs_mcache_get(struct pohmelfs_mcache *m)
 903{
 904        atomic_inc(&m->refcnt);
 905}
 906
 907static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb,
 908                struct pohmelfs_mcache *m)
 909{
 910        if (atomic_dec_and_test(&m->refcnt))
 911                pohmelfs_mcache_free(psb, m);
 912}
 913
 914/*#define POHMELFS_TRUNCATE_ON_INODE_FLUSH
 915 */
 916
 917#endif /* __KERNEL__*/
 918
 919#endif /* __NETFS_H */
 920