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