From b1da9409520d40b964ed5578bb632d715a6e6275 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 22 Aug 2008 15:33:24 -0700 Subject: [PATCH] kclient: some writepage cleanup --- src/TODO | 6 ++++-- src/kernel/addr.c | 44 ++++++++++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/TODO b/src/TODO index 328fe83a7d8a8..b818e989a96e5 100644 --- a/src/TODO +++ b/src/TODO @@ -18,8 +18,10 @@ big items snaps on kclient -/- we need a rw snap mutex, so that pending io blocks while we update snap contexts - - we can push down to a per-realm rw mutex later + +- short reads not allowed.. +- short writes ...? + - need to do ORDERSNAP flag - to get sync write retry and delayed flushsnap for sync writes diff --git a/src/kernel/addr.c b/src/kernel/addr.c index 6418031383527..41135f59d2051 100644 --- a/src/kernel/addr.c +++ b/src/kernel/addr.c @@ -287,7 +287,7 @@ static int ceph_readpages(struct file *file, struct address_space *mapping, * ceph_writepage: * clear dirty page, and set the writeback flag in the radix tree. * to actually write data to the remote OSDs. - * leave pages locked. + * leave page locked. */ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) { @@ -298,11 +298,14 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) int len = PAGE_CACHE_SIZE; loff_t i_size; int err = 0; - int was_dirty; struct ceph_snap_context *snapc; - if (!page->mapping || !page->mapping->host) + dout(10, "writepage %p idx %lu\n", page, page->index); + + if (!page->mapping || !page->mapping->host) { + dout(10, "writepage %p - no mapping\n", page); return -EFAULT; + } inode = page->mapping->host; ci = ceph_inode(inode); osdc = &ceph_inode_to_client(inode)->osdc; @@ -311,31 +314,32 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) i_size = i_size_read(inode); if (i_size < page_off + len) len = i_size - page_off; - - dout(10, "ceph_writepage inode %p page %p index %lu on %llu~%u\n", + snapc = (void *)page->private; + dout(10, "writepage inode %p page %p index %lu on %llu~%u\n", inode, page, page->index, page_off, len); - page_cache_get(page); - was_dirty = PageDirty(page); - snapc = (void *)page->private; set_page_writeback(page); - err = ceph_osdc_writepages(osdc, ceph_vino(inode), &ci->i_layout, - (void *)page->private, - page_off, len, &page, 1); - if (err >= 0) { - if (was_dirty) { - dout(20, "cleaned page %p\n", page); + if (snapc) { + err = ceph_osdc_writepages(osdc, ceph_vino(inode), + &ci->i_layout, snapc, + page_off, len, &page, 1); + if (err >= 0) { + dout(20, "writepage cleaned page %p\n", page); + page->private = 0; + ClearPagePrivate(page); ceph_put_wrbuffer_cap_refs(ci, 1, snapc); + ceph_put_snap_context(snapc); + err = 0; /* vfs expects us to return 0 */ + } else { + dout(20, "writepage redirtying page %p\n", page); + ceph_redirty_page(page->mapping, page); + if (wbc) + wbc->pages_skipped++; } - SetPageUptodate(page); - err = 0; /* vfs expects us to return 0 */ } else { - if (wbc) - wbc->pages_skipped++; - ceph_set_page_dirty(page, snapc); + dout(20, "writepage %p noop (no snapc)\n", page); } end_page_writeback(page); - page_cache_release(page); return err; } -- 2.39.5