Check whether readpages has non-contiguous pages in its list
[pohmelfs.git] / fs / pohmelfs / inode.c
blob389b73d946d6db692f4548047e85606b7d730d6b
1 /*
2 * Copyright (C) 2011+ Evgeniy Polyakov <zbr@ioremap.net>
3 */
5 #include <linux/buffer_head.h>
6 #include <linux/cred.h>
7 #include <linux/fiemap.h>
8 #include <linux/fs.h>
9 #include <linux/fs_struct.h>
10 #include <linux/mpage.h>
11 #include <linux/mount.h>
12 #include <linux/mm.h>
13 #include <linux/namei.h>
14 #include <linux/pagevec.h>
15 #include <linux/pagemap.h>
16 #include <linux/random.h>
17 #include <linux/scatterlist.h>
18 #include <linux/slab.h>
19 #include <linux/time.h>
20 #include <linux/writeback.h>
22 #include "pohmelfs.h"
24 char *pohmelfs_dump_id_len_raw(const unsigned char *id, unsigned int len, char *dst)
26 unsigned int i;
28 if (len > SHA512_DIGEST_SIZE)
29 len = SHA512_DIGEST_SIZE;
31 for (i=0; i<len; ++i)
32 sprintf(&dst[2*i], "%02x", id[i]);
33 return dst;
36 #define pohmelfs_dump_len 6
37 typedef struct {
38 char id_str[pohmelfs_dump_len * 2 + 1];
39 } pohmelfs_dump_t;
40 static DEFINE_PER_CPU(pohmelfs_dump_t, pohmelfs_dump_per_cpu);
42 char *pohmelfs_dump_id(const unsigned char *id)
44 pohmelfs_dump_t *ptr;
46 ptr = &get_cpu_var(pohmelfs_dump_per_cpu);
47 pohmelfs_dump_id_len_raw(id, pohmelfs_dump_len, ptr->id_str);
48 put_cpu_var(ptr);
50 return ptr->id_str;
53 #define dnet_raw_id_scratch 6
54 typedef struct {
55 unsigned long rand;
56 struct timespec ts;
57 } dnet_raw_id_scratch_t;
58 static DEFINE_PER_CPU(dnet_raw_id_scratch_t, dnet_raw_id_scratch_per_cpu);
60 static int pohmelfs_gen_id(struct pohmelfs_sb *psb, struct dnet_raw_id *id)
62 dnet_raw_id_scratch_t *sc;
63 int err;
64 long rand;
66 get_random_bytes(&rand, sizeof(sc->rand));
68 sc = &get_cpu_var(dnet_raw_id_scratch_per_cpu);
69 sc->rand ^= rand;
70 sc->ts = CURRENT_TIME;
72 err = pohmelfs_hash(psb, sc, sizeof(dnet_raw_id_scratch_t), id);
73 put_cpu_var(sc);
75 return err;
78 #define UNHASHED_OBSCURE_STRING_SIZE sizeof(" (deleted)")
81 * Create path from root for given inode.
82 * Path is formed as set of stuctures, containing name of the object
83 * and its inode data (mode, permissions and so on).
85 static int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len)
87 struct path path;
88 struct dentry *d;
89 char *ptr;
90 int err = 0, strlen, reduce = 0;
92 d = d_find_alias(&pi->vfs_inode);
93 if (!d) {
94 err = -ENOENT;
95 goto err_out_exit;
98 spin_lock(&current->fs->lock);
99 path.mnt = mntget(current->fs->root.mnt);
100 spin_unlock(&current->fs->lock);
102 path.dentry = d;
104 if (!IS_ROOT(d) && d_unhashed(d))
105 reduce = 1;
107 ptr = d_path(&path, data, len);
108 if (IS_ERR(ptr)) {
109 err = PTR_ERR(ptr);
110 goto err_out_put;
113 if (reduce && len >= UNHASHED_OBSCURE_STRING_SIZE) {
114 char *end = data + len - UNHASHED_OBSCURE_STRING_SIZE;
115 *end = '\0';
118 strlen = len - (ptr - (char *)data);
119 memmove(data, ptr, strlen);
120 ptr = data;
122 err = strlen - 1; /* no including 0-byte */
124 pr_debug("%s: dname: '%s', len: %u, maxlen: %u, name: '%s', strlen: %d.\n",
125 __func__, d->d_name.name, d->d_name.len, len, ptr, strlen);
127 err_out_put:
128 dput(d);
129 mntput(path.mnt);
130 err_out_exit:
131 return err;
134 int pohmelfs_http_compat_id(struct pohmelfs_inode *pi)
136 struct pohmelfs_sb *psb = pohmelfs_sb(pi->vfs_inode.i_sb);
137 struct timespec ts = CURRENT_TIME;
138 int idx = ts.tv_nsec % psb->http_compat;
139 struct pohmelfs_path *p = &psb->path[idx];
140 int err;
142 mutex_lock(&p->lock);
143 err = pohmelfs_construct_path_string(pi, p->data, PAGE_SIZE);
144 if (err > 0) {
145 pohmelfs_hash(psb, p->data, err, &pi->id);
147 mutex_unlock(&p->lock);
149 return err;
152 static int pohmelfs_sb_inode_insert(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi)
154 struct rb_node **n = &psb->inode_root.rb_node, *parent = NULL;
155 struct pohmelfs_inode *tmp;
156 int cmp, err = 0;
158 spin_lock(&psb->inode_lock);
159 while (*n) {
160 parent = *n;
162 tmp = rb_entry(parent, struct pohmelfs_inode, node);
164 cmp = dnet_id_cmp_str(tmp->id.id, pi->id.id);
165 if (cmp < 0)
166 n = &parent->rb_left;
167 else if (cmp > 0)
168 n = &parent->rb_right;
169 else {
170 err = -EEXIST;
171 goto err_out_unlock;
175 rb_link_node(&pi->node, parent, n);
176 rb_insert_color(&pi->node, &psb->inode_root);
178 err_out_unlock:
179 spin_unlock(&psb->inode_lock);
181 return err;
184 struct pohmelfs_inode *pohmelfs_sb_inode_lookup(struct pohmelfs_sb *psb, struct dnet_raw_id *id)
186 struct rb_node *n = psb->inode_root.rb_node;
187 struct pohmelfs_inode *pi, *found = NULL;
188 int cmp;
190 spin_lock(&psb->inode_lock);
191 while (n) {
192 pi = rb_entry(n, struct pohmelfs_inode, node);
194 cmp = dnet_id_cmp_str(pi->id.id, id->id);
195 if (cmp < 0) {
196 n = n->rb_left;
197 } else if (cmp > 0)
198 n = n->rb_right;
199 else {
200 found = pi;
201 break;
204 if (found) {
205 if (!igrab(&found->vfs_inode))
206 found = NULL;
208 spin_unlock(&psb->inode_lock);
210 return found;
213 struct inode *pohmelfs_alloc_inode(struct super_block *sb)
215 struct pohmelfs_inode *pi;
217 pi = kmem_cache_zalloc(pohmelfs_inode_cache, GFP_NOIO);
218 if (!pi)
219 goto err_out_exit;
221 inode_init_once(&pi->vfs_inode);
223 rb_init_node(&pi->node);
224 mutex_init(&pi->lock);
226 return &pi->vfs_inode;
228 err_out_exit:
229 return NULL;
232 void pohmelfs_destroy_inode(struct inode *inode)
234 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
236 pr_debug("pohmelfs: %s: destroy: ino: %ld, dirty: %lx\n", pohmelfs_dump_id(pi->id.id), inode->i_ino, inode->i_state & I_DIRTY);
238 kfree(pi->groups);
239 kmem_cache_free(pohmelfs_inode_cache, pi);
242 int pohmelfs_hash(struct pohmelfs_sb *psb, const void *data, const size_t size, struct dnet_raw_id *id)
244 struct scatterlist sg;
245 struct hash_desc desc;
247 sg_init_table(&sg, 1);
248 sg_set_buf(&sg, data, size);
250 desc.tfm = psb->hash;
251 desc.flags = 0;
253 return crypto_hash_digest(&desc, &sg, size, id->id);
256 struct pohmelfs_readpages_priv {
257 struct pohmelfs_wait wait;
258 struct kref refcnt;
259 int page_num, page_index;
260 struct page *pages[0];
263 static void pohmelfs_readpages_free(struct kref *kref)
265 struct pohmelfs_readpages_priv *rp = container_of(kref, struct pohmelfs_readpages_priv, refcnt);
266 struct pohmelfs_inode *pi = rp->wait.pi;
267 int i;
269 pr_debug("pohmelfs: %s: pohmelfs_readpages_free: read: %ld/%ld, wait: %d\n",
270 pohmelfs_dump_id(pi->id.id), atomic_long_read(&rp->wait.count),
271 rp->page_num * PAGE_CACHE_SIZE, rp->wait.condition);
273 for (i = 0; i < rp->page_num; ++i) {
274 struct page *page = rp->pages[i];
276 flush_dcache_page(page);
277 SetPageUptodate(page);
278 unlock_page(page);
279 page_cache_release(page);
282 iput(&rp->wait.pi->vfs_inode);
283 kfree(rp);
286 static void pohmelfs_readpages_destroy(struct pohmelfs_trans *t)
288 struct pohmelfs_readpages_priv *rp = t->priv;
289 struct pohmelfs_wait *wait = &rp->wait;
291 if (!wait->condition)
292 wait->condition = 1;
294 wake_up(&wait->wq);
295 kref_put(&rp->refcnt, pohmelfs_readpages_free);
298 static int pohmelfs_readpages_complete(struct pohmelfs_trans *t, struct pohmelfs_state *recv)
300 struct pohmelfs_readpages_priv *rp = t->priv;
301 struct pohmelfs_wait *wait = &rp->wait;
302 struct dnet_cmd *cmd = &recv->cmd;
304 if (!(cmd->flags & DNET_FLAGS_MORE)) {
305 if (!wait->condition) {
306 wait->condition = cmd->status;
307 if (!wait->condition)
308 wait->condition = 1;
309 wake_up(&rp->wait.wq);
313 pr_debug("pohmelfs: %d:%s: pohmelfs_readpages_complete: read: %ld, wait: %d\n",
314 cmd->id.group_id, pohmelfs_dump_id(wait->pi->id.id), atomic_long_read(&wait->count), wait->condition);
316 return 0;
319 static int pohmelfs_readpages_init(struct pohmelfs_trans *t)
321 struct pohmelfs_readpages_priv *rp = t->priv;
323 kref_get(&rp->refcnt);
324 return 0;
327 static int pohmelfs_readpages_recv_reply(struct pohmelfs_trans *t, struct pohmelfs_state *recv)
329 struct pohmelfs_readpages_priv *rp = t->priv;
330 struct pohmelfs_wait *wait = &rp->wait;
331 struct pohmelfs_inode *pi = wait->pi;
332 unsigned int asize = sizeof(struct dnet_attr) + sizeof(struct dnet_io_attr);
333 void *data = &t->cmd.attr; /* overwrite send buffer used for attr/ioattr */
334 struct dnet_cmd *cmd = &recv->cmd;
335 struct page *page;
336 pgoff_t offset;
337 int err, size;
339 if (t->recv_offset < asize) {
340 size = asize - t->recv_offset;
341 data += t->recv_offset;
342 err = pohmelfs_recv(t, recv, data, size);
343 if (err < 0)
344 goto err_out_exit;
346 dnet_convert_io_attr(&t->cmd.p.io);
349 while (t->recv_offset != cmd->size) {
350 offset = (t->recv_offset - asize) & (PAGE_CACHE_SIZE - 1);
351 size = PAGE_CACHE_SIZE - offset;
352 page = rp->pages[rp->page_index];
354 if (size > cmd->size - t->recv_offset)
355 size = cmd->size - t->recv_offset;
357 data = kmap(page);
358 err = pohmelfs_recv(t, recv, data + offset, size);
359 kunmap(page);
361 if (err > 0 && ((err + offset == PAGE_CACHE_SIZE) || (t->recv_offset == cmd->size))) {
362 rp->page_index++;
365 if (err < 0)
366 goto err_out_exit;
368 atomic_long_add(err, &wait->count);
371 err = 0;
373 err_out_exit:
374 if ((err < 0) && (err != -ENOENT) && (err != -EAGAIN))
375 pr_info("pohmelfs: %d:%s: pohmelfs_readpages_recv_data: offset: %lld, data size: %llu, err: %d\n",
376 cmd->id.group_id, pohmelfs_dump_id(pi->id.id), t->recv_offset - asize + t->cmd.p.io.offset,
377 (unsigned long long)cmd->size - asize, err);
379 return err;
382 static int pohmelfs_readpages_group(struct pohmelfs_inode *pi, struct pohmelfs_readpages_priv *rp, int group_id)
384 struct pohmelfs_sb *psb = pohmelfs_sb(pi->vfs_inode.i_sb);
385 struct pohmelfs_wait *wait = &rp->wait;
386 struct pohmelfs_io *io;
387 long ret;
388 int err;
390 io = kmem_cache_zalloc(pohmelfs_io_cache, GFP_NOIO);
391 if (!io) {
392 err = -ENOMEM;
393 goto err_out_exit;
396 io->pi = pi;
397 io->id = &pi->id;
398 io->cmd = DNET_CMD_READ;
399 io->cflags = DNET_FLAGS_NEED_ACK | DNET_FLAGS_NOLOCK;
400 io->offset = page_offset(rp->pages[0]);
401 io->size = rp->page_num * PAGE_CACHE_SIZE;
402 if (psb->no_read_csum)
403 io->ioflags = DNET_IO_FLAGS_NOCSUM;
404 io->cb.init = pohmelfs_readpages_init;
405 io->cb.complete = pohmelfs_readpages_complete;
406 io->cb.destroy = pohmelfs_readpages_destroy;
407 io->cb.recv_reply = pohmelfs_readpages_recv_reply;
408 io->priv = rp;
410 err = pohmelfs_send_io_group(io, group_id);
411 if (err)
412 goto err_out_free;
414 ret = wait_event_interruptible_timeout(wait->wq, wait->condition != 0, msecs_to_jiffies(psb->read_wait_timeout));
415 if (ret <= 0) {
416 err = ret;
417 if (ret == 0)
418 err = -ETIMEDOUT;
419 goto err_out_free;
422 if (wait->condition < 0) {
423 err = wait->condition;
424 goto err_out_free;
427 err = atomic_long_read(&wait->count);
429 err_out_free:
430 kmem_cache_free(pohmelfs_io_cache, io);
431 err_out_exit:
432 return err;
435 static int pohmelfs_readpages_groups(struct pohmelfs_inode *pi, struct pohmelfs_readpages_priv *rp,
436 int *groups, int group_num)
438 int err = -ENOENT;
439 int i;
441 for (i = 0; i < group_num; ++i) {
442 err = pohmelfs_readpages_group(pi, rp, groups[i]);
443 if (err < 0)
444 continue;
446 break;
449 pi->update = get_seconds();
450 return err;
453 static struct pohmelfs_readpages_priv *pohmelfs_readpages_alloc(struct pohmelfs_inode *pi, int page_num)
455 struct pohmelfs_readpages_priv *rp;
456 int err;
458 rp = kzalloc(sizeof(struct pohmelfs_readpages_priv) + page_num * sizeof(struct page *), GFP_NOIO);
459 if (!rp) {
460 err = -ENOMEM;
461 goto err_out_exit;
464 err = pohmelfs_wait_init(&rp->wait, pi);
465 if (err)
466 goto err_out_free;
468 rp->page_num = page_num;
469 kref_init(&rp->refcnt);
470 return rp;
472 err_out_free:
473 kfree(rp);
474 err_out_exit:
475 return ERR_PTR(err);
478 static int pohmelfs_readpages_send(struct pohmelfs_inode *pi, struct pohmelfs_readpages_priv *rp)
480 struct pohmelfs_sb *psb = pohmelfs_sb(pi->vfs_inode.i_sb);
481 int err;
483 if (pi->group_num) {
484 err = pohmelfs_readpages_groups(pi, rp, pi->groups, pi->group_num);
485 } else {
486 err = pohmelfs_readpages_groups(pi, rp, psb->groups, psb->group_num);
489 return err;
492 static int pohmelfs_readpages_send_list(struct address_space *mapping, struct list_head *page_list, int num)
494 struct inode *inode = mapping->host;
495 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
496 int err = 0, i;
497 struct pohmelfs_readpages_priv *rp;
498 struct page *tmp, *page;
500 if (list_empty(page_list))
501 goto err_out_exit;
503 rp = pohmelfs_readpages_alloc(pi, num);
504 if (IS_ERR(rp)) {
505 err = PTR_ERR(rp);
506 goto err_out_exit;
509 i = 0;
510 list_for_each_entry_safe(page, tmp, page_list, lru) {
511 list_del(&page->lru);
513 if (add_to_page_cache_lru(page, mapping, page->index, GFP_KERNEL)) {
514 /* Failed - free current page, optionally send already grabbed and free others */
515 page_cache_release(page);
516 break;
519 rp->pages[i] = page;
520 i++;
523 if (i > 0) {
524 rp->page_num = i;
525 err = pohmelfs_readpages_send(pi, rp);
527 pr_debug("pohmelfs: %s: readpages: ino: %lu, offset: %lu, pages: %u/%u: %d\n",
528 pohmelfs_dump_id(pi->id.id), inode->i_ino, (long)page_offset(rp->pages[0]), rp->page_num, num, err);
531 kref_put(&rp->refcnt, pohmelfs_readpages_free);
533 /* Cleanup pages which were not added into page cache */
534 list_for_each_entry_safe(page, tmp, page_list, lru) {
535 list_del(&page->lru);
536 page_cache_release(page);
539 err_out_exit:
540 return err;
543 static int pohmelfs_readpages(struct file *filp, struct address_space *mapping,
544 struct list_head *page_list, unsigned nr_pages)
546 struct page *tmp, *page;
547 pgoff_t idx;
548 LIST_HEAD(head);
549 int err = 0, i = 0;
551 while (!list_empty(page_list)) {
552 page = list_entry(page_list->prev, struct page, lru);
553 idx = page->index;
554 i = 0;
556 list_for_each_entry_safe_reverse(page, tmp, page_list, lru) {
557 if (idx != page->index)
558 break;
560 list_move(&page->lru, &head);
561 i++;
564 err = pohmelfs_readpages_send_list(mapping, &head, i);
566 if (err >= 0)
567 err = 0;
569 return err;
572 static int pohmelfs_readpage(struct file *file, struct page *page)
574 struct inode *inode = page->mapping->host;
575 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
576 struct pohmelfs_readpages_priv *rp;
577 int err;
579 if (inode->i_size <= page->index << PAGE_CACHE_SHIFT) {
580 SetPageUptodate(page);
581 unlock_page(page);
582 return 0;
585 rp = pohmelfs_readpages_alloc(pi, 1);
586 if (IS_ERR(rp)) {
587 err = PTR_ERR(rp);
588 goto err_out_exit;
591 rp->pages[0] = page;
592 page_cache_get(page);
594 err = pohmelfs_readpages_send(pi, rp);
595 pr_err("pohmelfs: %s: readpage: ino: %lu, offset: %lu, uptodate: %d, err: %d\n",
596 pohmelfs_dump_id(pi->id.id), inode->i_ino, (long)page_offset(page),
597 PageUptodate(page), err);
599 if (err >= 0)
600 err = 0;
602 kref_put(&rp->refcnt, pohmelfs_readpages_free);
603 err_out_exit:
604 return err;
607 void pohmelfs_write_ctl_release(struct kref *kref)
609 struct pohmelfs_write_ctl *ctl = container_of(kref, struct pohmelfs_write_ctl, refcnt);
610 struct address_space *mapping = ctl->pvec.pages[0]->mapping;
611 struct inode *inode = mapping->host;
612 struct pohmelfs_sb *psb = pohmelfs_sb(inode->i_sb);
613 int bad_write = atomic_read(&ctl->good_writes) < psb->group_num / 2 + 1;
614 struct page *page;
615 unsigned int i;
617 if (psb->successful_write_count && (atomic_read(&ctl->good_writes) >= psb->successful_write_count))
618 bad_write = 0;
620 if (bad_write) {
621 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
622 unsigned long long offset = page_offset(ctl->pvec.pages[0]);
624 pr_debug("pohmelfs: %s: bad write: ino: %lu, isize: %llu, offset: %llu: writes: %d/%d\n",
625 pohmelfs_dump_id(pi->id.id),
626 inode->i_ino, inode->i_size, offset,
627 atomic_read(&ctl->good_writes), psb->group_num);
628 mapping_set_error(mapping, -EIO);
631 for (i = 0; i < pagevec_count(&ctl->pvec); ++i) {
632 page = ctl->pvec.pages[i];
634 if (PageLocked(page)) {
635 end_page_writeback(page);
637 if (bad_write) {
638 SetPageError(page);
639 ClearPageUptodate(page);
641 * Do not reschedule failed write page again
642 * This may explode systems with large caches
643 * when there is no connection to elliptics cluster
645 //set_page_dirty(page);
647 unlock_page(page);
651 pagevec_release(&ctl->pvec);
652 kmem_cache_free(pohmelfs_write_cache, ctl);
655 static int pohmelfs_writepages_chunk(struct pohmelfs_inode *pi, struct pohmelfs_write_ctl *ctl,
656 struct writeback_control *wbc, struct address_space *mapping)
658 struct inode *inode = &pi->vfs_inode;
659 uint64_t offset, size;
660 unsigned i;
661 int err = 0, good = 0;
663 offset = page_offset(ctl->pvec.pages[0]);
665 size = 0;
666 /* we will lookup them again when doing actual send */
667 for (i = 0; i< pagevec_count(&ctl->pvec); ++i) {
668 struct page *page = ctl->pvec.pages[i];
670 lock_page(page);
671 #if 1
672 if (unlikely(page->mapping != mapping)) {
673 continue_unlock:
674 unlock_page(page);
675 continue;
678 if (wbc->sync_mode != WB_SYNC_NONE)
679 wait_on_page_writeback(page);
680 if (PageWriteback(page)) {
681 unlock_page(page);
682 break;
685 if (!PageDirty(page))
686 goto continue_unlock;
688 if (!clear_page_dirty_for_io(page))
689 goto continue_unlock;
690 #else
691 clear_page_dirty_for_io(page);
692 #endif
694 set_page_writeback(page);
696 good++;
697 size += PAGE_CACHE_SIZE;
698 wbc->nr_to_write--;
701 if (good != 0) {
702 size = pagevec_count(&ctl->pvec) * PAGE_CACHE_SIZE;
703 if (offset + size > inode->i_size)
704 size = inode->i_size - offset;
706 err = pohmelfs_write_command(pi, ctl, offset, size);
707 if (err)
708 goto err_out_exit;
711 err_out_exit:
712 kref_put(&ctl->refcnt, pohmelfs_write_ctl_release);
713 return err;
716 static int pohmelfs_writepages_send(struct address_space *mapping, struct writeback_control *wbc, struct pagevec *pvec, int start, int end)
718 struct inode *inode = mapping->host;
719 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
720 struct pohmelfs_write_ctl *ctl;
721 int err, i;
723 ctl = kmem_cache_zalloc(pohmelfs_write_cache, GFP_NOIO);
724 if (!ctl) {
725 err = -ENOMEM;
726 goto err_out_exit;
729 kref_init(&ctl->refcnt);
730 atomic_set(&ctl->good_writes, 0);
732 for (i = start; i < end; ++i)
733 pagevec_add(&ctl->pvec, pvec->pages[i]);
735 err = pohmelfs_writepages_chunk(pi, ctl, wbc, mapping);
736 if (err)
737 goto err_out_exit;
739 err_out_exit:
740 return err;
743 static int pohmelfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
745 struct inode *inode = mapping->host;
746 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
747 pgoff_t index, start, end /* inclusive */, idx;
748 int done = 0;
749 int range_whole = 0;
750 int should_loop = 1;
751 int nr_pages, err = 0, i, start_idx;
752 struct pagevec pvec;
754 index = wbc->range_start >> PAGE_CACHE_SHIFT;
755 end = wbc->range_end >> PAGE_CACHE_SHIFT;
757 pr_debug("pohmelfs: %s: writepages: ino: %ld, nr: %ld, index: %llu, end: %llu, total_size: %lu, sync: %d\n",
758 pohmelfs_dump_id(pohmelfs_inode(inode)->id.id), inode->i_ino,
759 wbc->nr_to_write, wbc->range_start, wbc->range_end, (unsigned long)inode->i_size, wbc->sync_mode);
761 if (wbc->range_cyclic) {
762 start = mapping->writeback_index; /* Start from prev offset */
763 end = -1;
764 } else {
765 start = wbc->range_start >> PAGE_CACHE_SHIFT;
766 end = wbc->range_end >> PAGE_CACHE_SHIFT;
767 if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
768 range_whole = 1;
769 should_loop = 0;
771 index = start;
773 retry:
774 while (!done && index <= end) {
775 nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
776 min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
777 if (!nr_pages) {
778 err = 0;
779 break;
782 idx = pvec.pages[0]->index;
783 for (start_idx = 0, i = 0; i< nr_pages; ++i) {
784 struct page *page = pvec.pages[i];
786 /* non-contiguous pages detected */
787 if (idx != page->index) {
788 err = pohmelfs_writepages_send(mapping, wbc, &pvec, start_idx, i);
789 if (err)
790 goto err_out_exit;
791 start_idx = i;
794 idx++;
797 err = pohmelfs_writepages_send(mapping, wbc, &pvec, start_idx, nr_pages);
798 if (err)
799 goto err_out_exit;
801 if (wbc->nr_to_write <= 0)
802 done = 1;
805 if (should_loop && !done) {
806 /* more to do; loop back to beginning of file */
807 should_loop = 0;
808 index = 0;
809 goto retry;
812 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
813 mapping->writeback_index = index;
815 err = pohmelfs_metadata_inode(pi, wbc->sync_mode != WB_SYNC_NONE);
816 if (err)
817 goto err_out_exit;
820 if (test_and_clear_bit(AS_EIO, &mapping->flags))
821 err = -EIO;
822 err_out_exit:
823 pr_debug("pohmelfs: %s: metadata write complete: %d\n", pohmelfs_dump_id(pi->id.id), err);
824 return err;
827 static const struct address_space_operations pohmelfs_aops = {
828 .write_begin = simple_write_begin,
829 .write_end = simple_write_end,
830 .writepages = pohmelfs_writepages,
831 .readpage = pohmelfs_readpage,
832 .readpages = pohmelfs_readpages,
833 .set_page_dirty = __set_page_dirty_nobuffers,
836 void pohmelfs_convert_inode_info(struct pohmelfs_inode_info *info)
838 info->ino = cpu_to_le64(info->ino);
839 info->mode = cpu_to_le64(info->mode);
840 info->nlink = cpu_to_le64(info->nlink);
841 info->uid = cpu_to_le32(info->uid);
842 info->gid = cpu_to_le32(info->gid);
843 info->namelen = cpu_to_le32(info->namelen);
844 info->blocks = cpu_to_le64(info->blocks);
845 info->rdev = cpu_to_le64(info->rdev);
846 info->size = cpu_to_le64(info->size);
847 info->version = cpu_to_le64(info->version);
848 info->blocksize = cpu_to_le64(info->blocksize);
849 info->flags = cpu_to_le64(info->flags);
851 dnet_convert_time(&info->ctime);
852 dnet_convert_time(&info->mtime);
853 dnet_convert_time(&info->atime);
856 void pohmelfs_fill_inode_info(struct inode *inode, struct pohmelfs_inode_info *info)
858 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
860 memcpy(info->id.id, pi->id.id, DNET_ID_SIZE);
862 info->ino = inode->i_ino;
863 info->mode = inode->i_mode;
864 info->nlink = inode->i_nlink;
865 info->uid = inode->i_uid;
866 info->gid = inode->i_gid;
867 info->blocks = inode->i_blocks;
868 info->rdev = inode->i_rdev;
869 info->size = inode->i_size;
870 info->version = inode->i_version;
871 info->blocksize = 1 << inode->i_blkbits;
873 info->ctime.tsec = inode->i_ctime.tv_sec;
874 info->ctime.tnsec = inode->i_ctime.tv_nsec;
876 info->mtime.tsec = inode->i_mtime.tv_sec;
877 info->mtime.tnsec = inode->i_mtime.tv_nsec;
879 info->atime.tsec = inode->i_atime.tv_sec;
880 info->atime.tnsec = inode->i_atime.tv_nsec;
882 info->flags = 0;
885 void pohmelfs_fill_inode(struct inode *inode, struct pohmelfs_inode_info *info)
887 pr_debug("pohmelfs: %s: ino: %lu inode is regular: %d, dir: %d, link: %d, mode: %o, "
888 "namelen: %u, size: %llu, state: %lx, mtime: %llu.%llu/%lu.%lu\n",
889 pohmelfs_dump_id(info->id.id), inode->i_ino,
890 S_ISREG(inode->i_mode), S_ISDIR(inode->i_mode),
891 S_ISLNK(inode->i_mode), inode->i_mode, info->namelen, inode->i_size, inode->i_state,
892 (unsigned long long)info->mtime.tsec, (unsigned long long)info->mtime.tnsec,
893 inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec);
895 if (info->mtime.tsec < inode->i_mtime.tv_sec)
896 return;
897 if ((info->mtime.tsec == inode->i_mtime.tv_sec) &&
898 (info->mtime.tnsec < inode->i_mtime.tv_nsec))
899 return;
901 pohmelfs_inode(inode)->id = info->id;
903 inode->i_mode = info->mode;
904 set_nlink(inode, info->nlink);
905 inode->i_uid = info->uid;
906 inode->i_gid = info->gid;
907 inode->i_blocks = info->blocks;
908 inode->i_rdev = info->rdev;
909 inode->i_size = info->size;
910 inode->i_version = info->version;
911 inode->i_blkbits = ffs(info->blocksize);
913 inode->i_mtime = pohmelfs_date(&info->mtime);
914 inode->i_atime = pohmelfs_date(&info->atime);
915 inode->i_ctime = pohmelfs_date(&info->ctime);
918 static void pohmelfs_inode_info_current(struct pohmelfs_sb *psb, struct pohmelfs_inode_info *info)
920 struct timespec ts = CURRENT_TIME;
921 struct dnet_time dtime;
923 info->nlink = S_ISDIR(info->mode) ? 2 : 1;
924 info->uid = current_fsuid();
925 info->gid = current_fsgid();
926 info->size = 0;
927 info->blocksize = PAGE_SIZE;
928 info->blocks = 0;
929 info->rdev = 0;
930 info->version = 0;
932 dtime.tsec = ts.tv_sec;
933 dtime.tnsec = ts.tv_nsec;
935 info->ctime = dtime;
936 info->mtime = dtime;
937 info->atime = dtime;
939 pohmelfs_gen_id(psb, &info->id);
942 const struct inode_operations pohmelfs_special_inode_operations = {
943 .setattr = simple_setattr,
946 struct pohmelfs_inode *pohmelfs_existing_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode_info *info)
948 struct pohmelfs_inode *pi;
949 struct inode *inode;
950 int err;
952 inode = iget_locked(psb->sb, atomic_long_inc_return(&psb->ino));
953 if (!inode) {
954 err = -ENOMEM;
955 goto err_out_exit;
958 pi = pohmelfs_inode(inode);
960 if (inode->i_state & I_NEW) {
961 pohmelfs_fill_inode(inode, info);
963 * i_mapping is a pointer to i_data during inode initialization.
965 inode->i_data.a_ops = &pohmelfs_aops;
967 if (S_ISREG(inode->i_mode)) {
968 inode->i_fop = &pohmelfs_file_ops;
969 inode->i_op = &pohmelfs_file_inode_operations;
970 } else if (S_ISDIR(inode->i_mode)) {
971 inode->i_fop = &pohmelfs_dir_fops;
972 inode->i_op = &pohmelfs_dir_inode_operations;
973 } else if (S_ISLNK(inode->i_mode)) {
974 inode->i_op = &pohmelfs_symlink_inode_operations;
975 inode->i_mapping->a_ops = &pohmelfs_aops;
976 } else {
977 inode->i_op = &pohmelfs_special_inode_operations;
980 err = pohmelfs_sb_inode_insert(psb, pi);
981 if (err)
982 goto err_out_put;
984 unlock_new_inode(inode);
987 return pi;
989 err_out_put:
990 unlock_new_inode(inode);
991 iput(inode);
992 err_out_exit:
993 return ERR_PTR(err);
996 struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb, int mode)
998 struct pohmelfs_inode *pi;
999 struct pohmelfs_inode_info *info;
1000 int err;
1002 info = kmem_cache_zalloc(pohmelfs_inode_info_cache, GFP_NOIO);
1003 if (!info) {
1004 err = -ENOMEM;
1005 goto err_out_exit;
1008 info->mode = mode;
1010 pohmelfs_inode_info_current(psb, info);
1012 pi = pohmelfs_existing_inode(psb, info);
1013 if (IS_ERR(pi)) {
1014 err = PTR_ERR(pi);
1015 goto err_out_free;
1018 kmem_cache_free(pohmelfs_inode_info_cache, info);
1019 return pi;
1021 err_out_free:
1022 kmem_cache_free(pohmelfs_inode_info_cache, info);
1023 err_out_exit:
1024 return ERR_PTR(err);
1027 int pohmelfs_wait_init(struct pohmelfs_wait *wait, struct pohmelfs_inode *pi)
1029 if (!igrab(&pi->vfs_inode))
1030 return -EINVAL;
1032 wait->pi = pi;
1034 atomic_long_set(&wait->count, 0);
1035 init_waitqueue_head(&wait->wq);
1036 kref_init(&wait->refcnt);
1038 return 0;
1041 struct pohmelfs_wait *pohmelfs_wait_alloc(struct pohmelfs_inode *pi)
1043 struct pohmelfs_wait *wait;
1045 wait = kmem_cache_zalloc(pohmelfs_wait_cache, GFP_NOIO);
1046 if (!wait) {
1047 goto err_out_exit;
1050 if (pohmelfs_wait_init(wait, pi))
1051 goto err_out_free;
1053 return wait;
1055 err_out_free:
1056 kmem_cache_free(pohmelfs_wait_cache, wait);
1057 err_out_exit:
1058 return NULL;
1061 static void pohmelfs_wait_free(struct kref *kref)
1063 struct pohmelfs_wait *wait = container_of(kref, struct pohmelfs_wait, refcnt);
1064 struct inode *inode = &wait->pi->vfs_inode;
1066 iput(inode);
1067 kmem_cache_free(pohmelfs_wait_cache, wait);
1070 void pohmelfs_wait_put(struct pohmelfs_wait *wait)
1072 kref_put(&wait->refcnt, pohmelfs_wait_free);