fuse: separate queue for FORGET requests
authorMiklos Szeredi <mszeredi@suse.cz>
Tue, 7 Dec 2010 19:16:56 +0000 (20:16 +0100)
committerMiklos Szeredi <mszeredi@suse.cz>
Tue, 7 Dec 2010 19:16:56 +0000 (20:16 +0100)
commit07e77dca8a1f17a724a9b7449f0ca02e70e9d057
tree69186be641145fd997ce15e17a22598d9a264119
parent8ac835056ca39b242d98332f46e4d65428a8b7db
fuse: separate queue for FORGET requests

Terje Malmedal reports that a fuse filesystem with 32 million inodes
on a machine with lots of memory can go unresponsive for up to 30
minutes when all those inodes are evicted from the icache.

The reason is that FORGET messages, sent when the inode is evicted,
are queued up together with regular filesystem requests, and while the
huge queue of FORGET messages are processed no other filesystem
operation can proceed.

Since a full fuse request structure is allocated for each inode, these
take up quite a bit of memory as well.

To solve these issues, create a slim 'fuse_forget_link' structure
containing just the minimum of information required to send the FORGET
request and chain these on a separate queue.

When userspace is asking for a request make sure that FORGET and
non-FORGET requests are selected fairly: for each 8 non-FORGET allow
16 FORGET requests.  This will make sure FORGETs do not pile up, yet
other requests are also allowed to proceed while the queued FORGETs
are processed.

Reported-by: Terje Malmedal <terje.malmedal@usit.uio.no>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
fs/fuse/dev.c
fs/fuse/dir.c
fs/fuse/fuse_i.h
fs/fuse/inode.c