|
@@ -382,11 +382,62 @@ static void release_openowner(struct nfs4_stateowner *sop)
|
|
nfs4_put_stateowner(sop);
|
|
nfs4_put_stateowner(sop);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static DEFINE_SPINLOCK(sessionid_lock);
|
|
|
|
+#define SESSION_HASH_SIZE 512
|
|
|
|
+static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE];
|
|
|
|
+
|
|
|
|
+static inline int
|
|
|
|
+hash_sessionid(struct nfs4_sessionid *sessionid)
|
|
|
|
+{
|
|
|
|
+ struct nfsd4_sessionid *sid = (struct nfsd4_sessionid *)sessionid;
|
|
|
|
+
|
|
|
|
+ return sid->sequence % SESSION_HASH_SIZE;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void
|
|
|
|
+dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
|
|
|
|
+{
|
|
|
|
+ u32 *ptr = (u32 *)(&sessionid->data[0]);
|
|
|
|
+ dprintk("%s: %u:%u:%u:%u\n", fn, ptr[0], ptr[1], ptr[2], ptr[3]);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* caller must hold sessionid_lock */
|
|
|
|
+static struct nfsd4_session *
|
|
|
|
+find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid)
|
|
|
|
+{
|
|
|
|
+ struct nfsd4_session *elem;
|
|
|
|
+ int idx;
|
|
|
|
+
|
|
|
|
+ dump_sessionid(__func__, sessionid);
|
|
|
|
+ idx = hash_sessionid(sessionid);
|
|
|
|
+ dprintk("%s: idx is %d\n", __func__, idx);
|
|
|
|
+ /* Search in the appropriate list */
|
|
|
|
+ list_for_each_entry(elem, &sessionid_hashtbl[idx], se_hash) {
|
|
|
|
+ dump_sessionid("list traversal", &elem->se_sessionid);
|
|
|
|
+ if (!memcmp(elem->se_sessionid.data, sessionid->data,
|
|
|
|
+ NFS4_MAX_SESSIONID_LEN)) {
|
|
|
|
+ return elem;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dprintk("%s: session not found\n", __func__);
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* caller must hold sessionid_lock */
|
|
static void
|
|
static void
|
|
-release_session(struct nfsd4_session *ses)
|
|
|
|
|
|
+unhash_session(struct nfsd4_session *ses)
|
|
{
|
|
{
|
|
list_del(&ses->se_hash);
|
|
list_del(&ses->se_hash);
|
|
list_del(&ses->se_perclnt);
|
|
list_del(&ses->se_perclnt);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void
|
|
|
|
+release_session(struct nfsd4_session *ses)
|
|
|
|
+{
|
|
|
|
+ spin_lock(&sessionid_lock);
|
|
|
|
+ unhash_session(ses);
|
|
|
|
+ spin_unlock(&sessionid_lock);
|
|
nfsd4_put_session(ses);
|
|
nfsd4_put_session(ses);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3205,6 +3256,8 @@ nfs4_state_init(void)
|
|
INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
|
|
INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
|
|
INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
|
|
INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
|
|
}
|
|
}
|
|
|
|
+ for (i = 0; i < SESSION_HASH_SIZE; i++)
|
|
|
|
+ INIT_LIST_HEAD(&sessionid_hashtbl[i]);
|
|
for (i = 0; i < FILE_HASH_SIZE; i++) {
|
|
for (i = 0; i < FILE_HASH_SIZE; i++) {
|
|
INIT_LIST_HEAD(&file_hashtbl[i]);
|
|
INIT_LIST_HEAD(&file_hashtbl[i]);
|
|
}
|
|
}
|