mirror of
https://github.com/ceph/ceph
synced 2025-01-10 05:00:59 +00:00
kclient: writepage cleanup, behaving
This commit is contained in:
parent
c2f5b52e95
commit
84f2bac28d
@ -62,43 +62,41 @@ out_unlock:
|
||||
*/
|
||||
static int ceph_writepage(struct page *page, struct writeback_control *wbc)
|
||||
{
|
||||
struct inode *inode = page->mapping->host;
|
||||
struct inode *inode;
|
||||
struct ceph_inode_info *ci;
|
||||
struct ceph_osd_client *osdc;
|
||||
loff_t page_off = page->index << PAGE_CACHE_SHIFT;
|
||||
int len = PAGE_CACHE_SIZE;
|
||||
loff_t i_size;
|
||||
int err = 0;
|
||||
|
||||
if (!page->mapping || !page->mapping->host)
|
||||
return -EFAULT;
|
||||
|
||||
inode = page->mapping->host;
|
||||
ci = ceph_inode(inode);
|
||||
osdc = &ceph_inode_to_client(inode)->osdc;
|
||||
|
||||
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",
|
||||
inode, page, page->index, page_off, len);
|
||||
|
||||
get_page(page);
|
||||
page_cache_get(page);
|
||||
set_page_writeback(page);
|
||||
SetPageUptodate(page);
|
||||
|
||||
dout(10, "ceph_writepage inode %p page %p index %lu\n",
|
||||
inode, page, page->index);
|
||||
|
||||
|
||||
|
||||
/* write a page at the index of page->index, by size of PAGE_SIZE */
|
||||
err = ceph_osdc_writepage(osdc, ceph_ino(inode), &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) {
|
||||
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:
|
||||
page_off, len, page);
|
||||
if (err >= 0)
|
||||
SetPageUptodate(page);
|
||||
//else
|
||||
//redirty_page_for_writepage(page); /* is this right?? */
|
||||
unlock_page(page);
|
||||
end_page_writeback(page);
|
||||
put_page(page);
|
||||
|
||||
page_cache_release(page);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -309,7 +307,6 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
|
||||
struct page *page, void *fsdata)
|
||||
{
|
||||
struct inode *inode = file->f_dentry->d_inode;
|
||||
unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
|
||||
|
||||
dout(10, "write_end file %p inode %p page %p %d~%d (%d)\n", file,
|
||||
inode, page, (int)pos, (int)copied, (int)len);
|
||||
|
@ -28,7 +28,7 @@ static int ceph_readpage_async(struct ceph_osd_client *osdc,
|
||||
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 page *page);
|
||||
|
||||
void ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
|
||||
{
|
||||
@ -482,7 +482,6 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
|
||||
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;
|
||||
}
|
||||
@ -571,7 +570,6 @@ int ceph_osdc_silly_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
|
||||
reply = req->r_reply;
|
||||
replyhead = reply->front.iov_base;
|
||||
dout(10, "silly_write result %d, returning %d\n", replyhead->result, (int)len);
|
||||
ceph_msg_put(reply);
|
||||
put_request(req);
|
||||
return (int)len;
|
||||
}
|
||||
@ -656,12 +654,8 @@ int ceph_osdc_commit_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = ceph_writepage_async(osdc, ino, layout, off, len, write_data);
|
||||
if (ret) {
|
||||
kunmap(page);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//ret = ceph_writepage_async(osdc, ino, layout, off, len, write_data);
|
||||
ret = len;
|
||||
kunmap(page);
|
||||
return ret;
|
||||
}
|
||||
@ -670,29 +664,17 @@ int ceph_osdc_commit_write(struct ceph_osd_client *osdc, ceph_ino_t ino,
|
||||
* Do write a single page, sending data to remote OSDs.
|
||||
*/
|
||||
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)
|
||||
struct ceph_file_layout *layout,
|
||||
loff_t off, loff_t len,
|
||||
struct page *page)
|
||||
{
|
||||
int ret = 0;
|
||||
char *write_data;
|
||||
|
||||
dout(10, "writepage on ino %llx at %lld~%lld\n", ino, off, len);
|
||||
BUG_ON(len > PAGE_SIZE);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
kmap(page);
|
||||
ret = ceph_writepage_async(osdc, ino, layout, off, len, page);
|
||||
kunmap(page);
|
||||
return ret;
|
||||
}
|
||||
@ -741,7 +723,6 @@ static int ceph_readpage_async(struct ceph_osd_client *osdc,
|
||||
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;
|
||||
@ -751,26 +732,32 @@ static int ceph_readpage_async(struct ceph_osd_client *osdc,
|
||||
* do a write job for one 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)
|
||||
struct ceph_file_layout *layout,
|
||||
loff_t off, loff_t len,
|
||||
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;
|
||||
__u64 toff = off, tlen = len;
|
||||
int po, l;
|
||||
int ret = 0;
|
||||
|
||||
/* request msg */
|
||||
/* request + msg */
|
||||
reqm = new_request_msg(osdc, CEPH_OSD_OP_WRITE);
|
||||
if (IS_ERR(reqm))
|
||||
return PTR_ERR(reqm);
|
||||
req = alloc_request(1);
|
||||
if (IS_ERR(req)) {
|
||||
ceph_msg_put(reqm);
|
||||
return PTR_ERR(req);
|
||||
}
|
||||
|
||||
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 */
|
||||
reqhead->flags = CEPH_OSD_OP_ACK; /* just ACK for now */
|
||||
|
||||
dout(10, "writepage_async getting object mapping on %llx %llu~%llu\n",
|
||||
ino, off, len);
|
||||
calc_file_object_mapping(layout, &toff, &tlen, &reqhead->oid,
|
||||
@ -785,33 +772,19 @@ static int ceph_writepage_async(struct ceph_osd_client *osdc, ceph_ino_t ino,
|
||||
dout(10, "writepage_async object block %u %llu~%llu\n",
|
||||
reqhead->oid.bno, reqhead->offset, reqhead->length);
|
||||
|
||||
req = alloc_request(1);
|
||||
if (IS_ERR(req))
|
||||
return PTR_ERR(req);
|
||||
|
||||
/* register+send request */
|
||||
spin_lock(&osdc->lock);
|
||||
req = register_request(osdc, reqm, 1, req);
|
||||
if (IS_ERR(req)) {
|
||||
ceph_msg_put(reqm);
|
||||
put_request(req);
|
||||
spin_unlock(&osdc->lock);
|
||||
return PTR_ERR(req);
|
||||
}
|
||||
|
||||
/* copy data into a page in a request message */
|
||||
dout(10, "writepage_async alloc\n");
|
||||
req->r_pages[0] = alloc_pages(GFP_KERNEL, 1);
|
||||
po = off & ~PAGE_MASK;
|
||||
|
||||
dout(10, "writepage_async copy\n");
|
||||
l = min_t(int, PAGE_SIZE-po, len);
|
||||
if (copy_from_user(page_address(req->r_pages[0]) + po, write_data, l)) {
|
||||
dout(10, "writepage_async fault\n");
|
||||
ret = -EFAULT;
|
||||
unregister_request(osdc, req);
|
||||
spin_unlock(&osdc->lock);
|
||||
goto out;
|
||||
}
|
||||
req->r_pages[0] = page;
|
||||
|
||||
req->r_request->pages = req->r_pages;
|
||||
req->r_request->nr_pages = req->r_nr_pages;
|
||||
@ -835,14 +808,8 @@ static int ceph_writepage_async(struct ceph_osd_client *osdc, ceph_ino_t ino,
|
||||
|
||||
reply = req->r_reply;
|
||||
replyhead = reply->front.iov_base;
|
||||
dout(10, "writepage_async result %d, returning %d\n",
|
||||
replyhead->result, (int)len);
|
||||
ceph_msg_put(reply);
|
||||
put_request(req);
|
||||
|
||||
ret = len;
|
||||
|
||||
out:
|
||||
ret = le32_to_cpu(replyhead->result);
|
||||
dout(10, "writepage_async result %d\n", ret);
|
||||
put_request(req);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user