From patchwork Fri Jan 15 05:27:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ravishankar N X-Patchwork-Id: 8037911 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 49845BEEE5 for ; Fri, 15 Jan 2016 05:31:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 36555204EA for ; Fri, 15 Jan 2016 05:31:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2A38A204DE for ; Fri, 15 Jan 2016 05:31:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751586AbcAOFbZ (ORCPT ); Fri, 15 Jan 2016 00:31:25 -0500 Received: from mail-qg0-f68.google.com ([209.85.192.68]:34627 "EHLO mail-qg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750810AbcAOFbY (ORCPT ); Fri, 15 Jan 2016 00:31:24 -0500 Received: by mail-qg0-f68.google.com with SMTP id 94so56840747qgt.1; Thu, 14 Jan 2016 21:31:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id; bh=zYQmNfTC3SBwaddBUx81WV7pA+CfhYAhlZiGupvvGmI=; b=q1wgOd5nvbb2K4l0MxyJsN6HlNosv5Yl/PDskAPwTZvEkafDAhm7eVEyCHiWeDGDhd ZrfeqfKv8c6oi+kodNreX1gJBfqGfUqzYV8bb2Rx+vhUIBz1AhnrJMPsnEoRIcl84kiM 3dH08IBidusNPto86wz52XV1lsiVksu21Zh/VQH5G0lupIpkE3/dM0wr1IjCwrZp/l63 nm3tOkIeP3P6Tv91Pce+XLdyE7CqoRAhM4vNBk97vpfiMmNSrk62DyGkIhV3R/Is82S0 /FN84dxq+FfOAymh+dWzb/aM8H5kdBQ650spVRw6MVcL8TX071sUpM6ZfujL3CftAf25 eG3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=zYQmNfTC3SBwaddBUx81WV7pA+CfhYAhlZiGupvvGmI=; b=gIM5mnCQ1JSVaU2BrYCxxigbi4ExHwtQDoanQ3YmyuLJ+sTTH4PmuVT1lPgXA28ol8 HcxAbEzVQcPWkqv7wDgFJGzRBaZbX67ssI0b8pQXNhDpK+o10KxV23nn8hfoCJ4HmQbN 6kW1D+yjnzDx+kdXeGkFt4KQ421vDJj+VcgNChsvmvRitV28E5gxTJxks7cV6uinf7JL N53JAWfAuFuIHqew7JE6JPU7Ny7bUS6A2dDBEzPQi2f6a40xKuUHTWBIGc/ULpQFSVXo LvG1Ex8UGOtaYLYi9DcAyBGHa1Qg86x21Px5R84igRz8uwxYsfQCDCt/DNKHVcX5uQf8 BAIg== X-Gm-Message-State: ALoCoQnkYgXMAO2492BEsPOj/v8izHE27IkcjEcdTj0I6XTOlHJEJctQmT/Vn9d9LNJAAkjgiN6DcbFzxduKBOed7WvXKlT0iw== X-Received: by 10.140.145.196 with SMTP id 187mr11490066qhr.15.1452835883370; Thu, 14 Jan 2016 21:31:23 -0800 (PST) Received: from tuxpad.redhat.com ([202.62.91.50]) by smtp.gmail.com with ESMTPSA id u65sm3902050qhc.9.2016.01.14.21.31.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Jan 2016 21:31:22 -0800 (PST) From: Ravishankar N To: torvalds@linux-foundation.org, david@fromorbit.com, viro@zeniv.linux.org.uk Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, fuse-devel@lists.sourceforge.net, Ravishankar N , Miklos Szeredi Subject: [PATCH] fuse: add support for SEEK_HOLE and SEEK_DATA in lseek Date: Fri, 15 Jan 2016 10:57:15 +0530 Message-Id: <1452835635-14440-1-git-send-email-ravishankar@redhat.com> X-Mailer: git-send-email 2.5.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-3.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RCVD_IN_SBL_CSS,RP_MATCHES_RCVD,T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A useful performance improvement for accessing virtual machine images via FUSE mount. See https://bugzilla.redhat.com/show_bug.cgi?id=1220173 for a use-case for glusterFS. Signed-off-by: Ravishankar N Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 73 +++++++++++++++++++++++++++++++++++++++++------ fs/fuse/fuse_i.h | 3 ++ include/uapi/linux/fuse.h | 17 ++++++++++- 3 files changed, 84 insertions(+), 9 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 570ca40..aa03aab 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2231,20 +2231,77 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block) return err ? 0 : outarg.block; } +static loff_t fuse_lseek(struct file *file, loff_t offset, int whence) +{ + struct inode *inode = file->f_mapping->host; + struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_file *ff = file->private_data; + FUSE_ARGS(args); + struct fuse_lseek_in inarg = { + .fh = ff->fh, + .offset = offset, + .whence = whence + }; + struct fuse_lseek_out outarg; + int err; + + if (fc->no_lseek) + goto fallback; + + args.in.h.opcode = FUSE_LSEEK; + args.in.h.nodeid = ff->nodeid; + args.in.numargs = 1; + args.in.args[0].size = sizeof(inarg); + args.in.args[0].value = &inarg; + args.out.numargs = 1; + args.out.args[0].size = sizeof(outarg); + args.out.args[0].value = &outarg; + err = fuse_simple_request(fc, &args); + if (err) { + if (err == -ENOSYS) { + fc->no_lseek = 1; + goto fallback; + } + return err; + } + + return vfs_setpos(file, outarg.offset, inode->i_sb->s_maxbytes); + +fallback: + err = fuse_update_attributes(inode, NULL, file, NULL); + if (!err) + return generic_file_llseek(file, offset, whence); + else + return err; +} + static loff_t fuse_file_llseek(struct file *file, loff_t offset, int whence) { loff_t retval; struct inode *inode = file_inode(file); - /* No i_mutex protection necessary for SEEK_CUR and SEEK_SET */ - if (whence == SEEK_CUR || whence == SEEK_SET) - return generic_file_llseek(file, offset, whence); - - mutex_lock(&inode->i_mutex); - retval = fuse_update_attributes(inode, NULL, file, NULL); - if (!retval) + switch (whence) { + case SEEK_SET: + case SEEK_CUR: + /* No i_mutex protection necessary for SEEK_CUR and SEEK_SET */ retval = generic_file_llseek(file, offset, whence); - mutex_unlock(&inode->i_mutex); + break; + case SEEK_END: + mutex_lock(&inode->i_mutex); + retval = fuse_update_attributes(inode, NULL, file, NULL); + if (!retval) + retval = generic_file_llseek(file, offset, whence); + mutex_unlock(&inode->i_mutex); + break; + case SEEK_HOLE: + case SEEK_DATA: + mutex_lock(&inode->i_mutex); + retval = fuse_lseek(file, offset, whence); + mutex_unlock(&inode->i_mutex); + break; + default: + retval = -EINVAL; + } return retval; } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 4051131..ce394b5 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -605,6 +605,9 @@ struct fuse_conn { /** Does the filesystem support asynchronous direct-IO submission? */ unsigned async_dio:1; + /** Is lseek not implemented by fs? */ + unsigned no_lseek:1; + /** The number of requests waiting for completion */ atomic_t num_waiting; diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index c9aca04..5974fae 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -102,6 +102,9 @@ * - add ctime and ctimensec to fuse_setattr_in * - add FUSE_RENAME2 request * - add FUSE_NO_OPEN_SUPPORT flag + * + * 7.24 + * - add FUSE_LSEEK for SEEK_HOLE and SEEK_DATA support */ #ifndef _LINUX_FUSE_H @@ -137,7 +140,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 23 +#define FUSE_KERNEL_MINOR_VERSION 24 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -358,6 +361,7 @@ enum fuse_opcode { FUSE_FALLOCATE = 43, FUSE_READDIRPLUS = 44, FUSE_RENAME2 = 45, + FUSE_LSEEK = 46, /* CUSE specific operations */ CUSE_INIT = 4096, @@ -758,4 +762,15 @@ struct fuse_notify_retrieve_in { /* Device ioctls: */ #define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t) +struct fuse_lseek_in { + uint64_t fh; + uint64_t offset; + uint32_t whence; + uint32_t padding; +}; + +struct fuse_lseek_out { + uint64_t offset; +}; + #endif /* _LINUX_FUSE_H */