Thanks George. The code in dbuf_do_evict() will not
attempt to get the mutex again as it is held already.
This mutex_enter() is simply to avoid acquiring it twice
and not a synchonization lock.

Bhaskar

> 
> In the code below, dbuf_find() will return with db_mtx locked which will 
> prevent dbuf_do_evict() from proceedin as it will block waiting on this 
> mutex:
> 
> dbuf_do_evict(void *private)
> {
>          if (!MUTEX_HELD(&db->db_mtx))
>                  mutex_enter(&db->db_mtx);
> 
> Thanks,
> George
> 
> Bhaskar Sarkar wrote:
>> Hi,
>>
>> Can a dbuf be in DB_CACHED state, db_holds == 0,
>> b_efunc != NULL while its db_buf is put on the
>> eviction list ?  From an ASSERT in dbuf_do_evict(),
>> it appears that it can. If it can, I am wondering what
>> is preventing the following race
>>
>> dbuf_hold_impl()
>>      db = dbuf_find(dn, level, blkid);
>>
>>      ...
>>      if (db->db_buf && refcount_is_zero(&db->db_holds)) {
>>                  arc_buf_add_ref(db->db_buf, db);
>>                  /*
>>                   * The above just returns as db_buf is on the
>>                   * eviction list. Now, suppose arc_do_user_evicts()
>>                   * selects this buf and calls dbuf_do_evict().
>>                   * Nothing really stops this function.
>>                   *
>>                   * Now there is a race between dbuf_do_evict() and
>>                   * the following code
>>                   */
>>                  if (db->db_buf->b_data == NULL) {
>>                          ....
>>      ....
>>      }
>>
>> Sorry if I overlooked something that is very obvious.
>>
>> Thanks
>> Bhaskar
>> _______________________________________________
>> zfs-code mailing list
>> zfs-code at opensolaris.org
>> http://mail.opensolaris.org/mailman/listinfo/zfs-code
> _______________________________________________
> zfs-code mailing list
> zfs-code at opensolaris.org
> http://mail.opensolaris.org/mailman/listinfo/zfs-code


Reply via email to