diff options
author | Miloslav Trmač <mitr@redhat.com> | 2010-09-14 21:13:47 +0200 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2010-09-14 21:13:47 +0200 |
commit | c788635e2fddab3cb38685a6affa85deaacd0b06 (patch) | |
tree | 4bd4aaf3eb5a5df2c911df5026ff6d1fde5c1d24 | |
parent | 5b31c8f546a1561f23089657be4d51831b15b7ac (diff) | |
download | cryptodev-linux-c788635e2fddab3cb38685a6affa85deaacd0b06.tar.gz cryptodev-linux-c788635e2fddab3cb38685a6affa85deaacd0b06.tar.xz cryptodev-linux-c788635e2fddab3cb38685a6affa85deaacd0b06.zip |
Handle concurrency of ask->op_type
-rw-r--r-- | cryptodev_main.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/cryptodev_main.c b/cryptodev_main.c index f4799d6..93bb676 100644 --- a/cryptodev_main.c +++ b/cryptodev_main.c @@ -113,7 +113,10 @@ enum alg_op_type { /* A socket holding a crypto_tfm. */ struct alg_sock { struct sock sk; - enum alg_op_type op_type; + + /* enum alg_op_type; Only changes once, from OP_NONE */ + atomic_t op_type; + struct data_sock *slaves[1]; unsigned num_slaves, accept_idx; struct hash_data hash; @@ -141,6 +144,11 @@ static struct alg_sock *alg_sk(struct sock *sk) return container_of(sk, struct alg_sock, sk); } +static enum alg_op_type ask_op_type(struct alg_sock *ask) +{ + return atomic_read(&ask->op_type); +} + #ifdef DEBUG static void __dump_data_sock(int line, const struct data_sock *dsk) { @@ -156,18 +164,21 @@ static void __dump_alg_sock(int line, const struct alg_sock *ask) [OP_HASH] = "OP_HASH", }; - const char *type; + enum alg_op_type type; + const char *type_name; char type_buf[32]; - if (ask->op_type < ARRAY_SIZE(types) && types[ask->op_type] != NULL) - type = types[ask->op_type]; + type = ask_op_type(ask); + if (type < ARRAY_SIZE(types) && types[type] != NULL) + type_name = types[type]; else { sprintf(type_buf, "%d", (int)type); - type = type_buf; + type_name = type_buf; } printk(KERN_DEBUG "@%d: %p: cnt %d, %s, slave %p: %u/%u, hash %d\n", - line, ask, atomic_read(&ask->sk.sk_refcnt), type, ask->slaves[0], - ask->accept_idx, ask->num_slaves, ask->hash.init); + line, ask, atomic_read(&ask->sk.sk_refcnt), type_name, + ask->slaves[0], ask->accept_idx, ask->num_slaves, + ask->hash.init); } #define DUMP_ASK(ASK) (__dump_alg_sock(__LINE__, (ASK))) @@ -315,7 +326,7 @@ static int do_data_sendmsg(struct kiocb *iocb, struct alg_sock *ask, DUMP_ASK(ask); - switch (ask->op_type) { + switch (ask_op_type(ask)) { case OP_HASH: BUG_ON(index != 0); BUG_ON(ask->hash.init == 0); @@ -365,7 +376,7 @@ static int do_data_recvmsg(struct kiocb *iocb, struct alg_sock *ask, DUMP_ASK(ask); - switch (ask->op_type) { + switch (ask_op_type(ask)) { case OP_HASH: { char digest[NCR_HASH_MAX_OUTPUT_SIZE]; int res; @@ -443,7 +454,7 @@ static void alg_destruct(struct sock *sk) ask = alg_sk(sk); DUMP_ASK(ask); - switch (ask->op_type) { + switch (ask_op_type(ask)) { case OP_NONE: break; @@ -517,7 +528,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *myaddr, // FIXME: locking - if (ask->op_type != OP_NONE) + if (ask_op_type(ask) != OP_NONE) return -EINVAL; if (strncmp(addr->salg_type, "hash", sizeof(addr->salg_type)) == 0) { @@ -525,7 +536,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *myaddr, res = cryptodev_hash_init(&ask->hash, addr->salg_tfm, NULL, 0); if (res != 0) return res; - ask->op_type = OP_HASH; + atomic_set(&ask->op_type, OP_HASH); } else return -EINVAL; @@ -576,7 +587,7 @@ static int alg_listen(struct socket *sock, int len) if (ask->num_slaves != 0) return -EINVAL; - switch (ask->op_type) { + switch (ask_op_type(ask)) { case OP_NONE: return -EDESTADDRREQ; @@ -642,8 +653,7 @@ static int alg_sendmsg(struct kiocb *iocb, struct socket *sock, ask = alg_sk(sock->sk); DUMP_ASK(ask); - // FIXME: locking - if (ask->op_type == OP_NONE) + if (ask_op_type(ask) == OP_NONE) return -ENOTCONN; return do_data_sendmsg(iocb, ask, 0, m, total_len); @@ -654,12 +664,10 @@ static int alg_recvmsg(struct kiocb *iocb, struct socket *sock, { struct alg_sock *ask; - // FIXME: locking ask = alg_sk(sock->sk); DUMP_ASK(ask); - // FIXME: locking - if (ask->op_type == OP_NONE) + if (ask_op_type(ask) == OP_NONE) return -ENOTCONN; return do_data_recvmsg(iocb, ask, 0, m, total_len, flags); |