[Virtio-fs] [PATCH] fuse: refcount FORGET requests

Liu Bo bo.liu at linux.alibaba.com
Fri May 31 18:35:04 UTC 2019


On Fri, May 31, 2019 at 01:44:35PM -0400, Vivek Goyal wrote:
> On Fri, May 31, 2019 at 10:38:22AM -0700, Liu Bo wrote:
> > On Fri, May 31, 2019 at 09:22:28AM -0400, Vivek Goyal wrote:
> > > On Fri, May 31, 2019 at 05:24:03PM +0800, Peng Tao wrote:
> > > > Right now FORGET requests are not tracked and they might be sent
> > > > after DESTROY request.
> > > 
> > > How does that happen?
> > > 
> > > > Normally this is OK, since user space should
> > > > be able to reject them knowing that the file system is already umounted.
> > > > But if the same file system is mounted right again and the file is
> > > > opened again, user space can be confused by the refcount decrement
> > > > carried by the old FORGET requests.
> > > > 
> > > > E.g., it can trigger an assertion in virtiofsd when running xfstests
> > > > generic/129 and generic/130 together:
> > > > 
> > > > unique: 23, opcode: FORGET (2), nodeid: 4, insize: 64, pid: 0
> > > >   forget 4 1 -2
> > > > virtiofsd: contrib/virtiofsd/passthrough_ll.c:1044: unref_inode: Assertion `inode->refcount >= n' failed.
> > > > 
> > > > To avoid confusing user space in such case, refcount FORGET requests so
> > > > that fuse_sb_destroy() waits for all inflight requests before returning.
> > > 
> > > forgets are optional and destroy is supposed to cleanup any pending
> > > state.
> > 
> > Since we've ensured that DESTROY is the last fuse_request sent to userspace
> > daemon, we only need to deal with those FORGET requests sent before DESTROY.
> > 
> > Given that FORGET is sent via HIGHPRI vq, in order to solve the problem, would
> > it make sense to route DESTROY to HIGHPRI vq as well?
> > 
> > Or, we can let lo_init to clear reqs in HIGHPRI vq?
> 
> I am looking at another approach. Given sending forget is optional, I am
> writing a patch to not send forgets after virtio_kill_sb() has been
> called. And also flush any in flight forgets. Something like.
> 
> virtio_kill_sb() {
> 	disconnect fsvq. Do not send any further forgets.
> 	flush in flight and pending forgets;
> 	fuse_kill_sb_anon()
> }
> 
> This should make sure once daemon seems destroy, after that there are
> no more forget requests.

Does it refer to flushing &fsvq->done_work?

If so, flushing inflight only covers those returned FORGETs, doesn't it?

If there are inflight forgets not coming back from daemon, I think we have to
wait for them as well.

thanks,
-liubo




More information about the Virtio-fs mailing list