Commit 4e563944 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ceph-for-5.3-rc6' of git://github.com/ceph/ceph-client

Pull ceph fixes from Ilya Dryomov:
 "Three important fixes tagged for stable (an indefinite hang, a crash
  on an assert and a NULL pointer dereference) plus a small series from
  Luis fixing instances of vfree() under spinlock"

* tag 'ceph-for-5.3-rc6' of git://github.com/ceph/ceph-client:
  libceph: fix PG split vs OSD (re)connect race
  ceph: don't try fill file_lock on unsuccessful GETFILELOCK reply
  ceph: clear page dirty before invalidate page
  ceph: fix buffer free while holding i_ceph_lock in fill_inode()
  ceph: fix buffer free while holding i_ceph_lock in __ceph_build_xattrs_blob()
  ceph: fix buffer free while holding i_ceph_lock in __ceph_setxattr()
  libceph: allow ceph_buffer_put() to receive a NULL ceph_buffer
parents 1374a22e a5613724
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -913,8 +913,9 @@ get_more_pages:
			if (page_offset(page) >= ceph_wbc.i_size) {
				dout("%p page eof %llu\n",
				     page, ceph_wbc.i_size);
				if (ceph_wbc.size_stable ||
				    page_offset(page) >= i_size_read(inode))
				if ((ceph_wbc.size_stable ||
				    page_offset(page) >= i_size_read(inode)) &&
				    clear_page_dirty_for_io(page))
					mapping->a_ops->invalidatepage(page,
								0, PAGE_SIZE);
				unlock_page(page);
+4 −1
Original line number Diff line number Diff line
@@ -1301,6 +1301,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
{
	struct ceph_inode_info *ci = cap->ci;
	struct inode *inode = &ci->vfs_inode;
	struct ceph_buffer *old_blob = NULL;
	struct cap_msg_args arg;
	int held, revoking;
	int wake = 0;
@@ -1365,7 +1366,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
	ci->i_requested_max_size = arg.max_size;

	if (flushing & CEPH_CAP_XATTR_EXCL) {
		__ceph_build_xattrs_blob(ci);
		old_blob = __ceph_build_xattrs_blob(ci);
		arg.xattr_version = ci->i_xattrs.version;
		arg.xattr_buf = ci->i_xattrs.blob;
	} else {
@@ -1409,6 +1410,8 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,

	spin_unlock(&ci->i_ceph_lock);

	ceph_buffer_put(old_blob);

	ret = send_cap_msg(&arg);
	if (ret < 0) {
		dout("error sending cap msg, must requeue %p\n", inode);
+4 −3
Original line number Diff line number Diff line
@@ -736,6 +736,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
	int issued, new_issued, info_caps;
	struct timespec64 mtime, atime, ctime;
	struct ceph_buffer *xattr_blob = NULL;
	struct ceph_buffer *old_blob = NULL;
	struct ceph_string *pool_ns = NULL;
	struct ceph_cap *new_cap = NULL;
	int err = 0;
@@ -881,7 +882,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
	if ((ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL))  &&
	    le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) {
		if (ci->i_xattrs.blob)
			ceph_buffer_put(ci->i_xattrs.blob);
			old_blob = ci->i_xattrs.blob;
		ci->i_xattrs.blob = xattr_blob;
		if (xattr_blob)
			memcpy(ci->i_xattrs.blob->vec.iov_base,
@@ -1022,7 +1023,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
out:
	if (new_cap)
		ceph_put_cap(mdsc, new_cap);
	if (xattr_blob)
	ceph_buffer_put(old_blob);
	ceph_buffer_put(xattr_blob);
	ceph_put_string(pool_ns);
	return err;
+1 −2
Original line number Diff line number Diff line
@@ -111,8 +111,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct inode *inode,
		req->r_wait_for_completion = ceph_lock_wait_for_completion;

	err = ceph_mdsc_do_request(mdsc, inode, req);

	if (operation == CEPH_MDS_OP_GETFILELOCK) {
	if (!err && operation == CEPH_MDS_OP_GETFILELOCK) {
		fl->fl_pid = -le64_to_cpu(req->r_reply_info.filelock_reply->pid);
		if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
			fl->fl_type = F_RDLCK;
+3 −1
Original line number Diff line number Diff line
@@ -465,6 +465,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
	struct inode *inode = &ci->vfs_inode;
	struct ceph_cap_snap *capsnap;
	struct ceph_snap_context *old_snapc, *new_snapc;
	struct ceph_buffer *old_blob = NULL;
	int used, dirty;

	capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS);
@@ -541,7 +542,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
	capsnap->gid = inode->i_gid;

	if (dirty & CEPH_CAP_XATTR_EXCL) {
		__ceph_build_xattrs_blob(ci);
		old_blob = __ceph_build_xattrs_blob(ci);
		capsnap->xattr_blob =
			ceph_buffer_get(ci->i_xattrs.blob);
		capsnap->xattr_version = ci->i_xattrs.version;
@@ -584,6 +585,7 @@ update_snapc:
	}
	spin_unlock(&ci->i_ceph_lock);

	ceph_buffer_put(old_blob);
	kfree(capsnap);
	ceph_put_snap_context(old_snapc);
}
Loading