diff mbox

[2/2] layout-sim: allow non-conflicting LAYOUTGETs while in layout recall

Message ID 1296482588-4140-2-git-send-email-bhalevy@panasas.com (mailing list archive)
State RFC, archived
Headers show

Commit Message

Benny Halevy Jan. 31, 2011, 2:03 p.m. UTC
None
diff mbox

Patch

diff --git a/server.c b/server.c
index b9c90de..7119ab2 100644
--- a/server.c
+++ b/server.c
@@ -65,6 +65,7 @@  verify_stateid(struct msg *m)
 			/* FIXME: use an actual limit on parallelism */
 			return m->status = NFS4ERR_OLD_STATEID;
 		} else if (m->stateid.type == LAYOUT_STATEID) {
+			/* FIXME: is this specified for LAYOUTRETURN. */
 			if (srv_layout.layout_recall_msg &&
 		            m->stateid.seq < srv_layout.layout_recall_msg->stateid.seq)
 				return m->status = NFS4ERR_OLD_STATEID;
@@ -78,10 +79,26 @@  verify_stateid(struct msg *m)
 	return 0;
 }
 
+static bool
+is_conflicting(struct layout_range *lr, struct layout_range *r)
+{
+	if (lr->iomode != IOMODE_ANY && lr->iomode != r->iomode)
+		return false;
+	if (r->offset >= lr->offset)
+		return (lr->length == NFS4_MAX_UINT64) ||
+		       (lr->offset + lr->length > r->offset);
+	else
+		return (r->length == NFS4_MAX_UINT64) ||
+		       (r->offset + r->length > lr->offset);
+}
+
 static void
 srv_recv_layoutget(struct msg *m)
 {
-	if (srv_layout.layout_recall_msg) {
+	struct msg *lrm = srv_layout.layout_recall_msg;
+
+	/* See section 12.5.5.2.1.3 */
+	if (lrm && is_conflicting(&lrm->range, &m->range)) {
 		m->status = NFS4ERR_RECALLCONFLICT;
 		goto out;
 	}