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

Commit bd355f8a 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: do not call __mark_dirty_inode under i_lock
  libceph: fix ceph_osdc_alloc_request error checks
  ceph: handle ceph_osdc_new_request failure in ceph_writepages_start
  libceph: fix ceph_msg_new error path
  ceph: use ihold() when i_lock is held
parents 1c08232c fca65b4a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -777,9 +777,9 @@ static int rbd_do_request(struct request *rq,
				      ops,
				      false,
				      GFP_NOIO, pages, bio);
	if (IS_ERR(req)) {
	if (!req) {
		up_read(&header->snap_rwsem);
		ret = PTR_ERR(req);
		ret = -ENOMEM;
		goto done_pages;
	}

+7 −0
Original line number Diff line number Diff line
@@ -775,6 +775,13 @@ get_more_pages:
					    ci->i_truncate_seq,
					    ci->i_truncate_size,
					    &inode->i_mtime, true, 1, 0);

				if (!req) {
					rc = -ENOMEM;
					unlock_page(page);
					break;
				}

				max_pages = req->r_num_pages;

				alloc_page_vec(fsc, req);
+7 −7
Original line number Diff line number Diff line
@@ -1331,10 +1331,11 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci)
}

/*
 * Mark caps dirty.  If inode is newly dirty, add to the global dirty
 * list.
 * Mark caps dirty.  If inode is newly dirty, return the dirty flags.
 * Caller is then responsible for calling __mark_inode_dirty with the
 * returned flags value.
 */
void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
{
	struct ceph_mds_client *mdsc =
		ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc;
@@ -1357,7 +1358,7 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
		list_add(&ci->i_dirty_item, &mdsc->cap_dirty);
		spin_unlock(&mdsc->cap_dirty_lock);
		if (ci->i_flushing_caps == 0) {
			igrab(inode);
			ihold(inode);
			dirty |= I_DIRTY_SYNC;
		}
	}
@@ -1365,9 +1366,8 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
	if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) &&
	    (mask & CEPH_CAP_FILE_BUFFER))
		dirty |= I_DIRTY_DATASYNC;
	if (dirty)
		__mark_inode_dirty(inode, dirty);
	__cap_delay_requeue(mdsc, ci);
	return dirty;
}

/*
@@ -1991,7 +1991,7 @@ static void __take_cap_refs(struct ceph_inode_info *ci, int got)
		ci->i_wr_ref++;
	if (got & CEPH_CAP_FILE_BUFFER) {
		if (ci->i_wrbuffer_ref == 0)
			igrab(&ci->vfs_inode);
			ihold(&ci->vfs_inode);
		ci->i_wrbuffer_ref++;
		dout("__take_cap_refs %p wrbuffer %d -> %d (?)\n",
		     &ci->vfs_inode, ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref);
+4 −1
Original line number Diff line number Diff line
@@ -734,9 +734,12 @@ retry_snap:
		}
	}
	if (ret >= 0) {
		int dirty;
		spin_lock(&inode->i_lock);
		__ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR);
		dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR);
		spin_unlock(&inode->i_lock);
		if (dirty)
			__mark_inode_dirty(inode, dirty);
	}

out:
+5 −1
Original line number Diff line number Diff line
@@ -1567,6 +1567,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
	int release = 0, dirtied = 0;
	int mask = 0;
	int err = 0;
	int inode_dirty_flags = 0;

	if (ceph_snap(inode) != CEPH_NOSNAP)
		return -EROFS;
@@ -1725,13 +1726,16 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
		dout("setattr %p ATTR_FILE ... hrm!\n", inode);

	if (dirtied) {
		__ceph_mark_dirty_caps(ci, dirtied);
		inode_dirty_flags = __ceph_mark_dirty_caps(ci, dirtied);
		inode->i_ctime = CURRENT_TIME;
	}

	release &= issued;
	spin_unlock(&inode->i_lock);

	if (inode_dirty_flags)
		__mark_inode_dirty(inode, inode_dirty_flags);

	if (mask) {
		req->r_inode = igrab(inode);
		req->r_inode_drop = release;
Loading