From b118c772387b3a563c7fdf463e5f89349e3c471b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 8 Jan 2008 14:04:26 -0800 Subject: [PATCH] some initial readpages bits --- src/kernel/addr.c | 28 ++++++++++++-- src/kernel/file.c | 6 +-- src/kernel/osd_client.c | 84 ++++++++++++++++++++++++++++++++--------- src/kernel/osd_client.h | 3 ++ 4 files changed, 97 insertions(+), 24 deletions(-) diff --git a/src/kernel/addr.c b/src/kernel/addr.c index a1dd5eecfdf7a..90425765c784e 100644 --- a/src/kernel/addr.c +++ b/src/kernel/addr.c @@ -17,9 +17,8 @@ static int ceph_readpage(struct file *filp, struct page *page) struct ceph_osd_client *osdc = &ceph_inode_to_client(inode)->osdc; int err = 0; - dout(10, "ceph_readpage file %p page %p index %lu\n", filp, - page, page->index); - dout(10, " inode %p\n", inode); + dout(10, "ceph_readpage inode %p file %p page %p index %lu\n", + inode, filp, page, page->index); err = ceph_osdc_readpage(osdc, inode->i_ino, &ci->i_layout, page->index << PAGE_SHIFT, PAGE_SIZE, page); if (err) goto out_unlock; @@ -30,7 +29,30 @@ out_unlock: return err; } +static int ceph_readpages(struct file *file, struct address_space *mapping, + struct list_head *pages, unsigned nr_pages) +{ + struct inode *inode = file->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_osd_client *osdc = &ceph_inode_to_client(inode)->osdc; + int err = 0; + + dout(10, "ceph_readpages inode %p file %p nr_pages %d\n", + inode, file, nr_pages); + + err = ceph_osdc_readpages(osdc, inode->i_ino, &ci->i_layout, + pages, nr_pages); + if (err < 0) goto out_unlock; + + // hrm + //SetPageUptodate(page); +out_unlock: + return err; + + +} const struct address_space_operations ceph_aops = { .readpage = ceph_readpage, +// .readpages = ceph_readpages }; diff --git a/src/kernel/file.c b/src/kernel/file.c index f29d2000ef7be..4ee8a6735ea16 100644 --- a/src/kernel/file.c +++ b/src/kernel/file.c @@ -49,7 +49,7 @@ int ceph_open(struct inode *inode, struct file *file) struct ceph_inode_cap *cap; struct ceph_file_info *fi; - dout(5, "dir_open inode %p (%lu) file %p\n", inode, inode->i_ino, file); + dout(5, "ceph_open inode %p (%lu) file %p\n", inode, inode->i_ino, file); cap = ceph_find_cap(inode, 0); if (!cap) { cap = ceph_do_open(inode, file); @@ -63,7 +63,7 @@ int ceph_open(struct inode *inode, struct file *file) file->private_data = fi; atomic_inc(&ci->i_cap_count); - dout(5, "open_dir success\n"); + dout(5, "ceph_open success\n"); return 0; } @@ -72,7 +72,7 @@ int ceph_release(struct inode *inode, struct file *filp) struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_file_info *fi = filp->private_data; - dout(5, "dir_release inode %p filp %p\n", inode, filp); + dout(5, "ceph_release inode %p filp %p\n", inode, filp); atomic_dec(&ci->i_cap_count); if (fi->rinfo.reply) diff --git a/src/kernel/osd_client.c b/src/kernel/osd_client.c index 2056953c2b381..555e3e4e47978 100644 --- a/src/kernel/osd_client.c +++ b/src/kernel/osd_client.c @@ -353,31 +353,79 @@ int ceph_osdc_readpage(struct ceph_osd_client *osdc, ceph_ino_t ino, /* * read multiple pages (readahead) */ +#if 0 + +int ceph_osdc_readpages_filler(struct ceph_osd_request *req, struct page *p) +{ + +} + int ceph_osdc_readpages(struct ceph_osd_client *osdc, ceph_ino_t ino, struct ceph_file_layout *layout, - loff_t off, loff_t len, - struct page **pages) + struct list_head *pagels, int nr_pages) { - struct ceph_object oid; + struct ceph_msg *reqm, *reply; + struct ceph_osd_request_head *reqhead; + struct ceph_osd_request *req; + struct ceph_osd_reply_head *replyhead; + __u64 off, len; + struct page *page; + + /* + * for now, our strategy is simple: start with the + * initial page, and fetch as much of that object as + * we can that falls within the range specified by + * nr_pages. + */ - BUG_ON(layout->fl_stripe_unit & ~PAGE_MASK); + /* request msg */ + reqm = new_request_msg(osdc, CEPH_OSD_OP_READ); + if (IS_ERR(reqm)) + return PTR_ERR(reqm); + reqhead = reqm->front.iov_base; + reqhead->oid.ino = ino; + reqhead->oid.rev = 0; + off = list_to_page(pagels)->index << PAGE_SHIFT; + len = nr_pages << PAGE_SHIFT; + calc_file_object_mapping(layout, &off, &len, &reqhead->oid, + &reqhead->offset, &reqhead->length); + BUG_ON(len != 0); + nr_pages = DIV_ROUND_UP(reqhead->length, PAGE_SIZE); + calc_object_layout(&reqhead->layout, &reqhead->oid, layout, osdc->osdmap); + dout(10, "readpage object block %u %llu~%llu\n", reqhead->oid.bno, reqhead->offset, reqhead->length); - /* this may do a scatter/gather type of thing... need to track - * that mess somehow - */ + /* register request */ + spin_lock(&osdc->lock); + req = register_request(osdc, reqm, nr_pages); + if (IS_ERR(req)) { + ceph_msg_put(reqm); + spin_unlock(&osdc->lock); + return PTR_ERR(req); + } - /* map range onto objects */ - oid.ino = ino; - oid.rev = 0; - while (len > 0) { - /*calc_file_object_mapping(layout, &off, &len, &oid, &oxoff, &oxlen); - npages = calc_pages_for(oxoff, oxlen); - dout(10, " object block %u %u~%u over %d pages\n", - oid.bno, oxoff, oxlen, npages); - */ - /* make request */ + /* prepage pages (add to page cache, request vector) */ + read_cache_pages(mapping, pagels, ceph_readpages_filler, req); - } + /* send request */ + reqhead->osdmap_epoch = osdc->osdmap->epoch; + send_request(osdc, req); + spin_unlock(&osdc->lock); + + /* wait */ + dout(10, "readpage tid %llu waiting for reply on %p\n", req->r_tid, req); + wait_for_completion(&req->r_completion); + dout(10, "readpage tid %llu got reply on %p\n", req->r_tid, req); + + spin_lock(&osdc->lock); + unregister_request(osdc, req); + spin_unlock(&osdc->lock); + reply = req->r_reply; + replyhead = reply->front.iov_base; + dout(10, "readpage result %d\n", replyhead->result); + ceph_msg_put(reply); + put_request(req); return 0; } + +#endif diff --git a/src/kernel/osd_client.h b/src/kernel/osd_client.h index 3ca8ebbf0f340..a737d3bc4f0ba 100644 --- a/src/kernel/osd_client.h +++ b/src/kernel/osd_client.h @@ -62,6 +62,9 @@ extern int ceph_osdc_readpage(struct ceph_osd_client *osdc, ceph_ino_t ino, struct ceph_file_layout *layout, loff_t off, loff_t len, struct page *page); +extern int ceph_osdc_readpages(struct ceph_osd_client *osdc, ceph_ino_t ino, + struct ceph_file_layout *layout, + struct list_head *pagels, int nr_pages); #endif -- 2.39.5