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