From: Simon Wilkinson Date: Fri, 23 Apr 2010 14:07:58 +0000 (+0100) Subject: Linux: Don't roll our own llseek X-Git-Tag: openafs-devel-1_5_75~377 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=20d08fb0ec7190bac622e9ac8a17f97b7feef1cb;p=packages%2Fo%2Fopenafs.git Linux: Don't roll our own llseek llseek is a little more complex than just setting the pos field of the file structure. Where vfs_llseek is available to us (it has been since 2.6.8) use that directly. If vfs_llseek isn't available, then use either the filesystem's llseek method, or default_llseek (available since 2.6.0), to ensure we get the proper locking. Change-Id: I26bcbff984c7164be1724eee7a46cbe6e02bc510 Reviewed-on: http://gerrit.openafs.org/1816 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- diff --git a/acinclude.m4 b/acinclude.m4 index 80cb33ad2..14f10e837 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -815,6 +815,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_HAVE_SPLICE_DIRECT_TO_ACTOR LINUX_HAVE_PAGE_OFFSET LINUX_HAVE_ZERO_USER_SEGMENTS + LINUX_HAVE_VFS_LLSEEK LINUX_STRUCT_TASK_HAS_CRED LINUX_STRUCT_PROC_DIR_ENTRY_HAS_OWNER LINUX_HAVE_KMEM_CACHE_T diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h index 0b52019cf..e507e6b45 100644 --- a/src/afs/LINUX/osi_compat.h +++ b/src/afs/LINUX/osi_compat.h @@ -230,3 +230,12 @@ zero_user_segments(struct page *pp, unsigned int from1, unsigned int to1, } #endif +#ifndef HAVE_VFS_LLSEEK +static inline loff_t +vfs_llseek(struct file *filp, loff_t offset, int origin) { + if (filp->f_op->llseek) + return filp->f_op->llseek(filp, offset, origin); + return default_llseek(filp, offset, origin); +} +#endif + diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c index f5e21d563..8b2151ac1 100644 --- a/src/afs/LINUX/osi_file.c +++ b/src/afs/LINUX/osi_file.c @@ -387,13 +387,10 @@ osi_rdwr(struct osi_file *osifile, uio_t * uiop, int rw) TO_USER_SPACE(); /* seek to the desired position. Return -1 on error. */ - if (filp->f_op->llseek) { - if (filp->f_op->llseek(filp, (loff_t) uiop->uio_offset, 0) != uiop->uio_offset) { - code = -1; - goto out; - } - } else - filp->f_pos = uiop->uio_offset; + if (vfs_llseek(filp, (loff_t) uiop->uio_offset, 0) != uiop->uio_offset) { + code = -1; + goto out; + } while (code == 0 && uiop->uio_resid > 0 && uiop->uio_iovcnt > 0) { iov = uiop->uio_iov; diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 14cf9a6be..8d0a00fce 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -1257,3 +1257,16 @@ AC_DEFUN([LINUX_HAVE_PAGE_OFFSET], [ AC_DEFINE([HAVE_PAGE_OFFSET], 1, [define if your kernel has the page_offset function]) fi]) +AC_DEFUN([LINUX_HAVE_VFS_LLSEEK], [ + AC_MSG_CHECKING([for vfs_llseek]) + AC_CACHE_VAL([ac_cv_linux_have_vfs_llseek], [ + AC_TRY_KBUILD( +[#include ], +[vfs_llseek(NULL, 0, 0);], + ac_cv_linux_have_vfs_llseek=yes, + ac_cv_linux_have_vfs_llseek=no)]) + AC_MSG_RESULT($ac_cv_linux_have_vfs_llseek) + if test "x$ac_cv_linux_have_vfs_llseek" = "xyes"; then + AC_DEFINE([HAVE_VFS_LLSEEK], 1, [define if your kernel has the vfs_llseek function]) + fi]) +