Date: Tue, 21 Nov 2006 17:18:14 GMT From: Michael Bushkov <bushman@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 110291 for review Message-ID: <200611211718.kALHIEuD068573@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=110291 Change 110291 by bushman@bushman_nss_ldap_cached on 2006/11/20 11:09:09 + Now, before writing something to cache, we check for such element existence. With this check we now avoid some race-condition situations, when 2 program write similar data to the same cache entry. Affected files ... .. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/query.c#10 edit Differences ... ==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/query.c#10 (text) ==== @@ -339,6 +339,7 @@ struct cache_write_request *write_request; struct cache_write_response *write_response; cache_entry c_entry; + size_t tdata_size; TRACE_IN(on_write_request_process); init_comm_element(&qstate->response, CET_WRITE_RESPONSE); @@ -386,19 +387,35 @@ if (c_entry != NULL) { configuration_lock_entry(qstate->config_entry, CELT_POSITIVE); qstate->config_entry->positive_cache_entry = c_entry; - write_response->error_code = cache_write(c_entry, + + /* checking if there is already a record in the cache */ + write_response->error_code = cache_read(c_entry, write_request->cache_key, - write_request->cache_key_size, - write_request->data, - write_request->data_size); - configuration_unlock_entry(qstate->config_entry, CELT_POSITIVE); + write_request->cache_key_size, NULL, + &tdata_size); + + if (write_response->error_code == -1) { + write_response->error_code = cache_write(c_entry, + write_request->cache_key, write_request->cache_key_size, + write_request->data, write_request->data_size); - if ((qstate->config_entry->common_query_timeout.tv_sec != 0) || - (qstate->config_entry->common_query_timeout.tv_usec != 0)) + if ((qstate->config_entry->common_query_timeout.tv_sec + != 0) || + (qstate->config_entry->common_query_timeout.tv_usec + != 0)) memcpy(&qstate->timeout, - &qstate->config_entry->common_query_timeout, - sizeof(struct timeval)); - + &qstate->config_entry->common_query_timeout, + sizeof(struct timeval)); + } else { + LOG_ERR_2("write_request", + "trying to write to entry '%s', despite that " + "there is already an element with specified " + "key in the cache", write_request->entry); + + write_response->error_code = -1; + } + + configuration_unlock_entry(qstate->config_entry, CELT_POSITIVE); } else write_response->error_code = -1; @@ -417,6 +434,7 @@ struct cache_write_request *write_request; struct cache_write_response *write_response; cache_entry c_entry; + size_t tdata_size; TRACE_IN(on_negative_write_request_process); init_comm_element(&qstate->response, CET_WRITE_RESPONSE); @@ -468,20 +486,37 @@ if (c_entry != NULL) { configuration_lock_entry(qstate->config_entry, CELT_NEGATIVE); qstate->config_entry->negative_cache_entry = c_entry; - write_response->error_code = cache_write(c_entry, + + write_response->error_code = cache_read(c_entry, write_request->cache_key, - write_request->cache_key_size, - negative_data, - sizeof(negative_data)); + write_request->cache_key_size, + NULL, + &tdata_size); + if (write_response->error_code == -1) { + write_response->error_code = cache_write(c_entry, + write_request->cache_key, write_request->cache_key_size, + negative_data, sizeof(negative_data)); + + if ((qstate->config_entry->common_query_timeout.tv_sec + != 0) || + (qstate->config_entry->common_query_timeout.tv_usec + != 0)) + memcpy(&qstate->timeout, + &qstate->config_entry->common_query_timeout, + sizeof(struct timeval)); + } else + write_response->error_code = -1; + configuration_unlock_entry(qstate->config_entry, CELT_NEGATIVE); - - if ((qstate->config_entry->common_query_timeout.tv_sec != 0) || - (qstate->config_entry->common_query_timeout.tv_usec != 0)) - memcpy(&qstate->timeout, - &qstate->config_entry->common_query_timeout, - sizeof(struct timeval)); - } else + } else { + LOG_ERR_2("write_request", + "trying to write negative request to entry " + "'%s', despite that " + "there is already an element with specified " + "key in the cache", write_request->entry); + write_response->error_code = -1; + } fin: qstate->kevent_filter = EVFILT_WRITE; @@ -697,9 +732,11 @@ } configuration_unlock_entry(qstate->config_entry, CELT_POSITIVE); - configuration_lock_entry(qstate->config_entry, CELT_NEGATIVE); - qstate->config_entry->negative_cache_entry = neg_c_entry; if (read_response->error_code == -1) { + configuration_lock_entry(qstate->config_entry, + CELT_NEGATIVE); + qstate->config_entry->negative_cache_entry = + neg_c_entry; read_response->error_code = cache_read(neg_c_entry, read_request->cache_key, read_request->cache_key_size, NULL, @@ -710,8 +747,9 @@ read_response->data = NULL; read_response->data_size = 0; } - } - configuration_unlock_entry(qstate->config_entry, CELT_NEGATIVE); + configuration_unlock_entry(qstate->config_entry, + CELT_NEGATIVE); + } if ((read_response->error_code == -1) && (qstate->config_entry->flags &
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611211718.kALHIEuD068573>