Commit 33caad32 authored by Sage Weil's avatar Sage Weil

ceph: perform lazy writes when file mode and caps permit

If we have marked a file as "lazy" (using the ceph ioctl), perform buffered
writes when the MDS caps allow it.
Signed-off-by: default avatarSage Weil <sage@newdream.net>
parent 8c6e9229
...@@ -337,8 +337,7 @@ static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds) ...@@ -337,8 +337,7 @@ static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
} }
/* /*
* Return id of any MDS with a cap, preferably FILE_WR|WRBUFFER|EXCL, else * Return id of any MDS with a cap, preferably FILE_WR|BUFFER|EXCL, else -1.
* -1.
*/ */
static int __ceph_get_cap_mds(struct ceph_inode_info *ci, u32 *mseq) static int __ceph_get_cap_mds(struct ceph_inode_info *ci, u32 *mseq)
{ {
...@@ -346,7 +345,7 @@ static int __ceph_get_cap_mds(struct ceph_inode_info *ci, u32 *mseq) ...@@ -346,7 +345,7 @@ static int __ceph_get_cap_mds(struct ceph_inode_info *ci, u32 *mseq)
int mds = -1; int mds = -1;
struct rb_node *p; struct rb_node *p;
/* prefer mds with WR|WRBUFFER|EXCL caps */ /* prefer mds with WR|BUFFER|EXCL caps */
for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
cap = rb_entry(p, struct ceph_cap, ci_node); cap = rb_entry(p, struct ceph_cap, ci_node);
mds = cap->mds; mds = cap->mds;
...@@ -831,7 +830,7 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci) ...@@ -831,7 +830,7 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
{ {
int want = 0; int want = 0;
int mode; int mode;
for (mode = 0; mode < 4; mode++) for (mode = 0; mode < CEPH_FILE_MODE_NUM; mode++)
if (ci->i_nr_by_mode[mode]) if (ci->i_nr_by_mode[mode])
want |= ceph_caps_for_mode(mode); want |= ceph_caps_for_mode(mode);
return want; return want;
......
...@@ -807,11 +807,12 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -807,11 +807,12 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos) unsigned long nr_segs, loff_t pos)
{ {
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct ceph_file_info *fi = file->private_data;
struct inode *inode = file->f_dentry->d_inode; struct inode *inode = file->f_dentry->d_inode;
struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_inode_info *ci = ceph_inode(inode);
struct ceph_osd_client *osdc = &ceph_sb_to_client(inode->i_sb)->osdc; struct ceph_osd_client *osdc = &ceph_sb_to_client(inode->i_sb)->osdc;
loff_t endoff = pos + iov->iov_len; loff_t endoff = pos + iov->iov_len;
int got = 0; int want, got = 0;
int ret, err; int ret, err;
if (ceph_snap(inode) != CEPH_NOSNAP) if (ceph_snap(inode) != CEPH_NOSNAP)
...@@ -824,8 +825,11 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -824,8 +825,11 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
dout("aio_write %p %llx.%llx %llu~%u getting caps. i_size %llu\n", dout("aio_write %p %llx.%llx %llu~%u getting caps. i_size %llu\n",
inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
inode->i_size); inode->i_size);
ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER, if (fi->fmode & CEPH_FILE_MODE_LAZY)
&got, endoff); want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
else
want = CEPH_CAP_FILE_BUFFER;
ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, &got, endoff);
if (ret < 0) if (ret < 0)
goto out; goto out;
...@@ -833,7 +837,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -833,7 +837,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
ceph_cap_string(got)); ceph_cap_string(got));
if ((got & CEPH_CAP_FILE_BUFFER) == 0 || if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 ||
(iocb->ki_filp->f_flags & O_DIRECT) || (iocb->ki_filp->f_flags & O_DIRECT) ||
(inode->i_sb->s_flags & MS_SYNCHRONOUS)) { (inode->i_sb->s_flags & MS_SYNCHRONOUS)) {
ret = ceph_sync_write(file, iov->iov_base, iov->iov_len, ret = ceph_sync_write(file, iov->iov_base, iov->iov_len,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment