Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ffdb8f1b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
  ceph: unwind canceled flock state
  ceph: fix ENOENT logic in striped_read
  ceph: fix short sync reads from the OSD
  ceph: fix sync vs canceled write
  ceph: use ihold when we already have an inode ref
parents 80dadf86 0c1f91f2
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -453,7 +453,7 @@ static int ceph_writepage(struct page *page, struct writeback_control *wbc)
	int err;
	int err;
	struct inode *inode = page->mapping->host;
	struct inode *inode = page->mapping->host;
	BUG_ON(!inode);
	BUG_ON(!inode);
	igrab(inode);
	ihold(inode);
	err = writepage_nounlock(page, wbc);
	err = writepage_nounlock(page, wbc);
	unlock_page(page);
	unlock_page(page);
	iput(inode);
	iput(inode);
+4 −6
Original line number Original line Diff line number Diff line
@@ -2940,14 +2940,12 @@ void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc)
	while (!list_empty(&mdsc->cap_dirty)) {
	while (!list_empty(&mdsc->cap_dirty)) {
		ci = list_first_entry(&mdsc->cap_dirty, struct ceph_inode_info,
		ci = list_first_entry(&mdsc->cap_dirty, struct ceph_inode_info,
				      i_dirty_item);
				      i_dirty_item);
		inode = igrab(&ci->vfs_inode);
		inode = &ci->vfs_inode;
		ihold(inode);
		dout("flush_dirty_caps %p\n", inode);
		dout("flush_dirty_caps %p\n", inode);
		spin_unlock(&mdsc->cap_dirty_lock);
		spin_unlock(&mdsc->cap_dirty_lock);
		if (inode) {
		ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, NULL);
			ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH,
					NULL);
		iput(inode);
		iput(inode);
		}
		spin_lock(&mdsc->cap_dirty_lock);
		spin_lock(&mdsc->cap_dirty_lock);
	}
	}
	spin_unlock(&mdsc->cap_dirty_lock);
	spin_unlock(&mdsc->cap_dirty_lock);
+7 −4
Original line number Original line Diff line number Diff line
@@ -308,7 +308,8 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
		req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
		req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
		if (IS_ERR(req))
		if (IS_ERR(req))
			return PTR_ERR(req);
			return PTR_ERR(req);
		req->r_inode = igrab(inode);
		req->r_inode = inode;
		ihold(inode);
		req->r_dentry = dget(filp->f_dentry);
		req->r_dentry = dget(filp->f_dentry);
		/* hints to request -> mds selection code */
		/* hints to request -> mds selection code */
		req->r_direct_mode = USE_AUTH_MDS;
		req->r_direct_mode = USE_AUTH_MDS;
@@ -787,10 +788,12 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
	err = ceph_mdsc_do_request(mdsc, dir, req);
	err = ceph_mdsc_do_request(mdsc, dir, req);
	if (err)
	if (err) {
		d_drop(dentry);
		d_drop(dentry);
	else if (!req->r_reply_info.head->is_dentry)
	} else if (!req->r_reply_info.head->is_dentry) {
		d_instantiate(dentry, igrab(old_dentry->d_inode));
		ihold(old_dentry->d_inode);
		d_instantiate(dentry, old_dentry->d_inode);
	}
	ceph_mdsc_put_request(req);
	ceph_mdsc_put_request(req);
	return err;
	return err;
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -109,7 +109,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
		err = ceph_mdsc_do_request(mdsc, NULL, req);
		err = ceph_mdsc_do_request(mdsc, NULL, req);
		inode = req->r_target_inode;
		inode = req->r_target_inode;
		if (inode)
		if (inode)
			igrab(inode);
			ihold(inode);
		ceph_mdsc_put_request(req);
		ceph_mdsc_put_request(req);
		if (!inode)
		if (!inode)
			return ERR_PTR(-ESTALE);
			return ERR_PTR(-ESTALE);
