linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org, fuse-devel@lists.sourceforge.net,
	miklos@szeredi.hu, npiggin@suse.de
Subject: Re: [PATCH 4/4] FUSE: implement direct mmap
Date: Tue, 30 Jun 2009 01:59:36 +0900	[thread overview]
Message-ID: <4A48F2F8.5090105@kernel.org> (raw)
In-Reply-To: <20090623171441.535c6c98.akpm@linux-foundation.org>

Hello, Andrew.

Andrew Morton wrote:
>> +static int fuse_mmap_commit_prep(struct fuse_conn *fc, struct fuse_req *req)
>> +{
>> +	struct fuse_mmap_commit_in *commit_in = (void *)req->in.args[0].value;
>> +	struct file *mfile = req->misc.mmap.file;
>> +	int fd;
>> +
>> +	if (!mfile)
>> +		return 0;
>> +
>> +	/* new mmap.file has been created, assign a fd to it */
>> +	fd = commit_in->fd = get_unused_fd_flags(O_CLOEXEC);
>> +	if (fd < 0)
>> +		return 0;
> 
> Shouldn't this be `return fd;'?

Non-zero return from prep aborts the command immediately and starts
processing the next command.  However, when the fd assigning fails,
the failure should be communicated to the userland server so that it
can release any resource it might be holding for the mmap.  So, the
failure state is recorded in commit_in->fd which and the prep callback
returns 0 so that the failure status can be transmitted to the
userland server.

>> +	fmmap->vm_ops = *vma->vm_ops;
>> +	vma->vm_ops = &fmmap->vm_ops;
>> +	vma->vm_ops->open = fuse_vm_open;
>> +	vma->vm_ops->close = fuse_vm_close;
>> +	vma->vm_private_data = fmmap;
>> +	err = 0;
> 
> Yes, the vm_operations save/overwrite/restore is the stinky part here.
> 
> I'm not completely clear what's going on here, and why, and what the
> overall implications and risks are.  Some discussion in the changelog
> would help.  With all that information we then would be better situated
> to discuss and perhaps solve <whatever problem this solves> by more
> pleasing means.
> 
> I mean, if the need for this hack indicates that there is some
> shortcoming in core VM then perhaps we can improve core VM.  Dunno.

Sorry about lack of explanation, in a nutshell, fuse direct mmap
implementation wants to use shmem but wants to know when each mmap is
opened and closed so that it can determine when the mmap is finally
released and tell the userland to release related resources.  I think
the following two approaches would be more regular for situations like
this.

1. Export the necessary parts of shmem operations and build our fuse's
   own vm_ops using necessary operations.

2. If vma can be nested, create wrapper vma around shmem vma and catch
   open/close calls from there.

#1 might be the better solution here but with two separate shmem
implementations it was a bit awkward.  #2 currently can't be done, so
I used bastardized form of #1.  So, yeap, it's ugly.

Anyways, it looks like the whole fd fiddling and shmem vma trickery
might all go away, so please don't invest too much time into it.

>> +	/* missing commit can cause resource leak on server side, don't fail */
>> +	req = fuse_get_req_nofail(fc, file);
> 
> That's an optimistically-named function.
> 
> <looks>
> 
> hm, it seems to duplicate mempool.c.

It's much more narrowly defined but yeah in a way.

>> +	if (err == -ENOSYS) {
>> +		/* Can't provide the coherency needed for MAP_SHARED */
>> +		if (vma->vm_flags & VM_MAYSHARE)
>> +			return -ENODEV;
>> +
>> +		invalidate_inode_pages2(file->f_mapping);
>> +
>> +		return generic_file_mmap(file, vma);
> 
> Now what's happening on this path?
> 
> We seem to have decided to fallback to a standard mmap of some form? 
> Why?  If the user's request failed, shouldn't we just fail the syscall?
> Hasn't the kernel just lied to userspace about what happened?
> 
> Also, this code looks like it's duplicating the behaviour of core MM? 
> If so then it needs to be kept in sync as core MM changes - that's a
> maintenance problem.  Can it be improved by changing core MM?

That's from the original mmap implementation before the direct mmap is
added.  It's just code movement.  No functional change by this patch
on this path.

>> --- a/fs/fuse/fuse_i.h
>> +++ b/fs/fuse/fuse_i.h
>> @@ -272,6 +272,13 @@ struct fuse_req {
>>  			struct fuse_write_out out;
>>  		} write;
>>  		struct fuse_lk_in lk_in;
>> +		struct {
>> +			/** to move filp for mmap between client and server */
> 
> Comment pretends to be kerneldoc?

Will fix.

>>  
>> +/**
> 
> kerneldoc?  Does this work?

I have no idea.  Will update.

>> + * Mmap flags
>> + *
>> + * FUSE_MMAP_DONT_COPY: don't copy the region on fork
>> + * FUSE_MMAP_DONT_EXPAND: can't be expanded with mremap()
>> + */
>> +#define FUSE_MMAP_DONT_COPY	(1 << 0)
>> +#define FUSE_MMAP_DONT_EXPAND	(1 << 1)
>> +

Thanks.

-- 
tejun

  reply	other threads:[~2009-06-29 16:59 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-18  9:24 [PATCHSET] FUSE/CUSE: implement direct mmap, take#3 Tejun Heo
2009-06-18  9:24 ` [PATCH 1/4] fdtable: export alloc_fd() Tejun Heo
2009-06-24  4:39   ` Al Viro
2009-06-30  3:05     ` Tejun Heo
2009-06-18  9:24 ` [PATCH 2/4] FUSE: make request_wait_answer() wait for ->end() completion Tejun Heo
     [not found]   ` <20090623165354.073a61fe.akpm@linux-foundation.org>
2009-06-24  0:04     ` Tejun Heo
2009-06-24 10:02   ` Miklos Szeredi
2009-06-29 16:20     ` Tejun Heo
2009-06-18  9:24 ` [PATCH 3/4] FUSE: implement fuse_req->prep() Tejun Heo
2009-06-23 23:56   ` Andrew Morton
2009-06-24  0:07     ` Tejun Heo
2009-06-18  9:24 ` [PATCH 4/4] FUSE: implement direct mmap Tejun Heo
2009-06-24  0:14   ` Andrew Morton
2009-06-29 16:59     ` Tejun Heo [this message]
2009-06-24 10:33   ` Miklos Szeredi
2009-06-29 16:42     ` Tejun Heo
2009-07-02 13:51       ` Miklos Szeredi
2009-07-04 11:14         ` Tejun Heo
2009-07-06 11:41           ` Miklos Szeredi
2009-07-08 23:14             ` Tejun Heo
2009-07-09 10:35               ` Miklos Szeredi
2009-06-18  9:27 ` [PATCH libfuse] implement direct mmap support Tejun Heo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4A48F2F8.5090105@kernel.org \
    --to=tj@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=fuse-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=npiggin@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).