2 * Copyright (C) 2011+ Evgeniy Polyakov <zbr@ioremap.net>
8 #include <linux/backing-dev.h>
9 #include <linux/crypto.h>
11 #include <linux/kref.h>
12 #include <linux/list.h>
13 #include <linux/mutex.h>
14 #include <linux/net.h>
15 #include <linux/pagemap.h>
16 #include <linux/printk.h>
17 #include <linux/slab.h>
18 #include <linux/wait.h>
19 #include <linux/workqueue.h>
21 #include <crypto/sha.h>
23 #define dnet_bswap16(x) cpu_to_le16(x)
24 #define dnet_bswap32(x) cpu_to_le32(x)
25 #define dnet_bswap64(x) cpu_to_le64(x)
27 /* theese are needed for packet.h below to compile */
28 #define DNET_ID_SIZE SHA512_DIGEST_SIZE
29 #define DNET_CSUM_SIZE SHA512_DIGEST_SIZE
32 * is not used in kernel, but we want to share the same header
33 * with userspace, so I put it here for compiler to shut up
35 int gettimeofday(struct timeval
*, struct timezone
*);
39 static inline struct timespec
pohmelfs_date(struct dnet_time
*tm
)
44 ts
.tv_nsec
= tm
->tnsec
;
51 struct dnet_attr attr
;
53 struct dnet_io_attr io
;
59 * Returns 1 when id1 > id2
63 static inline int dnet_id_cmp_str(const unsigned char *id1
, const unsigned char *id2
)
67 for (i
*=sizeof(unsigned long); i
<DNET_ID_SIZE
; ++i
) {
77 struct pohmelfs_state
;
79 struct pohmelfs_trans
;
81 struct pohmelfs_trans_cb
{
82 int (* init
)(struct pohmelfs_trans
*t
);
83 int (* complete
)(struct pohmelfs_trans
*t
, struct pohmelfs_state
*recv
);
84 int (* recv_reply
)(struct pohmelfs_trans
*t
, struct pohmelfs_state
*recv
);
85 void (* destroy
)(struct pohmelfs_trans
*t
);
88 struct pohmelfs_trans
{
89 struct list_head trans_entry
;
97 struct pohmelfs_state
*st
;
99 struct pohmelfs_cmd cmd
;
101 u64 header_size
, data_size
;
105 struct address_space
*mapping
;
107 unsigned long long recv_offset
;
112 struct pohmelfs_trans_cb cb
;
115 struct pohmelfs_trans
*pohmelfs_trans_alloc(struct inode
*inode
);
116 struct pohmelfs_trans
*pohmelfs_trans_alloc_io_buf(struct inode
*inode
, int group
, int command
,
117 void *data
, u64 offset
, u64 size
, int aflags
, int ioflags
, int type
);
118 void pohmelfs_trans_put(struct pohmelfs_trans
*t
);
120 int pohmelfs_trans_insert(struct pohmelfs_trans
*t
);
121 struct pohmelfs_trans
*pohmelfs_trans_lookup(struct pohmelfs_state
*st
, struct dnet_cmd
*cmd
);
123 struct pohmelfs_state
{
124 struct pohmelfs_sb
*psb
;
125 struct list_head state_entry
;
127 struct sockaddr_storage sa
;
133 struct mutex trans_lock
;
134 struct list_head trans_list
;
135 struct list_head sent_trans_list
;
141 /* Waiting/polling machinery */
143 wait_queue_head_t
*whead
;
145 struct work_struct send_work
;
146 struct work_struct recv_work
;
148 /* is set when dnet_cmd is being read, otherwise attached data */
150 /* currently read command reply */
154 struct pohmelfs_state
*pohmelfs_state_create(struct pohmelfs_sb
*psb
, struct sockaddr_storage
*sa
, int addrlen
,
155 int ask_route
, int group_id
);
156 struct pohmelfs_state
*pohmelfs_state_lookup(struct pohmelfs_sb
*psb
, struct dnet_raw_id
*id
, int group
);
158 static inline void pohmelfs_state_get(struct pohmelfs_state
*st
)
160 kref_get(&st
->refcnt
);
163 void pohmelfs_state_put(struct pohmelfs_state
*st
);
164 void pohmelfs_state_kill(struct pohmelfs_state
*st
);
166 struct pohmelfs_state
*pohmelfs_addr_exist(struct pohmelfs_sb
*psb
, struct sockaddr_storage
*sa
, int addrlen
);
168 void pohmelfs_state_schedule(struct pohmelfs_state
*st
);
170 __attribute__ ((format (printf
, 2, 3))) void pohmelfs_print_addr(struct sockaddr_storage
*addr
, const char *fmt
, ...);
172 #define POHMELFS_INODE_INFO_REMOVED (1<<0)
174 struct pohmelfs_inode_info
{
175 struct dnet_raw_id id
;
181 unsigned int blocksize
;
182 unsigned int namelen
;
191 struct dnet_time ctime
;
192 struct dnet_time mtime
;
193 struct dnet_time atime
;
194 } __attribute__ ((packed
));
196 void pohmelfs_fill_inode_info(struct inode
*inode
, struct pohmelfs_inode_info
*info
);
197 void pohmelfs_fill_inode(struct inode
*inode
, struct pohmelfs_inode_info
*info
);
198 void pohmelfs_convert_inode_info(struct pohmelfs_inode_info
*info
);
199 void pohmelfs_inode_info_current(struct pohmelfs_sb
*psb
, struct pohmelfs_inode_info
*info
);
201 struct pohmelfs_inode
{
202 struct inode vfs_inode
;
203 struct dnet_raw_id id
;
204 struct dnet_raw_id parent_id
;
208 unsigned long long offset
;
209 unsigned long long isize
;
212 int pohmelfs_send_inode_info(struct pohmelfs_inode
*pi
, struct dnet_raw_id
*id
, const char *sname
, int len
);
213 struct pohmelfs_inode
*pohmelfs_sb_inode_lookup(struct pohmelfs_sb
*psb
, struct dnet_raw_id
*id
);
216 struct super_block
*sb
;
217 struct backing_dev_info bdi
;
219 struct pohmelfs_inode
*root
;
221 spinlock_t inode_lock
;
222 struct rb_root inode_root
;
229 struct rb_root route_root
;
230 struct list_head state_list
;
231 spinlock_t state_lock
;
233 long read_wait_timeout
;
234 long write_wait_timeout
;
242 struct crypto_hash
*hash
;
244 struct workqueue_struct
*wq
;
250 static inline struct pohmelfs_sb
*pohmelfs_sb(struct super_block
*sb
)
252 return (struct pohmelfs_sb
*)sb
->s_fs_info
;
255 static inline struct pohmelfs_inode
*pohmelfs_inode(struct inode
*inode
)
257 return container_of(inode
, struct pohmelfs_inode
, vfs_inode
);
260 extern struct kmem_cache
*pohmelfs_inode_cache
;
261 extern struct kmem_cache
*pohmelfs_trans_cache
;
262 extern struct kmem_cache
*pohmelfs_inode_info_cache
;
263 extern struct kmem_cache
*pohmelfs_route_cache
;
264 extern struct kmem_cache
*pohmelfs_wait_cache
;
265 extern struct kmem_cache
*pohmelfs_io_cache
;
267 struct inode
*pohmelfs_alloc_inode(struct super_block
*sb
);
268 void pohmelfs_destroy_inode(struct inode
*);
270 struct pohmelfs_inode
*pohmelfs_existing_inode(struct pohmelfs_sb
*psb
, struct pohmelfs_inode_info
*info
);
271 struct pohmelfs_inode
*pohmelfs_new_inode(struct pohmelfs_sb
*psb
, int mode
);
272 int pohmelfs_hash(struct pohmelfs_sb
*psb
, const void *data
, const size_t size
, struct dnet_raw_id
*id
);
274 char *pohmelfs_dump_id(const unsigned char *id
);
276 extern const struct file_operations pohmelfs_dir_fops
;
277 extern const struct inode_operations pohmelfs_dir_inode_operations
;
279 extern const struct file_operations pohmelfs_file_ops
;
280 extern const struct inode_operations pohmelfs_file_inode_operations
;
282 extern void *pohmelfs_scratch_buf
;
283 extern int pohmelfs_scratch_buf_size
;
286 * if this flag is set, pohmelfs_inode_info->data is owned by the caller,
287 * so sending path may use it on its own and free (using kfree) when it's done
289 * This logic does not work for shared buffers or
290 * when multiple transactions will be sent for single pohmelfs_inode_info
292 #define POHMELFS_IO_OWN (1<<0)
295 struct pohmelfs_inode
*pi
;
297 struct dnet_raw_id
*id
;
314 struct address_space
*mapping
;
318 struct pohmelfs_trans_cb cb
;
321 int pohmelfs_send_io_group(struct pohmelfs_io
*pio
, int group_id
);
322 int pohmelfs_send_io(struct pohmelfs_io
*pio
);
323 int pohmelfs_send_buf_single(struct pohmelfs_io
*pio
, struct pohmelfs_state
*st
);
324 int pohmelfs_send_buf(struct pohmelfs_io
*pio
);
326 int pohmelfs_data_recv(struct pohmelfs_state
*st
, void *buf
, u64 size
, unsigned int flags
);
327 int pohmelfs_recv(struct pohmelfs_trans
*t
, struct pohmelfs_state
*recv
, void *data
, int size
);
329 struct pohmelfs_route
{
332 struct dnet_raw_id id
;
333 struct pohmelfs_state
*st
;
336 int pohmelfs_route_request(struct pohmelfs_state
*st
);
337 void pohmelfs_route_remove_all(struct pohmelfs_state
*st
);
339 struct pohmelfs_wait
{
340 wait_queue_head_t wq
;
341 struct pohmelfs_inode
*pi
;
347 struct pohmelfs_wait
*pohmelfs_wait_alloc(struct pohmelfs_inode
*pi
);
348 void pohmelfs_wait_put(struct pohmelfs_wait
*wait
);
349 static inline void pohmelfs_wait_get(struct pohmelfs_wait
*wait
)
351 kref_get(&wait
->refcnt
);
354 #endif /* __POHMELFS_H */