Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: (23 commits) ceph: document unlocked d_parent accesses ceph: explicitly reference rename old_dentry parent dir in request ceph: document locking for ceph_set_dentry_offset ceph: avoid d_parent in ceph_dentry_hash; fix ceph_encode_fh() hashing bug ceph: protect d_parent access in ceph_d_revalidate ceph: protect access to d_parent ceph: handle racing calls to ceph_init_dentry ceph: set dir complete frag after adding capability rbd: set blk_queue request sizes to object size ceph: set up readahead size when rsize is not passed rbd: cancel watch request when releasing the device ceph: ignore lease mask ceph: fix ceph_lookup_open intent usage ceph: only link open operations to directory unsafe list if O_CREAT|O_TRUNC ceph: fix bad parent_inode calc in ceph_lookup_open ceph: avoid carrying Fw cap during write into page cache libceph: don't time out osd requests that haven't been received ceph: report f_bfree based on kb_avail rather than diffing. ceph: only queue capsnap if caps are dirty ceph: fix snap writeback when racing with writes ...
This commit is contained in:
@@ -122,7 +122,7 @@ int ceph_open(struct inode *inode, struct file *file)
|
||||
struct ceph_mds_client *mdsc = fsc->mdsc;
|
||||
struct ceph_mds_request *req;
|
||||
struct ceph_file_info *cf = file->private_data;
|
||||
struct inode *parent_inode = file->f_dentry->d_parent->d_inode;
|
||||
struct inode *parent_inode = NULL;
|
||||
int err;
|
||||
int flags, fmode, wanted;
|
||||
|
||||
@@ -194,7 +194,10 @@ int ceph_open(struct inode *inode, struct file *file)
|
||||
req->r_inode = inode;
|
||||
ihold(inode);
|
||||
req->r_num_caps = 1;
|
||||
if (flags & (O_CREAT|O_TRUNC))
|
||||
parent_inode = ceph_get_dentry_parent_inode(file->f_dentry);
|
||||
err = ceph_mdsc_do_request(mdsc, parent_inode, req);
|
||||
iput(parent_inode);
|
||||
if (!err)
|
||||
err = ceph_init_file(inode, file, req->r_fmode);
|
||||
ceph_mdsc_put_request(req);
|
||||
@@ -222,9 +225,9 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
||||
{
|
||||
struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
|
||||
struct ceph_mds_client *mdsc = fsc->mdsc;
|
||||
struct file *file = nd->intent.open.file;
|
||||
struct inode *parent_inode = get_dentry_parent_inode(file->f_dentry);
|
||||
struct file *file;
|
||||
struct ceph_mds_request *req;
|
||||
struct dentry *ret;
|
||||
int err;
|
||||
int flags = nd->intent.open.flags;
|
||||
|
||||
@@ -242,16 +245,24 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
||||
req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
|
||||
}
|
||||
req->r_locked_dir = dir; /* caller holds dir->i_mutex */
|
||||
err = ceph_mdsc_do_request(mdsc, parent_inode, req);
|
||||
dentry = ceph_finish_lookup(req, dentry, err);
|
||||
if (!err && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
|
||||
err = ceph_mdsc_do_request(mdsc,
|
||||
(flags & (O_CREAT|O_TRUNC)) ? dir : NULL,
|
||||
req);
|
||||
err = ceph_handle_snapdir(req, dentry, err);
|
||||
if (err)
|
||||
goto out;
|
||||
if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
|
||||
err = ceph_handle_notrace_create(dir, dentry);
|
||||
if (!err)
|
||||
err = ceph_init_file(req->r_dentry->d_inode, file,
|
||||
req->r_fmode);
|
||||
if (err)
|
||||
goto out;
|
||||
file = lookup_instantiate_filp(nd, req->r_dentry, ceph_open);
|
||||
if (IS_ERR(file))
|
||||
err = PTR_ERR(file);
|
||||
out:
|
||||
ret = ceph_finish_lookup(req, dentry, err);
|
||||
ceph_mdsc_put_request(req);
|
||||
dout("ceph_lookup_open result=%p\n", dentry);
|
||||
return dentry;
|
||||
dout("ceph_lookup_open result=%p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ceph_release(struct inode *inode, struct file *file)
|
||||
@@ -643,7 +654,8 @@ again:
|
||||
|
||||
if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 ||
|
||||
(iocb->ki_filp->f_flags & O_DIRECT) ||
|
||||
(inode->i_sb->s_flags & MS_SYNCHRONOUS))
|
||||
(inode->i_sb->s_flags & MS_SYNCHRONOUS) ||
|
||||
(fi->flags & CEPH_F_SYNC))
|
||||
/* hmm, this isn't really async... */
|
||||
ret = ceph_sync_read(filp, base, len, ppos, &checkeof);
|
||||
else
|
||||
@@ -712,7 +724,7 @@ retry_snap:
|
||||
want = CEPH_CAP_FILE_BUFFER;
|
||||
ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, &got, endoff);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
goto out_put;
|
||||
|
||||
dout("aio_write %p %llx.%llx %llu~%u got cap refs on %s\n",
|
||||
inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
|
||||
@@ -720,12 +732,23 @@ retry_snap:
|
||||
|
||||
if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 ||
|
||||
(iocb->ki_filp->f_flags & O_DIRECT) ||
|
||||
(inode->i_sb->s_flags & MS_SYNCHRONOUS)) {
|
||||
(inode->i_sb->s_flags & MS_SYNCHRONOUS) ||
|
||||
(fi->flags & CEPH_F_SYNC)) {
|
||||
ret = ceph_sync_write(file, iov->iov_base, iov->iov_len,
|
||||
&iocb->ki_pos);
|
||||
} else {
|
||||
ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
|
||||
/*
|
||||
* buffered write; drop Fw early to avoid slow
|
||||
* revocation if we get stuck on balance_dirty_pages
|
||||
*/
|
||||
int dirty;
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR);
|
||||
spin_unlock(&inode->i_lock);
|
||||
ceph_put_cap_refs(ci, got);
|
||||
|
||||
ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
|
||||
if ((ret >= 0 || ret == -EIOCBQUEUED) &&
|
||||
((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host)
|
||||
|| ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) {
|
||||
@@ -733,7 +756,12 @@ retry_snap:
|
||||
if (err < 0)
|
||||
ret = err;
|
||||
}
|
||||
|
||||
if (dirty)
|
||||
__mark_inode_dirty(inode, dirty);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
int dirty;
|
||||
spin_lock(&inode->i_lock);
|
||||
@@ -743,12 +771,13 @@ retry_snap:
|
||||
__mark_inode_dirty(inode, dirty);
|
||||
}
|
||||
|
||||
out:
|
||||
out_put:
|
||||
dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n",
|
||||
inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
|
||||
ceph_cap_string(got));
|
||||
ceph_put_cap_refs(ci, got);
|
||||
|
||||
out:
|
||||
if (ret == -EOLDSNAPC) {
|
||||
dout("aio_write %p %llx.%llx %llu~%u got EOLDSNAPC, retrying\n",
|
||||
inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len);
|
||||
|
Reference in New Issue
Block a user