From owner-p4-projects@FreeBSD.ORG Tue Nov 21 16:20:32 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 44CC816AEDB; Tue, 21 Nov 2006 16:20:29 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id A55C816ADD1 for ; Tue, 21 Nov 2006 16:20:28 +0000 (UTC) (envelope-from bushman@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6B48143E09 for ; Tue, 21 Nov 2006 16:19:01 +0000 (GMT) (envelope-from bushman@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kALGJ3vp045881 for ; Tue, 21 Nov 2006 16:19:03 GMT (envelope-from bushman@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kALGJ3c8045878 for perforce@freebsd.org; Tue, 21 Nov 2006 16:19:03 GMT (envelope-from bushman@freebsd.org) Date: Tue, 21 Nov 2006 16:19:03 GMT Message-Id: <200611211619.kALGJ3c8045878@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bushman@freebsd.org using -f From: Michael Bushkov To: Perforce Change Reviews Cc: Subject: PERFORCE change 110291 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Nov 2006 16:20:32 -0000 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 &