pohmelfs: Use current logging styles.
[pohmelfs.git] / fs / pohmelfs / inode.c
blob5c73d943b91c9d3b031d16d9f1dd0338248ca697
1 /*
2 * Copyright (C) 2011+ Evgeniy Polyakov <zbr@ioremap.net>
3 */
5 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7 #include <linux/buffer_head.h>
8 #include <linux/cred.h>
9 #include <linux/fiemap.h>
10 #include <linux/fs.h>
11 #include <linux/fs_struct.h>
12 #include <linux/mpage.h>
13 #include <linux/mount.h>
14 #include <linux/mm.h>
15 #include <linux/namei.h>
16 #include <linux/pagevec.h>
17 #include <linux/pagemap.h>
18 #include <linux/random.h>
19 #include <linux/scatterlist.h>
20 #include <linux/slab.h>
21 #include <linux/time.h>
22 #include <linux/writeback.h>
24 #include "pohmelfs.h"
26 char *pohmelfs_dump_id_len_raw(const unsigned char *id, unsigned int len, char *dst)
28 unsigned int i;
30 if (len > SHA512_DIGEST_SIZE)
31 len = SHA512_DIGEST_SIZE;
33 for (i=0; i<len; ++i)
34 sprintf(&dst[2*i], "%02x", id[i]);
35 return dst;
38 #define pohmelfs_dump_len 6
39 typedef struct {
40 char id_str[pohmelfs_dump_len * 2 + 1];
41 } pohmelfs_dump_t;
42 static DEFINE_PER_CPU(pohmelfs_dump_t, pohmelfs_dump_per_cpu);
44 char *pohmelfs_dump_id(const unsigned char *id)
46 pohmelfs_dump_t *ptr;
48 ptr = &get_cpu_var(pohmelfs_dump_per_cpu);
49 pohmelfs_dump_id_len_raw(id, pohmelfs_dump_len, ptr->id_str);
50 put_cpu_var(ptr);
52 return ptr->id_str;
55 #define dnet_raw_id_scratch 6
56 typedef struct {
57 unsigned long rand;
58 struct timespec ts;
59 } dnet_raw_id_scratch_t;
60 static DEFINE_PER_CPU(dnet_raw_id_scratch_t, dnet_raw_id_scratch_per_cpu);
62 static int pohmelfs_gen_id(struct pohmelfs_sb *psb, struct dnet_raw_id *id)
64 dnet_raw_id_scratch_t *sc;
65 int err;
66 long rand;
68 get_random_bytes(&rand, sizeof(sc->rand));
70 sc = &get_cpu_var(dnet_raw_id_scratch_per_cpu);
71 sc->rand ^= rand;
72 sc->ts = CURRENT_TIME;
74 err = pohmelfs_hash(psb, sc, sizeof(dnet_raw_id_scratch_t), id);
75 put_cpu_var(sc);
77 return err;
80 #define UNHASHED_OBSCURE_STRING_SIZE sizeof(" (deleted)")
83 * Create path from root for given inode.
84 * Path is formed as set of stuctures, containing name of the object
85 * and its inode data (mode, permissions and so on).
87 static int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len)
89 struct path path;
90 struct dentry *d;
91 char *ptr;
92 int err = 0, strlen, reduce = 0;
94 d = d_find_alias(&pi->vfs_inode);
95 if (!d) {
96 err = -ENOENT;
97 goto err_out_exit;
100 spin_lock(&current->fs->lock);
101 path.mnt = mntget(current->fs->root.mnt);
102 spin_unlock(&current->fs->lock);
104 path.dentry = d;
106 if (!IS_ROOT(d) && d_unhashed(d))
107 reduce = 1;
109 ptr = d_path(&path, data, len);
110 if (IS_ERR(ptr)) {
111 err = PTR_ERR(ptr);
112 goto err_out_put;
115 if (reduce && len >= UNHASHED_OBSCURE_STRING_SIZE) {
116 char *end = data + len - UNHASHED_OBSCURE_STRING_SIZE;
117 *end = '\0';
120 strlen = len - (ptr - (char *)data);
121 memmove(data, ptr, strlen);
122 ptr = data;
124 err = strlen - 1; /* no including 0-byte */
126 pr_debug("dname: '%s', len: %u, maxlen: %u, name: '%s', strlen: %d\n",
127 d->d_name.name, d->d_name.len, len, ptr, strlen);
129 err_out_put:
130 dput(d);
131 mntput(path.mnt);
132 err_out_exit:
133 return err;
136 int pohmelfs_http_compat_id(struct pohmelfs_inode *pi)
138 struct pohmelfs_sb *psb = pohmelfs_sb(pi->vfs_inode.i_sb);
139 struct timespec ts = CURRENT_TIME;
140 int idx = ts.tv_nsec % psb->http_compat;
141 struct pohmelfs_path *p = &psb->path[idx];
142 int err;
144 mutex_lock(&p->lock);
145 err = pohmelfs_construct_path_string(pi, p->data, PAGE_SIZE);
146 if (err > 0) {
147 pohmelfs_hash(psb, p->data, err, &pi->id);
149 mutex_unlock(&p->lock);
151 return err;
154 static int pohmelfs_sb_inode_insert(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi)
156 struct rb_node **n = &psb->inode_root.rb_node, *parent = NULL;
157 struct pohmelfs_inode *tmp;
158 int cmp, err = 0;
160 spin_lock(&psb->inode_lock);
161 while (*n) {
162 parent = *n;
164 tmp = rb_entry(parent, struct pohmelfs_inode, node);
166 cmp = dnet_id_cmp_str(tmp->id.id, pi->id.id);
167 if (cmp < 0)
168 n = &parent->rb_left;
169 else if (cmp > 0)
170 n = &parent->rb_right;
171 else {
172 err = -EEXIST;
173 goto err_out_unlock;
177 rb_link_node(&pi->node, parent, n);
178 rb_insert_color(&pi->node, &psb->inode_root);
180 err_out_unlock:
181 spin_unlock(&psb->inode_lock);
183 return err;
186 struct pohmelfs_inode *pohmelfs_sb_inode_lookup(struct pohmelfs_sb *psb, struct dnet_raw_id *id)
188 struct rb_node *n = psb->inode_root.rb_node;
189 struct pohmelfs_inode *pi, *found = NULL;
190 int cmp;
192 spin_lock(&psb->inode_lock);
193 while (n) {
194 pi = rb_entry(n, struct pohmelfs_inode, node);
196 cmp = dnet_id_cmp_str(pi->id.id, id->id);
197 if (cmp < 0) {
198 n = n->rb_left;
199 } else if (cmp > 0)
200 n = n->rb_right;
201 else {
202 found = pi;
203 break;
206 if (found) {
207 if (!igrab(&found->vfs_inode))
208 found = NULL;
210 spin_unlock(&psb->inode_lock);
212 return found;
215 struct inode *pohmelfs_alloc_inode(struct super_block *sb)
217 struct pohmelfs_inode *pi;
219 pi = kmem_cache_zalloc(pohmelfs_inode_cache, GFP_NOIO);
220 if (!pi)
221 goto err_out_exit;
223 inode_init_once(&pi->vfs_inode);
225 rb_init_node(&pi->node);
226 mutex_init(&pi->lock);
228 return &pi->vfs_inode;
230 err_out_exit:
231 return NULL;
234 void pohmelfs_destroy_inode(struct inode *inode)
236 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
238 pr_debug("%s: ino: %ld, dirty: %lx\n",
239 pohmelfs_dump_id(pi->id.id), inode->i_ino,
240 inode->i_state & I_DIRTY);
242 kfree(pi->groups);
243 kmem_cache_free(pohmelfs_inode_cache, pi);
246 int pohmelfs_hash(struct pohmelfs_sb *psb, const void *data, const size_t size, struct dnet_raw_id *id)
248 struct scatterlist sg;
249 struct hash_desc desc;
251 sg_init_table(&sg, 1);
252 sg_set_buf(&sg, data, size);
254 desc.tfm = psb->hash;
255 desc.flags = 0;
257 return crypto_hash_digest(&desc, &sg, size, id->id);
260 struct pohmelfs_readpages_priv {
261 struct pohmelfs_wait wait;
262 struct kref refcnt;
263 int page_num, page_index;
264 struct page *pages[0];
267 static void pohmelfs_readpages_free(struct kref *kref)
269 struct pohmelfs_readpages_priv *rp = container_of(kref, struct pohmelfs_readpages_priv, refcnt);
270 struct pohmelfs_inode *pi = rp->wait.pi;
271 int i;
273 pr_debug("%s: read: %ld/%ld, wait: %d\n",
274 pohmelfs_dump_id(pi->id.id), atomic_long_read(&rp->wait.count),
275 rp->page_num * PAGE_CACHE_SIZE, rp->wait.condition);
277 for (i = 0; i < rp->page_num; ++i) {
278 struct page *page = rp->pages[i];
280 flush_dcache_page(page);
281 SetPageUptodate(page);
282 unlock_page(page);
283 page_cache_release(page);
286 iput(&rp->wait.pi->vfs_inode);
287 kfree(rp);
290 static void pohmelfs_readpages_destroy(struct pohmelfs_trans *t)
292 struct pohmelfs_readpages_priv *rp = t->priv;
293 struct pohmelfs_wait *wait = &rp->wait;
295 if (!wait->condition)
296 wait->condition = 1;
298 wake_up(&wait->wq);
299 kref_put(&rp->refcnt, pohmelfs_readpages_free);
302 static int pohmelfs_readpages_complete(struct pohmelfs_trans *t, struct pohmelfs_state *recv)
304 struct pohmelfs_readpages_priv *rp = t->priv;
305 struct pohmelfs_wait *wait = &rp->wait;
306 struct dnet_cmd *cmd = &recv->cmd;
308 if (!(cmd->flags & DNET_FLAGS_MORE)) {
309 if (!wait->condition) {
310 wait->condition = cmd->status;
311 if (!wait->condition)
312 wait->condition = 1;
313 wake_up(&rp->wait.wq);
317 pr_debug("%d:%s: read: %ld, wait: %d\n",
318 cmd->id.group_id, pohmelfs_dump_id(wait->pi->id.id),
319 atomic_long_read(&wait->count), wait->condition);
321 return 0;
324 static int pohmelfs_readpages_init(struct pohmelfs_trans *t)
326 struct pohmelfs_readpages_priv *rp = t->priv;
328 kref_get(&rp->refcnt);
329 return 0;
332 static int pohmelfs_readpages_recv_reply(struct pohmelfs_trans *t, struct pohmelfs_state *recv)
334 struct pohmelfs_readpages_priv *rp = t->priv;
335 struct pohmelfs_wait *wait = &rp->wait;
336 struct pohmelfs_inode *pi = wait->pi;
337 unsigned int asize = sizeof(struct dnet_attr) + sizeof(struct dnet_io_attr);
338 void *data = &t->cmd.attr; /* overwrite send buffer used for attr/ioattr */
339 struct dnet_cmd *cmd = &recv->cmd;
340 struct page *page;
341 pgoff_t offset;
342 int err, size;
344 if (t->io_offset < asize) {
345 size = asize - t->io_offset;
346 data += t->io_offset;
347 err = pohmelfs_recv(t, recv, data, size);
348 if (err < 0)
349 goto err_out_exit;
351 dnet_convert_io_attr(&t->cmd.p.io);
354 while (t->io_offset != cmd->size) {
355 offset = (t->io_offset - asize) & (PAGE_CACHE_SIZE - 1);
356 size = PAGE_CACHE_SIZE - offset;
357 page = rp->pages[rp->page_index];
359 if (size > cmd->size - t->io_offset)
360 size = cmd->size - t->io_offset;
362 data = kmap(page);
363 err = pohmelfs_recv(t, recv, data + offset, size);
364 kunmap(page);
366 if (err > 0 && ((err + offset == PAGE_CACHE_SIZE) || (t->io_offset == cmd->size))) {
367 rp->page_index++;
370 if (err < 0)
371 goto err_out_exit;
373 atomic_long_add(err, &wait->count);
376 err = 0;
378 err_out_exit:
379 if ((err < 0) && (err != -ENOENT) && (err != -EAGAIN))
380 pr_err("%d:%s: offset: %lld, data size: %llu, err: %d\n",
381 cmd->id.group_id, pohmelfs_dump_id(pi->id.id),
382 t->io_offset - asize + t->cmd.p.io.offset,
383 (unsigned long long)cmd->size - asize, err);
385 return err;
388 static int pohmelfs_readpages_group(struct pohmelfs_inode *pi, struct pohmelfs_readpages_priv *rp, int group_id)
390 struct pohmelfs_sb *psb = pohmelfs_sb(pi->vfs_inode.i_sb);
391 struct pohmelfs_wait *wait = &rp->wait;
392 struct pohmelfs_io *io;
393 long ret;
394 int err;
396 io = kmem_cache_zalloc(pohmelfs_io_cache, GFP_NOIO);
397 if (!io) {
398 err = -ENOMEM;
399 goto err_out_exit;
402 io->pi = pi;
403 io->id = &pi->id;
404 io->cmd = DNET_CMD_READ;
406 * We send read command with lock, so its will be picked by the same threads as process
407 * bulk write commands leaving nonblocking threads free for metadata commands like
408 * directory reading, lookup and so on
410 //io->cflags = DNET_FLAGS_NEED_ACK | DNET_FLAGS_NOLOCK;
411 io->cflags = DNET_FLAGS_NEED_ACK;
412 io->offset = page_offset(rp->pages[0]);
413 io->size = rp->page_num * PAGE_CACHE_SIZE;
414 if (psb->no_read_csum)
415 io->ioflags = DNET_IO_FLAGS_NOCSUM;
416 io->cb.init = pohmelfs_readpages_init;
417 io->cb.complete = pohmelfs_readpages_complete;
418 io->cb.destroy = pohmelfs_readpages_destroy;
419 io->cb.recv_reply = pohmelfs_readpages_recv_reply;
420 io->priv = rp;
422 err = pohmelfs_send_io_group(io, group_id);
423 if (err)
424 goto err_out_free;
426 ret = wait_event_interruptible_timeout(wait->wq, wait->condition != 0, msecs_to_jiffies(psb->read_wait_timeout));
427 if (ret <= 0) {
428 err = ret;
429 if (ret == 0)
430 err = -ETIMEDOUT;
431 goto err_out_free;
434 if (wait->condition < 0) {
435 err = wait->condition;
436 goto err_out_free;
439 err = atomic_long_read(&wait->count);
441 err_out_free:
442 kmem_cache_free(pohmelfs_io_cache, io);
443 err_out_exit:
444 return err;
447 static int pohmelfs_readpages_groups(struct pohmelfs_inode *pi, struct pohmelfs_readpages_priv *rp,
448 int *groups, int group_num)
450 int err = -ENOENT;
451 int i;
453 for (i = 0; i < group_num; ++i) {
454 err = pohmelfs_readpages_group(pi, rp, groups[i]);
455 if (err < 0)
456 continue;
458 break;
461 pi->update = get_seconds();
462 return err;
465 static struct pohmelfs_readpages_priv *pohmelfs_readpages_alloc(struct pohmelfs_inode *pi, int page_num)
467 struct pohmelfs_readpages_priv *rp;
468 int err;
470 rp = kzalloc(sizeof(struct pohmelfs_readpages_priv) + page_num * sizeof(struct page *), GFP_NOIO);
471 if (!rp) {
472 err = -ENOMEM;
473 goto err_out_exit;
476 err = pohmelfs_wait_init(&rp->wait, pi);
477 if (err)
478 goto err_out_free;
480 rp->page_num = page_num;
481 kref_init(&rp->refcnt);
482 return rp;
484 err_out_free:
485 kfree(rp);
486 err_out_exit:
487 return ERR_PTR(err);
490 static int pohmelfs_readpages_send(struct pohmelfs_inode *pi, struct pohmelfs_readpages_priv *rp)
492 struct pohmelfs_sb *psb = pohmelfs_sb(pi->vfs_inode.i_sb);
493 int err;
495 if (pi->group_num) {
496 err = pohmelfs_readpages_groups(pi, rp, pi->groups, pi->group_num);
497 } else {
498 err = pohmelfs_readpages_groups(pi, rp, psb->groups, psb->group_num);
501 return err;
504 static int pohmelfs_readpages_send_list(struct address_space *mapping, struct list_head *page_list, int num)
506 struct inode *inode = mapping->host;
507 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
508 int err = 0, i;
509 struct pohmelfs_readpages_priv *rp;
510 struct page *tmp, *page;
512 if (list_empty(page_list))
513 goto err_out_exit;
515 rp = pohmelfs_readpages_alloc(pi, num);
516 if (IS_ERR(rp)) {
517 err = PTR_ERR(rp);
518 goto err_out_exit;
521 i = 0;
522 list_for_each_entry_safe(page, tmp, page_list, lru) {
523 list_del(&page->lru);
525 if (add_to_page_cache_lru(page, mapping, page->index, GFP_KERNEL)) {
526 /* Failed - free current page, optionally send already grabbed and free others */
527 page_cache_release(page);
528 break;
531 rp->pages[i] = page;
532 i++;
535 if (i > 0) {
536 rp->page_num = i;
537 err = pohmelfs_readpages_send(pi, rp);
539 pr_debug("%s: ino: %lu, offset: %lu, pages: %u/%u: %d\n",
540 pohmelfs_dump_id(pi->id.id), inode->i_ino,
541 (long)page_offset(rp->pages[0]),
542 rp->page_num, num, err);
545 kref_put(&rp->refcnt, pohmelfs_readpages_free);
547 /* Cleanup pages which were not added into page cache */
548 list_for_each_entry_safe(page, tmp, page_list, lru) {
549 list_del(&page->lru);
550 page_cache_release(page);
553 err_out_exit:
554 return err;
557 static int pohmelfs_readpages(struct file *filp, struct address_space *mapping,
558 struct list_head *page_list, unsigned nr_pages)
560 struct page *tmp, *page;
561 pgoff_t idx;
562 LIST_HEAD(head);
563 int err = 0, i = 0;
565 while (!list_empty(page_list)) {
566 page = list_entry(page_list->prev, struct page, lru);
567 idx = page->index;
568 i = 0;
570 INIT_LIST_HEAD(&head);
572 list_for_each_entry_safe_reverse(page, tmp, page_list, lru) {
573 if (idx != page->index) {
574 struct pohmelfs_inode *pi = pohmelfs_inode(mapping->host);
575 pr_debug("%s: index mismatch: want: %ld, page-index: %ld, total: %d\n",
576 pohmelfs_dump_id(pi->id.id),
577 (long)idx, (long)page->index,
578 nr_pages);
579 break;
582 list_move_tail(&page->lru, &head);
583 i++;
584 idx++;
587 err = pohmelfs_readpages_send_list(mapping, &head, i);
589 if (err >= 0)
590 err = 0;
592 return err;
595 static int pohmelfs_readpage(struct file *file, struct page *page)
597 struct inode *inode = page->mapping->host;
598 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
599 struct pohmelfs_readpages_priv *rp;
600 int err;
602 if (inode->i_size <= page->index << PAGE_CACHE_SHIFT) {
603 SetPageUptodate(page);
604 unlock_page(page);
605 return 0;
608 rp = pohmelfs_readpages_alloc(pi, 1);
609 if (IS_ERR(rp)) {
610 err = PTR_ERR(rp);
611 goto err_out_exit;
614 rp->pages[0] = page;
615 page_cache_get(page);
617 err = pohmelfs_readpages_send(pi, rp);
618 if (err >= 0)
619 err = 0;
621 kref_put(&rp->refcnt, pohmelfs_readpages_free);
622 err_out_exit:
623 if (err < 0)
624 pr_err("%s: %s: ino: %lu, offset: %lu, uptodate: %d, err: %d\n",
625 __func__, pohmelfs_dump_id(pi->id.id), inode->i_ino,
626 (long)page_offset(page), PageUptodate(page), err);
628 return err;
631 void pohmelfs_write_ctl_release(struct kref *kref)
633 struct pohmelfs_write_ctl *ctl = container_of(kref, struct pohmelfs_write_ctl, refcnt);
634 struct address_space *mapping = ctl->pvec.pages[0]->mapping;
635 struct inode *inode = mapping->host;
636 struct pohmelfs_sb *psb = pohmelfs_sb(inode->i_sb);
637 int bad_write = atomic_read(&ctl->good_writes) < psb->group_num / 2 + 1;
638 struct page *page;
639 unsigned int i;
641 if (psb->successful_write_count && (atomic_read(&ctl->good_writes) >= psb->successful_write_count))
642 bad_write = 0;
644 if (bad_write) {
645 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
646 unsigned long long offset = page_offset(ctl->pvec.pages[0]);
648 pr_debug("%s: bad write: ino: %lu, isize: %llu, offset: %llu: writes: %d/%d\n",
649 pohmelfs_dump_id(pi->id.id),
650 inode->i_ino, inode->i_size, offset,
651 atomic_read(&ctl->good_writes), psb->group_num);
652 mapping_set_error(mapping, -EIO);
655 for (i = 0; i < pagevec_count(&ctl->pvec); ++i) {
656 page = ctl->pvec.pages[i];
658 if (PageLocked(page)) {
659 end_page_writeback(page);
661 if (bad_write) {
662 SetPageError(page);
663 ClearPageUptodate(page);
665 * Do not reschedule failed write page again
666 * This may explode systems with large caches
667 * when there is no connection to elliptics cluster
669 //set_page_dirty(page);
671 unlock_page(page);
675 pagevec_release(&ctl->pvec);
676 kmem_cache_free(pohmelfs_write_cache, ctl);
679 static int pohmelfs_writepages_chunk(struct pohmelfs_inode *pi, struct pohmelfs_write_ctl *ctl,
680 struct writeback_control *wbc, struct address_space *mapping)
682 struct inode *inode = &pi->vfs_inode;
683 uint64_t offset, size;
684 unsigned i;
685 int err = 0, good = 0;
687 offset = page_offset(ctl->pvec.pages[0]);
689 size = 0;
690 /* we will lookup them again when doing actual send */
691 for (i = 0; i< pagevec_count(&ctl->pvec); ++i) {
692 struct page *page = ctl->pvec.pages[i];
694 lock_page(page);
695 #if 1
696 if (unlikely(page->mapping != mapping)) {
697 continue_unlock:
698 unlock_page(page);
699 continue;
702 if (wbc->sync_mode != WB_SYNC_NONE)
703 wait_on_page_writeback(page);
704 if (PageWriteback(page)) {
705 unlock_page(page);
706 break;
709 if (!PageDirty(page))
710 goto continue_unlock;
712 if (!clear_page_dirty_for_io(page))
713 goto continue_unlock;
714 #else
715 clear_page_dirty_for_io(page);
716 #endif
718 set_page_writeback(page);
720 good++;
721 size += PAGE_CACHE_SIZE;
722 wbc->nr_to_write--;
725 if (good != 0) {
726 size = pagevec_count(&ctl->pvec) * PAGE_CACHE_SIZE;
727 if (offset + size > inode->i_size)
728 size = inode->i_size - offset;
730 err = pohmelfs_write_command(pi, ctl, offset, size);
731 if (err)
732 goto err_out_exit;
735 err_out_exit:
736 kref_put(&ctl->refcnt, pohmelfs_write_ctl_release);
737 return err;
740 static int pohmelfs_writepages_send(struct address_space *mapping, struct writeback_control *wbc, struct pagevec *pvec, int start, int end)
742 struct inode *inode = mapping->host;
743 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
744 struct pohmelfs_write_ctl *ctl;
745 int err, i;
747 ctl = kmem_cache_zalloc(pohmelfs_write_cache, GFP_NOIO);
748 if (!ctl) {
749 err = -ENOMEM;
750 goto err_out_exit;
753 kref_init(&ctl->refcnt);
754 atomic_set(&ctl->good_writes, 0);
756 for (i = start; i < end; ++i)
757 pagevec_add(&ctl->pvec, pvec->pages[i]);
759 err = pohmelfs_writepages_chunk(pi, ctl, wbc, mapping);
760 if (err)
761 goto err_out_exit;
763 err_out_exit:
764 return err;
767 static int pohmelfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
769 struct inode *inode = mapping->host;
770 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
771 pgoff_t index, start, end /* inclusive */, idx;
772 int done = 0;
773 int range_whole = 0;
774 int should_loop = 1;
775 int nr_pages, err = 0, i, start_idx;
776 struct pagevec pvec;
777 int written = 0;
779 index = wbc->range_start >> PAGE_CACHE_SHIFT;
780 end = wbc->range_end >> PAGE_CACHE_SHIFT;
782 pr_debug("%s: ino: %ld, nr: %ld, index: %llu, end: %llu, total_size: %lu, sync: %d\n",
783 pohmelfs_dump_id(pohmelfs_inode(inode)->id.id), inode->i_ino,
784 wbc->nr_to_write, wbc->range_start, wbc->range_end,
785 (unsigned long)inode->i_size, wbc->sync_mode);
787 if (wbc->range_cyclic) {
788 start = mapping->writeback_index; /* Start from prev offset */
789 end = -1;
790 } else {
791 start = wbc->range_start >> PAGE_CACHE_SHIFT;
792 end = wbc->range_end >> PAGE_CACHE_SHIFT;
793 if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
794 range_whole = 1;
795 should_loop = 0;
797 index = start;
799 retry:
800 while (!done && index <= end) {
801 nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
802 min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
803 if (!nr_pages) {
804 err = 0;
805 break;
808 idx = pvec.pages[0]->index;
809 for (start_idx = 0, i = 0; i< nr_pages; ++i) {
810 struct page *page = pvec.pages[i];
812 /* non-contiguous pages detected */
813 if (idx != page->index) {
814 err = pohmelfs_writepages_send(mapping, wbc, &pvec, start_idx, i);
815 if (err)
816 goto err_out_exit;
817 start_idx = i;
820 idx++;
823 err = pohmelfs_writepages_send(mapping, wbc, &pvec, start_idx, nr_pages);
824 if (err)
825 goto err_out_exit;
827 if (wbc->nr_to_write <= 0)
828 done = 1;
830 written += nr_pages;
833 if (should_loop && !done) {
834 /* more to do; loop back to beginning of file */
835 should_loop = 0;
836 index = 0;
837 goto retry;
840 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
841 mapping->writeback_index = index;
843 if (written) {
844 err = pohmelfs_metadata_inode(pi, wbc->sync_mode != WB_SYNC_NONE);
845 if (err)
846 goto err_out_exit;
850 if (test_and_clear_bit(AS_EIO, &mapping->flags))
851 err = -EIO;
852 err_out_exit:
853 pr_debug("%s: metadata write complete: %d\n",
854 pohmelfs_dump_id(pi->id.id), err);
855 return err;
858 static const struct address_space_operations pohmelfs_aops = {
859 .write_begin = simple_write_begin,
860 .write_end = simple_write_end,
861 .writepages = pohmelfs_writepages,
862 .readpage = pohmelfs_readpage,
863 .readpages = pohmelfs_readpages,
864 .set_page_dirty = __set_page_dirty_nobuffers,
867 void pohmelfs_convert_inode_info(struct pohmelfs_inode_info *info)
869 info->ino = cpu_to_le64(info->ino);
870 info->mode = cpu_to_le64(info->mode);
871 info->nlink = cpu_to_le64(info->nlink);
872 info->uid = cpu_to_le32(info->uid);
873 info->gid = cpu_to_le32(info->gid);
874 info->namelen = cpu_to_le32(info->namelen);
875 info->blocks = cpu_to_le64(info->blocks);
876 info->rdev = cpu_to_le64(info->rdev);
877 info->size = cpu_to_le64(info->size);
878 info->version = cpu_to_le64(info->version);
879 info->blocksize = cpu_to_le64(info->blocksize);
880 info->flags = cpu_to_le64(info->flags);
882 dnet_convert_time(&info->ctime);
883 dnet_convert_time(&info->mtime);
884 dnet_convert_time(&info->atime);
887 void pohmelfs_fill_inode_info(struct inode *inode, struct pohmelfs_inode_info *info)
889 struct pohmelfs_inode *pi = pohmelfs_inode(inode);
891 memcpy(info->id.id, pi->id.id, DNET_ID_SIZE);
893 info->ino = inode->i_ino;
894 info->mode = inode->i_mode;
895 info->nlink = inode->i_nlink;
896 info->uid = inode->i_uid;
897 info->gid = inode->i_gid;
898 info->blocks = inode->i_blocks;
899 info->rdev = inode->i_rdev;
900 info->size = inode->i_size;
901 info->version = inode->i_version;
902 info->blocksize = 1 << inode->i_blkbits;
904 info->ctime.tsec = inode->i_ctime.tv_sec;
905 info->ctime.tnsec = inode->i_ctime.tv_nsec;
907 info->mtime.tsec = inode->i_mtime.tv_sec;
908 info->mtime.tnsec = inode->i_mtime.tv_nsec;
910 info->atime.tsec = inode->i_atime.tv_sec;
911 info->atime.tnsec = inode->i_atime.tv_nsec;
913 info->flags = 0;
916 void pohmelfs_fill_inode(struct inode *inode, struct pohmelfs_inode_info *info)
918 pr_debug("%s: ino: %lu inode is regular: %d, dir: %d, link: %d, mode: %o, "
919 "namelen: %u, size: %llu, state: %lx, mtime: %llu.%llu/%lu.%lu\n",
920 pohmelfs_dump_id(info->id.id), inode->i_ino,
921 S_ISREG(inode->i_mode), S_ISDIR(inode->i_mode),
922 S_ISLNK(inode->i_mode), inode->i_mode, info->namelen,
923 inode->i_size, inode->i_state,
924 (unsigned long long)info->mtime.tsec,
925 (unsigned long long)info->mtime.tnsec,
926 inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec);
928 if (info->mtime.tsec < inode->i_mtime.tv_sec)
929 return;
930 if ((info->mtime.tsec == inode->i_mtime.tv_sec) &&
931 (info->mtime.tnsec < inode->i_mtime.tv_nsec))
932 return;
934 pohmelfs_inode(inode)->id = info->id;
936 inode->i_mode = info->mode;
937 set_nlink(inode, info->nlink);
938 inode->i_uid = info->uid;
939 inode->i_gid = info->gid;
940 inode->i_blocks = info->blocks;
941 inode->i_rdev = info->rdev;
942 inode->i_size = info->size;
943 inode->i_version = info->version;
944 inode->i_blkbits = ffs(info->blocksize);
946 inode->i_mtime = pohmelfs_date(&info->mtime);
947 inode->i_atime = pohmelfs_date(&info->atime);
948 inode->i_ctime = pohmelfs_date(&info->ctime);
951 static void pohmelfs_inode_info_current(struct pohmelfs_sb *psb, struct pohmelfs_inode_info *info)
953 struct timespec ts = CURRENT_TIME;
954 struct dnet_time dtime;
956 info->nlink = S_ISDIR(info->mode) ? 2 : 1;
957 info->uid = current_fsuid();
958 info->gid = current_fsgid();
959 info->size = 0;
960 info->blocksize = PAGE_SIZE;
961 info->blocks = 0;
962 info->rdev = 0;
963 info->version = 0;
965 dtime.tsec = ts.tv_sec;
966 dtime.tnsec = ts.tv_nsec;
968 info->ctime = dtime;
969 info->mtime = dtime;
970 info->atime = dtime;
972 pohmelfs_gen_id(psb, &info->id);
975 const struct inode_operations pohmelfs_special_inode_operations = {
976 .setattr = simple_setattr,
979 struct pohmelfs_inode *pohmelfs_existing_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode_info *info)
981 struct pohmelfs_inode *pi;
982 struct inode *inode;
983 int err;
985 inode = iget_locked(psb->sb, atomic_long_inc_return(&psb->ino));
986 if (!inode) {
987 err = -ENOMEM;
988 goto err_out_exit;
991 pi = pohmelfs_inode(inode);
993 if (inode->i_state & I_NEW) {
994 pohmelfs_fill_inode(inode, info);
996 * i_mapping is a pointer to i_data during inode initialization.
998 inode->i_data.a_ops = &pohmelfs_aops;
1000 if (S_ISREG(inode->i_mode)) {
1001 inode->i_fop = &pohmelfs_file_ops;
1002 inode->i_op = &pohmelfs_file_inode_operations;
1003 } else if (S_ISDIR(inode->i_mode)) {
1004 inode->i_fop = &pohmelfs_dir_fops;
1005 inode->i_op = &pohmelfs_dir_inode_operations;
1006 } else if (S_ISLNK(inode->i_mode)) {
1007 inode->i_op = &pohmelfs_symlink_inode_operations;
1008 inode->i_mapping->a_ops = &pohmelfs_aops;
1009 } else {
1010 inode->i_op = &pohmelfs_special_inode_operations;
1013 err = pohmelfs_sb_inode_insert(psb, pi);
1014 if (err)
1015 goto err_out_put;
1017 unlock_new_inode(inode);
1020 return pi;
1022 err_out_put:
1023 unlock_new_inode(inode);
1024 iput(inode);
1025 err_out_exit:
1026 return ERR_PTR(err);
1029 struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb, int mode)
1031 struct pohmelfs_inode *pi;
1032 struct pohmelfs_inode_info *info;
1033 int err;
1035 info = kmem_cache_zalloc(pohmelfs_inode_info_cache, GFP_NOIO);
1036 if (!info) {
1037 err = -ENOMEM;
1038 goto err_out_exit;
1041 info->mode = mode;
1043 pohmelfs_inode_info_current(psb, info);
1045 pi = pohmelfs_existing_inode(psb, info);
1046 if (IS_ERR(pi)) {
1047 err = PTR_ERR(pi);
1048 goto err_out_free;
1051 kmem_cache_free(pohmelfs_inode_info_cache, info);
1052 return pi;
1054 err_out_free:
1055 kmem_cache_free(pohmelfs_inode_info_cache, info);
1056 err_out_exit:
1057 return ERR_PTR(err);
1060 int pohmelfs_wait_init(struct pohmelfs_wait *wait, struct pohmelfs_inode *pi)
1062 if (!igrab(&pi->vfs_inode))
1063 return -EINVAL;
1065 wait->pi = pi;
1067 atomic_long_set(&wait->count, 0);
1068 init_waitqueue_head(&wait->wq);
1069 kref_init(&wait->refcnt);
1071 return 0;
1074 struct pohmelfs_wait *pohmelfs_wait_alloc(struct pohmelfs_inode *pi)
1076 struct pohmelfs_wait *wait;
1078 wait = kmem_cache_zalloc(pohmelfs_wait_cache, GFP_NOIO);
1079 if (!wait) {
1080 goto err_out_exit;
1083 if (pohmelfs_wait_init(wait, pi))
1084 goto err_out_free;
1086 return wait;
1088 err_out_free:
1089 kmem_cache_free(pohmelfs_wait_cache, wait);
1090 err_out_exit:
1091 return NULL;
1094 static void pohmelfs_wait_free(struct kref *kref)
1096 struct pohmelfs_wait *wait = container_of(kref, struct pohmelfs_wait, refcnt);
1097 struct inode *inode = &wait->pi->vfs_inode;
1099 iput(inode);
1100 kmem_cache_free(pohmelfs_wait_cache, wait);
1103 void pohmelfs_wait_put(struct pohmelfs_wait *wait)
1105 kref_put(&wait->refcnt, pohmelfs_wait_free);