Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: fuse: fix ioctl ABI fuse: allow batching of FORGET requests fuse: separate queue for FORGET requests fuse: ioctl cleanup Fix up trivial conflict in fs/fuse/inode.c due to RCU lookup having done the RCU-freeing of the inode in fuse_destroy_inode().
This commit is contained in:
@@ -71,6 +71,11 @@ struct fuse_mount_data {
|
||||
unsigned blksize;
|
||||
};
|
||||
|
||||
struct fuse_forget_link *fuse_alloc_forget()
|
||||
{
|
||||
return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL);
|
||||
}
|
||||
|
||||
static struct inode *fuse_alloc_inode(struct super_block *sb)
|
||||
{
|
||||
struct inode *inode;
|
||||
@@ -90,8 +95,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
|
||||
INIT_LIST_HEAD(&fi->queued_writes);
|
||||
INIT_LIST_HEAD(&fi->writepages);
|
||||
init_waitqueue_head(&fi->page_waitq);
|
||||
fi->forget_req = fuse_request_alloc();
|
||||
if (!fi->forget_req) {
|
||||
fi->forget = fuse_alloc_forget();
|
||||
if (!fi->forget) {
|
||||
kmem_cache_free(fuse_inode_cachep, inode);
|
||||
return NULL;
|
||||
}
|
||||
@@ -111,24 +116,10 @@ static void fuse_destroy_inode(struct inode *inode)
|
||||
struct fuse_inode *fi = get_fuse_inode(inode);
|
||||
BUG_ON(!list_empty(&fi->write_files));
|
||||
BUG_ON(!list_empty(&fi->queued_writes));
|
||||
if (fi->forget_req)
|
||||
fuse_request_free(fi->forget_req);
|
||||
kfree(fi->forget);
|
||||
call_rcu(&inode->i_rcu, fuse_i_callback);
|
||||
}
|
||||
|
||||
void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
|
||||
u64 nodeid, u64 nlookup)
|
||||
{
|
||||
struct fuse_forget_in *inarg = &req->misc.forget_in;
|
||||
inarg->nlookup = nlookup;
|
||||
req->in.h.opcode = FUSE_FORGET;
|
||||
req->in.h.nodeid = nodeid;
|
||||
req->in.numargs = 1;
|
||||
req->in.args[0].size = sizeof(struct fuse_forget_in);
|
||||
req->in.args[0].value = inarg;
|
||||
fuse_request_send_noreply(fc, req);
|
||||
}
|
||||
|
||||
static void fuse_evict_inode(struct inode *inode)
|
||||
{
|
||||
truncate_inode_pages(&inode->i_data, 0);
|
||||
@@ -136,8 +127,8 @@ static void fuse_evict_inode(struct inode *inode)
|
||||
if (inode->i_sb->s_flags & MS_ACTIVE) {
|
||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||
struct fuse_inode *fi = get_fuse_inode(inode);
|
||||
fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup);
|
||||
fi->forget_req = NULL;
|
||||
fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup);
|
||||
fi->forget = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,6 +532,7 @@ void fuse_conn_init(struct fuse_conn *fc)
|
||||
INIT_LIST_HEAD(&fc->interrupts);
|
||||
INIT_LIST_HEAD(&fc->bg_queue);
|
||||
INIT_LIST_HEAD(&fc->entry);
|
||||
fc->forget_list_tail = &fc->forget_list_head;
|
||||
atomic_set(&fc->num_waiting, 0);
|
||||
fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
|
||||
fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
|
||||
|
||||
Reference in New Issue
Block a user