lkml.org 
[lkml]   [2004]   [May]   [11]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
/
DateTue, 11 May 2004 10:08:53 -0400
SubjectRe: [ANNOUNCEMENT PATCH COW] proof of concept impementation of cowlinks
FromJan Harkes <>
On Tue, May 11, 2004 at 12:02:32PM +0200, Jörn Engel wrote:
> > Copyfile can trivially be implemented in libc. I don't see why it would
> > have to be a system call. If a network filesystem wants to optimize the
> > file copying it could do this based on the sendfile data. If source and
> > destination are within the same filesystem and we're copying the whole
> > file starting at offset 0, send a copyfile RPC.
> 
> Can you explain this to Steve?  I'm still quite clueless about network
> filesystems, but it sounded as if such an optimization was impossible
> to do in cifs without a combined create/copy/unlink_on_error system
> call.
> 
> If your suggestion works and the network filesystems can be changed to
> work independently of a struct file*, I agree with you that copyfile()
> is a stupid idea and should be forgotten.

I would probably do it by overriding the file_operations.sendfile
function. A first approximation of a possible implementation follows. I
went a bit crazy on the comments. The only problem is that the type of
target is unknown, block/loop.c and nfsd/vfs.c are using sendfile to
to send to something that is not a struct file.

Jan

int my_file_sendfile(struct file *in_file, loff_t *ppos, size_t count,
		     read_actor_t actor, void __user *target)
{
    struct file *out_file = NULL;
    /* We have to check the read_actor callback function to see if the
     * target actually points at a struct file. */
    if (actor != file_send_actor)
	goto copy_local;
    /* are both source and destination within the same file system
     * mountpoint? */
    if (in_file->f_dentry->d_inode->i_sb != out_file->f_dentry->d_inode->i_sb)
	goto copy_local;
    /* are we copying the entire source file? */
    if (*ppos != 0 || count != in_file->f_dentry->d_inode->i_size)
	goto copy_local;
    /* and are we at least overwriting the complete destination file?
       (alternatively we could check that the out_file is currently empty) */
    if (out_file->f_pos != 0 || out_file->f_dentry->d_inode->i_size > count)
	goto copy_local;
    /* we are in luck and can send a copyfile rpc */
    int err = make_copyfile_rpc(in_file, out_file);
    /* we probably should force a refresh of out_file as it changed on
     * the server and not locally */
    MY_I(out_file->f_dentry->d_inode)->time = 0;
    return err;
copy_local:
    /* no luck, we're sending to something that isn't a file or in the
     * same filesystem, or we only copy a partial file. any case, we
     * have to perform the copy locally. */
    return generic_file_sendfile(in_file, ppos, count, actor, target);
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:03    [from the cache]
©2003-2008