diff options
| -rw-r--r-- | fs/ceph/caps.c | 31 | ||||
| -rw-r--r-- | fs/ceph/export.c | 21 | ||||
| -rw-r--r-- | fs/ceph/file.c | 2 | ||||
| -rw-r--r-- | fs/ceph/osd_client.c | 2 | 
4 files changed, 33 insertions, 23 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 73c153092f72..5e9da996a151 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2283,7 +2283,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,  {  	struct ceph_inode_info *ci = ceph_inode(inode);  	int mds = session->s_mds; -	int seq = le32_to_cpu(grant->seq); +	unsigned seq = le32_to_cpu(grant->seq); +	unsigned issue_seq = le32_to_cpu(grant->issue_seq);  	int newcaps = le32_to_cpu(grant->caps);  	int issued, implemented, used, wanted, dirty;  	u64 size = le64_to_cpu(grant->size); @@ -2295,8 +2296,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,  	int revoked_rdcache = 0;  	int queue_invalidate = 0; -	dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", -	     inode, cap, mds, seq, ceph_cap_string(newcaps)); +	dout("handle_cap_grant inode %p cap %p mds%d seq %u/%u %s\n", +	     inode, cap, mds, seq, issue_seq, ceph_cap_string(newcaps));  	dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,  		inode->i_size); @@ -2392,6 +2393,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,  	}  	cap->seq = seq; +	cap->issue_seq = issue_seq;  	/* file layout may have changed */  	ci->i_layout = grant->layout; @@ -2774,15 +2776,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,  		if (op == CEPH_CAP_OP_IMPORT)  			__queue_cap_release(session, vino.ino, cap_id,  					    mseq, seq); - -		/* -		 * send any full release message to try to move things -		 * along for the mds (who clearly thinks we still have this -		 * cap). -		 */ -		ceph_add_cap_releases(mdsc, session); -		ceph_send_cap_releases(mdsc, session); -		goto done; +		goto flush_cap_releases;  	}  	/* these will work even if we don't have a cap yet */ @@ -2810,7 +2804,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,  		dout(" no cap on %p ino %llx.%llx from mds%d\n",  		     inode, ceph_ino(inode), ceph_snap(inode), mds);  		spin_unlock(&inode->i_lock); -		goto done; +		goto flush_cap_releases;  	}  	/* note that each of these drops i_lock for us */ @@ -2834,6 +2828,17 @@ void ceph_handle_caps(struct ceph_mds_session *session,  		       ceph_cap_op_name(op));  	} +	goto done; + +flush_cap_releases: +	/* +	 * send any full release message to try to move things +	 * along for the mds (who clearly thinks we still have this +	 * cap). +	 */ +	ceph_add_cap_releases(mdsc, session); +	ceph_send_cap_releases(mdsc, session); +  done:  	mutex_unlock(&session->s_mutex);  done_unlocked: diff --git a/fs/ceph/export.c b/fs/ceph/export.c index 4480cb1c63e7..e38423e82f2e 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c @@ -42,32 +42,37 @@ struct ceph_nfs_confh {  static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,  			  int connectable)  { +	int type;  	struct ceph_nfs_fh *fh = (void *)rawfh;  	struct ceph_nfs_confh *cfh = (void *)rawfh;  	struct dentry *parent = dentry->d_parent;  	struct inode *inode = dentry->d_inode; -	int type; +	int connected_handle_length = sizeof(*cfh)/4; +	int handle_length = sizeof(*fh)/4;  	/* don't re-export snaps */  	if (ceph_snap(inode) != CEPH_NOSNAP)  		return -EINVAL; -	if (*max_len >= sizeof(*cfh)) { +	if (*max_len >= connected_handle_length) {  		dout("encode_fh %p connectable\n", dentry);  		cfh->ino = ceph_ino(dentry->d_inode);  		cfh->parent_ino = ceph_ino(parent->d_inode);  		cfh->parent_name_hash = parent->d_name.hash; -		*max_len = sizeof(*cfh); +		*max_len = connected_handle_length;  		type = 2; -	} else if (*max_len > sizeof(*fh)) { -		if (connectable) -			return -ENOSPC; +	} else if (*max_len >= handle_length) { +		if (connectable) { +			*max_len = connected_handle_length; +			return 255; +		}  		dout("encode_fh %p\n", dentry);  		fh->ino = ceph_ino(dentry->d_inode); -		*max_len = sizeof(*fh); +		*max_len = handle_length;  		type = 1;  	} else { -		return -ENOSPC; +		*max_len = handle_length; +		return 255;  	}  	return type;  } diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 8c044a4f0457..66e4da6dba22 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -697,7 +697,7 @@ more:  			 * start_request so that a tid has been assigned.  			 */  			spin_lock(&ci->i_unsafe_lock); -			list_add(&ci->i_unsafe_writes, &req->r_unsafe_item); +			list_add(&req->r_unsafe_item, &ci->i_unsafe_writes);  			spin_unlock(&ci->i_unsafe_lock);  			ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR);  		} diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index dfced1dacbcd..3b5571b8ce22 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -549,7 +549,7 @@ static void __unregister_request(struct ceph_osd_client *osdc,   */  static void __cancel_request(struct ceph_osd_request *req)  { -	if (req->r_sent) { +	if (req->r_sent && req->r_osd) {  		ceph_con_revoke(&req->r_osd->o_con, req->r_request);  		req->r_sent = 0;  	}  | 