@@ -167,7 +167,7 @@ static struct dentry *__cfh_to_dentry(struct super_block *sb,
		err = ceph_mdsc_do_request(mdsc, NULL, req);
		err = ceph_mdsc_do_request(mdsc, NULL, req);
		inode = req->r_target_inode;
		inode = req->r_target_inode;
		if (inode)
		if (inode)
			igrab(inode);
			ihold(inode);
		ceph_mdsc_put_request(req);
		ceph_mdsc_put_request(req);
		if (!inode)
		if (!inode)
			return ERR_PTR(err ? err : -ESTALE);
			return ERR_PTR(err ? err : -ESTALE);
+19 −16
Original line number Original line Diff line number Diff line
@@ -191,7 +191,8 @@ int ceph_open(struct inode *inode, struct file *file)
		err = PTR_ERR(req);
		err = PTR_ERR(req);
		goto out;
		goto out;
	}
	}
	req->r_inode = igrab(inode);
	req->r_inode = inode;
	ihold(inode);
	req->r_num_caps = 1;
	req->r_num_caps = 1;
	err = ceph_mdsc_do_request(mdsc, parent_inode, req);
	err = ceph_mdsc_do_request(mdsc, parent_inode, req);
	if (!err)
	if (!err)
@@ -282,7 +283,7 @@ int ceph_release(struct inode *inode, struct file *file)
static int striped_read(struct inode *inode,
static int striped_read(struct inode *inode,
			u64 off, u64 len,
			u64 off, u64 len,
			struct page **pages, int num_pages,
			struct page **pages, int num_pages,
			int *checkeof, bool align_to_pages,
			int *checkeof, bool o_direct,
			unsigned long buf_align)
			unsigned long buf_align)
{
{
	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
@@ -307,7 +308,7 @@ static int striped_read(struct inode *inode,
	io_align = off & ~PAGE_MASK;
	io_align = off & ~PAGE_MASK;


more:
more:
	if (align_to_pages)
	if (o_direct)
		page_align = (pos - io_align + buf_align) & ~PAGE_MASK;
		page_align = (pos - io_align + buf_align) & ~PAGE_MASK;
	else
	else
		page_align = pos & ~PAGE_MASK;
		page_align = pos & ~PAGE_MASK;
@@ -317,10 +318,10 @@ static int striped_read(struct inode *inode,
				  ci->i_truncate_seq,
				  ci->i_truncate_seq,
				  ci->i_truncate_size,
				  ci->i_truncate_size,
				  page_pos, pages_left, page_align);
				  page_pos, pages_left, page_align);
	hit_stripe = this_len < left;
	was_short = ret >= 0 && ret < this_len;
	if (ret == -ENOENT)
	if (ret == -ENOENT)
		ret = 0;
		ret = 0;
	hit_stripe = this_len < left;
	was_short = ret >= 0 && ret < this_len;
	dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read,
	dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read,
	     ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
	     ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");


@@ -345,20 +346,22 @@ static int striped_read(struct inode *inode,
	}
	}


	if (was_short) {
	if (was_short) {
		/* was original extent fully inside i_size? */
		/* did we bounce off eof? */
		if (pos + left <= inode->i_size) {
		if (pos + left > inode->i_size)
			dout("zero tail\n");
			*checkeof = 1;
			ceph_zero_page_vector_range(page_off + read, len - read,

		/* zero trailing bytes (inside i_size) */
		if (left > 0 && pos < inode->i_size) {
			if (pos + left > inode->i_size)
				left = inode->i_size - pos;

			dout("zero tail %d\n", left);
			ceph_zero_page_vector_range(page_off + read, left,
						    pages);
						    pages);
			read = len;
			read += left;
			goto out;
		}
		}

		/* check i_size */
		*checkeof = 1;
	}
	}


out:
	if (ret >= 0)
	if (ret >= 0)
		ret = read;
		ret = read;
	dout("striped_read returns %d\n", ret);
	dout("striped_read returns %d\n", ret);
@@ -658,7 +661,7 @@ static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,


		/* hit EOF or hole? */
		/* hit EOF or hole? */
		if (statret == 0 && *ppos < inode->i_size) {
		if (statret == 0 && *ppos < inode->i_size) {
			dout("aio_read sync_read hit hole, reading more\n");
			dout("aio_read sync_read hit hole, ppos %lld < size %lld, reading more\n", *ppos, inode->i_size);
			read += ret;
			read += ret;
			base += ret;
			base += ret;
			len -= ret;
			len -= ret;
Loading