From 34d22f914680c0be0a625b1b265fb6e93c738038 Mon Sep 17 00:00:00 2001 From: Dongsu Park Date: Thu, 6 Mar 2008 11:25:42 -0800 Subject: [PATCH] defined ceph_osdc_readpages() and ceph_osdc_readpage_filler(). renamed do_ceph_read as ceph_readpage_async(), do_ceph_write as ceph_writepage_async() respectively. now ceph_writepage method is really used, and buggy unlock_page() functions were removed, to avoid kernel panics. Conflicts: src/kernel/addr.c src/kernel/file.c src/kernel/osd_client.c src/kernel/osd_client.h --- src/kernel/addr.c | 39 ++-- src/kernel/file.c | 4 +- src/kernel/osd_client.c | 507 +++++++++++++++++++++++----------------- src/kernel/osd_client.h | 20 +- 4 files changed, 330 insertions(+), 240 deletions(-) diff --git a/src/kernel/addr.c b/src/kernel/addr.c index fc1bc464c5afc..980f0972734df 100644 --- a/src/kernel/addr.c +++ b/src/kernel/addr.c @@ -25,8 +25,9 @@ static int ceph_readpage(struct file *filp, struct page *page) goto out_unlock; SetPageUptodate(page); + + /* TODO: update info in ci? */ out_unlock: - unlock_page(page); return err; } @@ -42,7 +43,7 @@ static int ceph_readpages(struct file *file, struct address_space *mapping, dout(10, "ceph_readpages inode %p file %p nr_pages %d\n", inode, file, nr_pages); - err = ceph_osdc_readpages(osdc, ceph_ino(inode), &ci->i_layout, + err = ceph_osdc_readpages(osdc, mapping, ceph_ino(inode), &ci->i_layout, pages, nr_pages); if (err < 0) goto out_unlock; @@ -82,17 +83,24 @@ static int ceph_writepage(struct page *page, struct writeback_control *wbc) dout(10, "ceph_writepage inode %p page %p index %lu\n", inode, page, page->index); - err = ceph_osdc_silly_write(osdc, inode->i_ino, &ci->i_layout, - PAGE_SIZE, 0, (const char *)page->first_page); -/* err = ceph_osdc_writepage(osdc, inode->i_ino, &ci->i_layout,*/ -/* page->index << PAGE_SHIFT, PAGE_SIZE, page);*/ - if (err) - goto out_unlock; + /* write a page at the index of page->index, by size of PAGE_SIZE */ + err = ceph_osdc_writepage(osdc, inode->i_ino, &ci->i_layout, + page->index << PAGE_SHIFT, PAGE_SIZE, page); + if (err) + goto out_unlock; + + /* update written data size in ceph_inode_info */ + spin_lock(&inode->i_lock); + if (inode->i_size <= PAGE_SIZE) { + ci->i_wr_size = inode->i_size = PAGE_SIZE; + inode->i_blocks = (inode->i_size + 512 - 1) >> 9; + dout(10, "extending file size to %d\n", (int)inode->i_size); + } + spin_unlock(&inode->i_lock); out_unlock: - unlock_page(page); - end_page_writeback(page); - put_page(page); + end_page_writeback(page); + put_page(page); return err; } @@ -115,7 +123,6 @@ static int ceph_prepare_write(struct file *filp, struct page *page, inode, page, from, (to-from)); /* - * TODO: * 1. check if page is up to date * 2. If not, read a page to be up to date */ @@ -146,9 +153,10 @@ static int ceph_prepare_write(struct file *filp, struct page *page, page->index << PAGE_SHIFT, PAGE_SIZE, page); if (err) goto out_unlock; - + + /* TODO: update info in ci? */ + out_unlock: - unlock_page(page); return err; } @@ -191,6 +199,8 @@ static int ceph_commit_write(struct file *filp, struct page *page, if (err) err = 0; /* FIXME: more sophisticated error handling */ kunmap(page); + + /* TODO: update info in ci? */ } else { /* set the page as up-to-date and mark it as dirty */ @@ -199,7 +209,6 @@ static int ceph_commit_write(struct file *filp, struct page *page, } /*out_unlock:*/ - unlock_page(page); return err; } diff --git a/src/kernel/file.c b/src/kernel/file.c index 70edaaa23a328..82f92e3ece91a 100644 --- a/src/kernel/file.c +++ b/src/kernel/file.c @@ -287,8 +287,8 @@ const struct file_operations ceph_file_fops = { .release = ceph_release, .llseek = generic_file_llseek, .read = do_sync_read, - .write = ceph_silly_write, - //.write = do_sync_write, + //.write = ceph_silly_write, + .write = do_sync_write, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, diff --git a/src/kernel/osd_client.c b/src/kernel/osd_client.c index ba804582b5208..eca06a1dc6ba2 100644 --- a/src/kernel/osd_client.c +++ b/src/kernel/osd_client.c @@ -2,7 +2,8 @@ #include #include #include -#include /* kmap, kunmap */ +#include /* kmap, kunmap */ +#include /* read_cache_pages */ int ceph_debug_osdc = 50; #define DOUT_VAR ceph_debug_osdc @@ -13,14 +14,20 @@ int ceph_debug_osdc = 50; #include "messenger.h" #include "crush/mapper.h" -static int do_ceph_read(struct ceph_osd_client *osdc, ceph_ino_t ino, - struct ceph_file_layout *layout, - loff_t off, loff_t len, - struct page *page); -static int do_ceph_write(struct ceph_osd_client *osdc, ceph_ino_t ino, - struct ceph_file_layout *layout, - loff_t off, loff_t len, - char *write_data); +struct ceph_readdesc { + struct ceph_osd_client *osdc; + struct ceph_file_layout *layout; + loff_t off; + loff_t len; +}; + +static int ceph_readpage_async(struct ceph_osd_client *osdc, + struct ceph_msg *reqm, + struct page *page); +static int ceph_writepage_async(struct ceph_osd_client *osdc, ceph_ino_t ino, + struct ceph_file_layout *layout, + loff_t off, loff_t len, + char *write_data); void ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client) { @@ -312,7 +319,26 @@ int ceph_osdc_readpage(struct ceph_osd_client *osdc, ceph_ino_t ino, loff_t off, loff_t len, struct page *page) { - int ret = do_ceph_read(osdc, ino, layout, off, len, page); + struct ceph_msg *reqm; + struct ceph_osd_request_head *reqhead; + int ret; + + dout(10, "readpage on ino %llx at %lld~%lld\n", ino, off, len); + + /* 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; + calc_file_object_mapping(layout, &off, &len, &reqhead->oid, + &reqhead->offset, &reqhead->length); + BUG_ON(len != 0); + 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); + + ret = ceph_readpage_async(osdc, reqm, page); if (ret < 0) return ret; return 0; @@ -321,14 +347,49 @@ 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_filler(void *data, struct page *page) { + struct ceph_readdesc *pdesc = (struct ceph_readdesc *)data; + struct ceph_osd_client *osdc = pdesc->osdc; + struct ceph_file_layout *layout = pdesc->layout; + loff_t off = pdesc->off; + loff_t len = pdesc->len; + + struct ceph_osd_request_head *reqhead; + struct ceph_msg *reqm; + struct inode *inode = page->mapping->host; + ceph_ino_t ino = ceph_ino(inode); + int ret; + + /* 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; + calc_file_object_mapping(layout, &off, &len, &reqhead->oid, + &reqhead->offset, &reqhead->length); + BUG_ON(len != 0); + 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); + ret = ceph_readpage_async(osdc, reqm, page); + if (ret < 0) + return ret; + + return 0; } -int ceph_osdc_readpages(struct ceph_osd_client *osdc, ceph_ino_t ino, +/* FIXME: Since this macro list_to_page is already defined in mm/readahead.c, + * it's not good to define it again at this point. + */ +#define list_to_page(head) (list_entry((head)->prev, struct page, lru)) + +int ceph_osdc_readpages(struct ceph_osd_client *osdc, + struct address_space *mapping, + ceph_ino_t ino, struct ceph_file_layout *layout, struct list_head *pagels, int nr_pages) { @@ -337,7 +398,10 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc, ceph_ino_t ino, struct ceph_osd_request *req; struct ceph_osd_reply_head *replyhead; __u64 off, len; - struct page *page; + struct ceph_readdesc desc = { + .osdc = osdc, + .layout = layout + }; /* * for now, our strategy is simple: start with the @@ -346,6 +410,8 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc, ceph_ino_t ino, * nr_pages. */ + dout(10, "readpage on ino %llx at %lld~%lld\n", ino, off, len); + /* request msg */ reqm = new_request_msg(osdc, CEPH_OSD_OP_READ); if (IS_ERR(reqm)) @@ -372,7 +438,9 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc, ceph_ino_t ino, } /* prepage pages (add to page cache, request vector) */ - read_cache_pages(mapping, pagels, ceph_readpages_filler, req); + desc.off = off; + desc.len = len; + read_cache_pages(mapping, pagels, ceph_osdc_readpages_filler, &desc); /* send request */ reqhead->osdmap_epoch = osdc->osdmap->epoch; @@ -396,8 +464,6 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc, ceph_ino_t ino, return 0; } -#endif - /* * silly hack. @@ -493,69 +559,84 @@ int ceph_osdc_prepare_write(struct ceph_osd_client *osdc, ceph_ino_t ino, loff_t off, loff_t len, struct page *page) { - int rc; - char *read_data; - - dout(10, "osdc_prepare_write on ino %llx at %lld~%lld\n", ino, off, len); - - get_page(page); - read_data = kmap(page); - - /* - * 1. Read a page by calling ceph_osdc_readpage() - * 2. Fill the rest bytes by 0, to align by PAGE_SIZE - */ - - rc = do_ceph_read(osdc, ino, layout, off, len, page); - if (rc < 0) - goto io_error; - - if (rc < PAGE_SIZE) - memset(read_data + rc, 0, PAGE_SIZE - rc); - - SetPageUptodate(page); - - rc = 0; - + int rc; + char *read_data; + struct ceph_msg *reqm; + struct ceph_osd_request_head *reqhead; + + dout(10, "osdc_prepare_write on ino %llx at %lld~%lld\n", ino, off, len); + + get_page(page); + read_data = kmap(page); + + /* + * 1. Read a page by calling ceph_osdc_readpage() + * 2. Fill the rest bytes by 0, to align by PAGE_SIZE + */ + + /* 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; + calc_file_object_mapping(layout, &off, &len, &reqhead->oid, + &reqhead->offset, &reqhead->length); + BUG_ON(len != 0); + 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); + + rc = ceph_readpage_async(osdc, reqm, page); + if (rc < 0) + goto io_error; + + if (rc < PAGE_SIZE) + memset(read_data + rc, 0, PAGE_SIZE - rc); + + SetPageUptodate(page); + + rc = 0; + io_error: - kunmap(page); - put_page(page); - return rc; + kunmap(page); + put_page(page); + return rc; } /* * Mark a page as dirty to be written into remote OSDs */ int ceph_osdc_commit_write(struct ceph_osd_client *osdc, ceph_ino_t ino, - struct ceph_file_layout *layout, - loff_t off, loff_t len, - struct page *page) + struct ceph_file_layout *layout, + loff_t off, loff_t len, + struct page *page) { - char *write_data; - int ret = 0; - - dout(10, "osdc_commit_write on ino %llx at %lld~%lld\n", ino, off, len); - - /* - * if it is not up-to-date, then force it to be so. - */ - - write_data = kmap(page); - write_data += off; - - if (len > PAGE_SIZE) { - kunmap(page); - return -EIO; - } - - ret = do_ceph_write(osdc, ino, layout, off, len, write_data); - if (ret) { - kunmap(page); - return ret; - } - - kunmap(page); - return ret; + char *write_data; + int ret = 0; + + dout(10, "osdc_commit_write on ino %llx at %lld~%lld\n", ino, off, len); + + /* + * if it is not up-to-date, then force it to be so. + */ + + write_data = kmap(page); + write_data += off; + + if (len > PAGE_SIZE) { + kunmap(page); + return -EIO; + } + + ret = ceph_writepage_async(osdc, ino, layout, off, len, write_data); + if (ret) { + kunmap(page); + return ret; + } + + kunmap(page); + return ret; } /* @@ -566,167 +647,153 @@ int ceph_osdc_writepage(struct ceph_osd_client *osdc, ceph_ino_t ino, loff_t off, loff_t len, struct page *page) { - int ret = 0; - char *write_data; - - dout(10, "ceph_osdc_writepage on ino %llx at %lld~%lld\n", ino, off, len); - - write_data = kmap(page); - write_data += off; - - if (len > PAGE_SIZE) { - kunmap(page); - return -EIO; - } - - ret = do_ceph_write(osdc, ino, layout, off, len, write_data); - if (ret) { - kunmap(page); - return ret; - } + int ret = 0; + char *write_data; + + dout(10, "ceph_osdc_writepage on ino %llx at %lld~%lld\n", ino, off, len); + + write_data = kmap(page); + write_data += off; + + if (len > PAGE_SIZE) { + kunmap(page); + return -EIO; + } + + ret = ceph_writepage_async(osdc, ino, layout, off, len, write_data); + if (ret) { + kunmap(page); + return ret; + } - kunmap(page); - return ret; + kunmap(page); + return ret; } /* * do a read job for one page */ -static int do_ceph_read(struct ceph_osd_client *osdc, ceph_ino_t ino, - struct ceph_file_layout *layout, - loff_t off, loff_t len, - struct page *page) +static int ceph_readpage_async(struct ceph_osd_client *osdc, + struct ceph_msg *reqm, + struct page *page) { - struct ceph_msg *reqm, *reply; - struct ceph_osd_request_head *reqhead; - struct ceph_osd_request *req; - struct ceph_osd_reply_head *replyhead; - - dout(10, "readpage on ino %llx at %lld~%lld\n", ino, off, len); - - /* 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; - calc_file_object_mapping(layout, &off, &len, &reqhead->oid, - &reqhead->offset, &reqhead->length); - BUG_ON(len != 0); - 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); - - /* register+send request */ - spin_lock(&osdc->lock); - req = register_request(osdc, reqm, 1); - if (IS_ERR(req)) { - ceph_msg_put(reqm); - spin_unlock(&osdc->lock); - return PTR_ERR(req); - } - req->r_pages[0] = page; - 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; + struct ceph_msg *reply; + struct ceph_osd_request_head *reqhead; + struct ceph_osd_request *req; + struct ceph_osd_reply_head *replyhead; + + reqhead = reqm->front.iov_base; + + /* register+send request */ + spin_lock(&osdc->lock); + req = register_request(osdc, reqm, 1); + if (IS_ERR(req)) { + ceph_msg_put(reqm); + spin_unlock(&osdc->lock); + return PTR_ERR(req); + } + req->r_pages[0] = page; + 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; } /* * do a write job for one page */ -static int do_ceph_write(struct ceph_osd_client *osdc, ceph_ino_t ino, - struct ceph_file_layout *layout, - loff_t off, loff_t len, - char *write_data) +static int ceph_writepage_async(struct ceph_osd_client *osdc, ceph_ino_t ino, + struct ceph_file_layout *layout, + loff_t off, loff_t len, + char *write_data) { - struct ceph_msg *reqm, *reply; - struct ceph_osd_request_head *reqhead; - struct ceph_osd_request *req; - struct ceph_osd_reply_head *replyhead; - __u64 toff = off, tlen = len; - int po, l; - int ret = 0; - - /* request msg */ - reqm = new_request_msg(osdc, CEPH_OSD_OP_WRITE); - if (IS_ERR(reqm)) - return PTR_ERR(reqm); - reqhead = reqm->front.iov_base; - reqhead->oid.ino = ino; - reqhead->oid.rev = 0; - reqhead->flags = CEPH_OSD_OP_ACK|CEPH_OSD_OP_SAFE; /* want them both */ - calc_file_object_mapping(layout, &toff, &tlen, &reqhead->oid, - &reqhead->offset, &reqhead->length); - if (tlen != 0) { - dout(10, "not writing complete bit.. skipping last %llu, doing %llu~%llu\n", tlen, off, len); - len -= tlen; - } - calc_object_layout(&reqhead->layout, &reqhead->oid, layout, osdc->osdmap); - dout(10, "osdc_writepage object block %u %llu~%llu\n", reqhead->oid.bno, reqhead->offset, reqhead->length); - - /* register+send request */ - spin_lock(&osdc->lock); - req = register_request(osdc, reqm, 1); - if (IS_ERR(req)) { - ceph_msg_put(reqm); - spin_unlock(&osdc->lock); - return PTR_ERR(req); - } - - /* copy data into a page in a request message */ - req->r_pages[0] = alloc_pages(GFP_KERNEL, 1); - po = off & ~PAGE_MASK; - - l = min_t(int, PAGE_SIZE-po, len); - if (copy_from_user(page_address(req->r_pages[0]) + po, write_data, l)) { - ret = -EFAULT; - goto out; - } - - req->r_request->pages = req->r_pages; - req->r_request->nr_pages = req->r_nr_pages; - req->r_request->hdr.data_len = len; - req->r_request->hdr.data_off = off; - - reqhead->osdmap_epoch = osdc->osdmap->epoch; - send_request(osdc, req); - spin_unlock(&osdc->lock); - - /* wait */ - dout(10, "writepage tid %llu waiting for reply on %p\n", req->r_tid, req); - wait_for_completion(&req->r_completion); - dout(10, "writepage 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, "writepage result %d, returning %d\n", replyhead->result, (int)len); - ceph_msg_put(reply); - put_request(req); - - ret = len; - + struct ceph_msg *reqm, *reply; + struct ceph_osd_request_head *reqhead; + struct ceph_osd_request *req; + struct ceph_osd_reply_head *replyhead; + __u64 toff = off, tlen = len; + int po, l; + int ret = 0; + + /* request msg */ + reqm = new_request_msg(osdc, CEPH_OSD_OP_WRITE); + if (IS_ERR(reqm)) + return PTR_ERR(reqm); + reqhead = reqm->front.iov_base; + reqhead->oid.ino = ino; + reqhead->oid.rev = 0; + reqhead->flags = CEPH_OSD_OP_ACK|CEPH_OSD_OP_SAFE; /* want them both */ + calc_file_object_mapping(layout, &toff, &tlen, &reqhead->oid, + &reqhead->offset, &reqhead->length); + if (tlen != 0) { + dout(10, "not writing complete bit.. skipping last %llu, doing %llu~%llu\n", tlen, off, len); + len -= tlen; + } + calc_object_layout(&reqhead->layout, &reqhead->oid, layout, osdc->osdmap); + dout(10, "osdc_writepage object block %u %llu~%llu\n", reqhead->oid.bno, reqhead->offset, reqhead->length); + + /* register+send request */ + spin_lock(&osdc->lock); + req = register_request(osdc, reqm, 1); + if (IS_ERR(req)) { + ceph_msg_put(reqm); + spin_unlock(&osdc->lock); + return PTR_ERR(req); + } + + /* copy data into a page in a request message */ + req->r_pages[0] = alloc_pages(GFP_KERNEL, 1); + po = off & ~PAGE_MASK; + + l = min_t(int, PAGE_SIZE-po, len); + if (copy_from_user(page_address(req->r_pages[0]) + po, write_data, l)) { + ret = -EFAULT; + goto out; + } + + req->r_request->pages = req->r_pages; + req->r_request->nr_pages = req->r_nr_pages; + req->r_request->hdr.data_len = len; + req->r_request->hdr.data_off = off; + + reqhead->osdmap_epoch = osdc->osdmap->epoch; + send_request(osdc, req); + spin_unlock(&osdc->lock); + + /* wait */ + dout(10, "writepage tid %llu waiting for reply on %p\n", req->r_tid, req); + wait_for_completion(&req->r_completion); + dout(10, "writepage 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, "writepage result %d, returning %d\n", replyhead->result, (int)len); + ceph_msg_put(reply); + put_request(req); + + ret = len; + out: - return ret; + return ret; } diff --git a/src/kernel/osd_client.h b/src/kernel/osd_client.h index 4f2a18072e4ae..c65a85b16fca4 100644 --- a/src/kernel/osd_client.h +++ b/src/kernel/osd_client.h @@ -61,9 +61,23 @@ 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); +extern int ceph_osdc_readpages(struct ceph_osd_client *osdc, + struct address_space *mapping, + ceph_ino_t ino, + struct ceph_file_layout *layout, + struct list_head *pagels, int nr_pages); +extern int ceph_osdc_prepare_write(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_commit_write(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_writepage(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_silly_write(struct ceph_osd_client *osdc, ceph_ino_t ino, struct ceph_file_layout *layout, -- 2.39.5