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