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