diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-06-27 22:25:40 +0200 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-07-26 22:25:25 +0200 |
commit | b2b1ff3da6b27285c725eeb6f4c274da0a8e6a60 (patch) | |
tree | e583bfe5f5af635b3db7866e57d7506acbeae2ba /fs/nfs/dir.c | |
parent | pNFS: Wait for stale layoutget calls to complete in pnfs_update_layout() (diff) | |
download | linux-b2b1ff3da6b27285c725eeb6f4c274da0a8e6a60.tar.xz linux-b2b1ff3da6b27285c725eeb6f4c274da0a8e6a60.zip |
NFS: Allow optimisation of lseek(fd, SEEK_CUR, 0) on directories
There should be no need to grab the inode lock if we're only reading
the file offset.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to '')
-rw-r--r-- | fs/nfs/dir.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7a9c14426855..8f8e9e9f2a79 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -904,23 +904,29 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence) dfprintk(FILE, "NFS: llseek dir(%pD2, %lld, %d)\n", filp, offset, whence); - inode_lock(inode); switch (whence) { - case 1: - offset += filp->f_pos; - case 0: - if (offset >= 0) - break; - default: - offset = -EINVAL; - goto out; + default: + return -EINVAL; + case SEEK_SET: + if (offset < 0) + return -EINVAL; + inode_lock(inode); + break; + case SEEK_CUR: + if (offset == 0) + return filp->f_pos; + inode_lock(inode); + offset += filp->f_pos; + if (offset < 0) { + inode_unlock(inode); + return -EINVAL; + } } if (offset != filp->f_pos) { filp->f_pos = offset; dir_ctx->dir_cookie = 0; dir_ctx->duped = 0; } -out: inode_unlock(inode); return offset; } |