mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-02-05 06:43:31 +03:00
RHEL 6.4 compat, fallocate()
In the upstream kernel the FALLOC_FL_PUNCH_HOLE #define was introduced after the fallocate() function was moved from the inode_operations to the file_operations structure. Therefore, the SPL code assumed that if FALLOC_FL_PUNCH_HOLE was defined it was safe to use f_ops->fallocate(). Unfortunately, the RHEL6.4 kernel has only backported the FALLOC_FL_PUNCH_HOLE #define and not the fallocate() change. To address this compatibility issue the spl_filp_fallocate() helper function was added to properly detect which interface is available. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
parent
46a75aadb7
commit
1c7b3eaf87
@ -78,6 +78,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
|
|||||||
SPL_AC_EXPORTED_RWSEM_IS_LOCKED
|
SPL_AC_EXPORTED_RWSEM_IS_LOCKED
|
||||||
SPL_AC_KERNEL_INVALIDATE_INODES
|
SPL_AC_KERNEL_INVALIDATE_INODES
|
||||||
SPL_AC_KERNEL_2ARGS_INVALIDATE_INODES
|
SPL_AC_KERNEL_2ARGS_INVALIDATE_INODES
|
||||||
|
SPL_AC_KERNEL_FALLOCATE
|
||||||
SPL_AC_SHRINK_DCACHE_MEMORY
|
SPL_AC_SHRINK_DCACHE_MEMORY
|
||||||
SPL_AC_SHRINK_ICACHE_MEMORY
|
SPL_AC_SHRINK_ICACHE_MEMORY
|
||||||
SPL_AC_KERN_PATH_PARENT_HEADER
|
SPL_AC_KERN_PATH_PARENT_HEADER
|
||||||
@ -1922,7 +1923,6 @@ AC_DEFUN([SPL_AC_2ARGS_VFS_FSYNC], [
|
|||||||
dnl #
|
dnl #
|
||||||
dnl # 3.5 API change,
|
dnl # 3.5 API change,
|
||||||
dnl # inode_operations.truncate_range removed
|
dnl # inode_operations.truncate_range removed
|
||||||
dnl # (deprecated in favor of FALLOC_FL_PUNCH_HOLE)
|
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([SPL_AC_INODE_TRUNCATE_RANGE], [
|
AC_DEFUN([SPL_AC_INODE_TRUNCATE_RANGE], [
|
||||||
AC_MSG_CHECKING([whether truncate_range() inode operation is available])
|
AC_MSG_CHECKING([whether truncate_range() inode operation is available])
|
||||||
@ -1938,7 +1938,77 @@ AC_DEFUN([SPL_AC_INODE_TRUNCATE_RANGE], [
|
|||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
]))
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 2.6.38 - 3.x API
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([SPL_AC_KERNEL_FILE_FALLOCATE], [
|
||||||
|
AC_MSG_CHECKING([whether fops->fallocate() exists])
|
||||||
|
SPL_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/fs.h>
|
||||||
|
],[
|
||||||
|
long (*fallocate) (struct file *, int, loff_t, loff_t) = NULL;
|
||||||
|
struct file_operations fops __attribute__ ((unused)) = {
|
||||||
|
.fallocate = fallocate,
|
||||||
|
};
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 2.6.x - 2.6.37 API
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([SPL_AC_KERNEL_INODE_FALLOCATE], [
|
||||||
|
AC_MSG_CHECKING([whether iops->fallocate() exists])
|
||||||
|
SPL_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/fs.h>
|
||||||
|
],[
|
||||||
|
long (*fallocate) (struct inode *, int, loff_t, loff_t) = NULL;
|
||||||
|
struct inode_operations fops __attribute__ ((unused)) = {
|
||||||
|
.fallocate = fallocate,
|
||||||
|
};
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_INODE_FALLOCATE, 1, [fops->fallocate() exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # PaX Linux 2.6.38 - 3.x API
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([SPL_AC_PAX_KERNEL_FILE_FALLOCATE], [
|
||||||
|
AC_MSG_CHECKING([whether fops->fallocate() exists])
|
||||||
|
SPL_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/fs.h>
|
||||||
|
],[
|
||||||
|
long (*fallocate) (struct file *, int, loff_t, loff_t) = NULL;
|
||||||
|
struct file_operations_no_const fops __attribute__ ((unused)) = {
|
||||||
|
.fallocate = fallocate,
|
||||||
|
};
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_FILE_FALLOCATE, 1, [fops->fallocate() exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # The fallocate callback was moved from the inode_operations
|
||||||
|
dnl # structure to the file_operations structure.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([SPL_AC_KERNEL_FALLOCATE], [
|
||||||
|
SPL_AC_KERNEL_FILE_FALLOCATE
|
||||||
|
SPL_AC_KERNEL_INODE_FALLOCATE
|
||||||
|
SPL_AC_PAX_KERNEL_FILE_FALLOCATE
|
||||||
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 2.6.33 API change. Also backported in RHEL5 as of 2.6.18-190.el5.
|
dnl # 2.6.33 API change. Also backported in RHEL5 as of 2.6.18-190.el5.
|
||||||
|
@ -50,6 +50,26 @@ spl_filp_open(const char *name, int flags, int mode, int *err)
|
|||||||
#define spl_filp_poff(f) (&(f)->f_pos)
|
#define spl_filp_poff(f) (&(f)->f_pos)
|
||||||
#define spl_filp_write(fp, b, s, p) (fp)->f_op->write((fp), (b), (s), p)
|
#define spl_filp_write(fp, b, s, p) (fp)->f_op->write((fp), (b), (s), p)
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
spl_filp_fallocate(struct file *fp, int mode, loff_t offset, loff_t len)
|
||||||
|
{
|
||||||
|
int error = -EOPNOTSUPP;
|
||||||
|
|
||||||
|
#ifdef HAVE_FILE_FALLOCATE
|
||||||
|
if (fp->f_op->fallocate)
|
||||||
|
error = fp->f_op->fallocate(fp, mode, offset, len);
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_INODE_FALLOCATE
|
||||||
|
if (fp->f_dentry && fp->f_dentry->d_inode &&
|
||||||
|
fp->f_dentry->d_inode->i_op->fallocate)
|
||||||
|
error = fp->f_dentry->d_inode->i_op->fallocate(
|
||||||
|
fp->f_dentry->d_inode, mode, offset, len);
|
||||||
|
# endif /* HAVE_INODE_FALLOCATE */
|
||||||
|
#endif /*HAVE_FILE_FALLOCATE */
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_VFS_FSYNC
|
#ifdef HAVE_VFS_FSYNC
|
||||||
# ifdef HAVE_2ARGS_VFS_FSYNC
|
# ifdef HAVE_2ARGS_VFS_FSYNC
|
||||||
# define spl_filp_fsync(fp, sync) vfs_fsync(fp, sync)
|
# define spl_filp_fsync(fp, sync) vfs_fsync(fp, sync)
|
||||||
|
@ -654,13 +654,15 @@ int vn_space(vnode_t *vp, int cmd, struct flock *bfp, int flag,
|
|||||||
ASSERT(bfp->l_start >= 0 && bfp->l_len > 0);
|
ASSERT(bfp->l_start >= 0 && bfp->l_len > 0);
|
||||||
|
|
||||||
#ifdef FALLOC_FL_PUNCH_HOLE
|
#ifdef FALLOC_FL_PUNCH_HOLE
|
||||||
if (vp->v_file->f_op->fallocate) {
|
/*
|
||||||
error = -vp->v_file->f_op->fallocate(vp->v_file,
|
* When supported by the underlying file system preferentially
|
||||||
|
* use the fallocate() callback to preallocate the space.
|
||||||
|
*/
|
||||||
|
error = -spl_filp_fallocate(vp->v_file,
|
||||||
FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
|
FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
|
||||||
bfp->l_start, bfp->l_len);
|
bfp->l_start, bfp->l_len);
|
||||||
if (!error)
|
if (error == 0)
|
||||||
SRETURN(0);
|
SRETURN(0);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_INODE_TRUNCATE_RANGE
|
#ifdef HAVE_INODE_TRUNCATE_RANGE
|
||||||
|
Loading…
Reference in New Issue
Block a user