On Wed, Jul 15, 2015 at 01:49:48PM +1000, NeilBrown wrote: > > In any case, you have two possibilities - explicit unexport triggering that > > dput(), etc. and umount(2) triggering the same. Whoever comes second gets > > to wait until it's done. So why not make the point where we commit to > > unexporting the sucker the place where we do pin_kill()? And have ->kill() > > of that thing prevent appearance of new entries, then wait for them to run > > down. Which is precisely the same thing you want to happen on umount... > > The "wait for them to run down" part is the sticking point. We don't > have any easy way to wait for there to be no more references, so I'd > really like to use the waiting that pin_kill() already does. > I want the ->kill function to just unhash the cache entry, and then > wait for pin_delete() to be called. pin_remove, presumably? > The final 'put' on the cache entry calls dput on the dentry and then > pin_remove(). > > The ->kill function can wait for that to happen by calling pin_kill(). > I guess there is no real need for a return value from pin_remove(). > > So > static void expkey_pin_kill(struct fs_pin *pin) > { > struct svc_expkey *key = container_of(pin, ....); > > cache_delete_entry(key->cd, &key->h); ... and another CPU drops the last reference, freeing the sucker. > pin_kill(&key->ek_pin); /* recursive call will wait for > * pin_delete() to be called */ ... oopsing on the spot. -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html