mirror of
https://git.proxmox.com/git/mirror_spl-debian
synced 2025-10-04 07:56:21 +00:00
Merge branch 'upstream'
This commit is contained in:
commit
67572ee8c5
@ -78,11 +78,14 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
|
||||
SPL_AC_EXPORTED_RWSEM_IS_LOCKED
|
||||
SPL_AC_KERNEL_INVALIDATE_INODES
|
||||
SPL_AC_KERNEL_2ARGS_INVALIDATE_INODES
|
||||
SPL_AC_KERNEL_FALLOCATE
|
||||
SPL_AC_SHRINK_DCACHE_MEMORY
|
||||
SPL_AC_SHRINK_ICACHE_MEMORY
|
||||
SPL_AC_KERN_PATH_PARENT_HEADER
|
||||
SPL_AC_KERN_PATH_PARENT_SYMBOL
|
||||
SPL_AC_KERN_PATH_LOCKED
|
||||
SPL_AC_CONFIG_ZLIB_INFLATE
|
||||
SPL_AC_CONFIG_ZLIB_DEFLATE
|
||||
SPL_AC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
|
||||
SPL_AC_SHRINK_CONTROL_STRUCT
|
||||
SPL_AC_RWSEM_SPINLOCK_IS_RAW
|
||||
@ -1311,9 +1314,12 @@ dnl #
|
||||
AC_DEFUN([SPL_AC_3ARGS_ON_EACH_CPU], [
|
||||
AC_MSG_CHECKING([whether on_each_cpu() wants 3 args])
|
||||
SPL_LINUX_TRY_COMPILE([
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
void on_each_cpu_func(void *data) { return; }
|
||||
],[
|
||||
on_each_cpu(NULL, NULL, 0);
|
||||
on_each_cpu(on_each_cpu_func, NULL, 0);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_3ARGS_ON_EACH_CPU, 1,
|
||||
@ -1922,7 +1928,6 @@ AC_DEFUN([SPL_AC_2ARGS_VFS_FSYNC], [
|
||||
dnl #
|
||||
dnl # 3.5 API change,
|
||||
dnl # inode_operations.truncate_range removed
|
||||
dnl # (deprecated in favor of FALLOC_FL_PUNCH_HOLE)
|
||||
dnl #
|
||||
AC_DEFUN([SPL_AC_INODE_TRUNCATE_RANGE], [
|
||||
AC_MSG_CHECKING([whether truncate_range() inode operation is available])
|
||||
@ -1938,7 +1943,77 @@ AC_DEFUN([SPL_AC_INODE_TRUNCATE_RANGE], [
|
||||
],[
|
||||
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 # 2.6.33 API change. Also backported in RHEL5 as of 2.6.18-190.el5.
|
||||
@ -2128,6 +2203,48 @@ AC_DEFUN([SPL_AC_KERN_PATH_LOCKED], [
|
||||
[])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # zlib inflate compat,
|
||||
dnl # Verify the kernel has CONFIG_ZLIB_INFLATE support enabled.
|
||||
dnl #
|
||||
AC_DEFUN([SPL_AC_CONFIG_ZLIB_INFLATE], [
|
||||
AC_MSG_CHECKING([whether CONFIG_ZLIB_INFLATE is defined])
|
||||
SPL_LINUX_TRY_COMPILE([
|
||||
#if !defined(CONFIG_ZLIB_INFLATE) && \
|
||||
!defined(CONFIG_ZLIB_INFLATE_MODULE)
|
||||
#error CONFIG_ZLIB_INFLATE not defined
|
||||
#endif
|
||||
],[ ],[
|
||||
AC_MSG_RESULT([yes])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([
|
||||
*** This kernel does not include the required zlib inflate support.
|
||||
*** Rebuild the kernel with CONFIG_ZLIB_INFLATE=y|m set.])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # zlib deflate compat,
|
||||
dnl # Verify the kernel has CONFIG_ZLIB_DEFLATE support enabled.
|
||||
dnl #
|
||||
AC_DEFUN([SPL_AC_CONFIG_ZLIB_DEFLATE], [
|
||||
AC_MSG_CHECKING([whether CONFIG_ZLIB_DEFLATE is defined])
|
||||
SPL_LINUX_TRY_COMPILE([
|
||||
#if !defined(CONFIG_ZLIB_DEFLATE) && \
|
||||
!defined(CONFIG_ZLIB_DEFLATE_MODULE)
|
||||
#error CONFIG_ZLIB_DEFLATE not defined
|
||||
#endif
|
||||
],[ ],[
|
||||
AC_MSG_RESULT([yes])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([
|
||||
*** This kernel does not include the required zlib deflate support.
|
||||
*** Rebuild the kernel with CONFIG_ZLIB_DEFLATE=y|m set.])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 2.6.39 API compat,
|
||||
dnl # The function zlib_deflate_workspacesize() now take 2 arguments.
|
||||
|
@ -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_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_2ARGS_VFS_FSYNC
|
||||
# define spl_filp_fsync(fp, sync) vfs_fsync(fp, sync)
|
||||
|
@ -51,6 +51,7 @@ typedef enum { CV_DEFAULT=0, CV_DRIVER } kcv_type_t;
|
||||
extern void __cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg);
|
||||
extern void __cv_destroy(kcondvar_t *cvp);
|
||||
extern void __cv_wait(kcondvar_t *cvp, kmutex_t *mp);
|
||||
extern void __cv_wait_io(kcondvar_t *cvp, kmutex_t *mp);
|
||||
extern void __cv_wait_interruptible(kcondvar_t *cvp, kmutex_t *mp);
|
||||
extern clock_t __cv_timedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time);
|
||||
extern clock_t __cv_timedwait_interruptible(kcondvar_t *cvp, kmutex_t *mp,
|
||||
@ -61,6 +62,7 @@ extern void __cv_broadcast(kcondvar_t *cvp);
|
||||
#define cv_init(cvp, name, type, arg) __cv_init(cvp, name, type, arg)
|
||||
#define cv_destroy(cvp) __cv_destroy(cvp)
|
||||
#define cv_wait(cvp, mp) __cv_wait(cvp, mp)
|
||||
#define cv_wait_io(cvp, mp) __cv_wait_io(cvp, mp)
|
||||
#define cv_wait_interruptible(cvp, mp) __cv_wait_interruptible(cvp,mp)
|
||||
#define cv_timedwait(cvp, mp, t) __cv_timedwait(cvp, mp, t)
|
||||
#define cv_timedwait_interruptible(cvp, mp, t) \
|
||||
|
@ -97,7 +97,7 @@ __cv_destroy(kcondvar_t *cvp)
|
||||
EXPORT_SYMBOL(__cv_destroy);
|
||||
|
||||
static void
|
||||
cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state)
|
||||
cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state, int io)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
SENTRY;
|
||||
@ -121,6 +121,9 @@ cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state)
|
||||
* ensures we're linked in to the waiters list and avoids the
|
||||
* race where 'cvp->cv_waiters > 0' but the list is empty. */
|
||||
mutex_exit(mp);
|
||||
if (io)
|
||||
io_schedule();
|
||||
else
|
||||
schedule();
|
||||
mutex_enter(mp);
|
||||
|
||||
@ -139,17 +142,24 @@ cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state)
|
||||
void
|
||||
__cv_wait(kcondvar_t *cvp, kmutex_t *mp)
|
||||
{
|
||||
cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE);
|
||||
cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(__cv_wait);
|
||||
|
||||
void
|
||||
__cv_wait_interruptible(kcondvar_t *cvp, kmutex_t *mp)
|
||||
{
|
||||
cv_wait_common(cvp, mp, TASK_INTERRUPTIBLE);
|
||||
cv_wait_common(cvp, mp, TASK_INTERRUPTIBLE, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(__cv_wait_interruptible);
|
||||
|
||||
void
|
||||
__cv_wait_io(kcondvar_t *cvp, kmutex_t *mp)
|
||||
{
|
||||
cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE, 1);
|
||||
}
|
||||
EXPORT_SYMBOL(__cv_wait_io);
|
||||
|
||||
/* 'expire_time' argument is an absolute wall clock time in jiffies.
|
||||
* Return value is time left (expire_time - now) or -1 if timeout occurred.
|
||||
*/
|
||||
|
@ -536,7 +536,7 @@ hostid_exec(void)
|
||||
* '/usr/bin/hostid' and redirect the result to /proc/sys/spl/hostid
|
||||
* for us to use. It's a horrific solution but it will do for now.
|
||||
*/
|
||||
rc = call_usermodehelper(argv[0], argv, envp, 1);
|
||||
rc = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
|
||||
if (rc)
|
||||
printk("SPL: Failed user helper '%s %s %s', rc = %d\n",
|
||||
argv[0], argv[1], argv[2], rc);
|
||||
@ -607,7 +607,7 @@ set_kallsyms_lookup_name(void)
|
||||
NULL };
|
||||
int rc;
|
||||
|
||||
rc = call_usermodehelper(argv[0], argv, envp, 1);
|
||||
rc = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
|
||||
|
||||
/*
|
||||
* Due to I/O buffering the helper may return successfully before
|
||||
|
@ -827,8 +827,7 @@ struct list_head spl_kmem_cache_list; /* List of caches */
|
||||
struct rw_semaphore spl_kmem_cache_sem; /* Cache list lock */
|
||||
taskq_t *spl_kmem_cache_taskq; /* Task queue for ageing / reclaim */
|
||||
|
||||
static int spl_cache_flush(spl_kmem_cache_t *skc,
|
||||
spl_kmem_magazine_t *skm, int flush);
|
||||
static void spl_cache_shrink(spl_kmem_cache_t *skc, void *obj);
|
||||
|
||||
SPL_SHRINKER_CALLBACK_FWD_DECLARE(spl_kmem_cache_generic_shrinker);
|
||||
SPL_SHRINKER_DECLARE(spl_kmem_cache_shrinker,
|
||||
@ -1244,6 +1243,38 @@ spl_emergency_free(spl_kmem_cache_t *skc, void *obj)
|
||||
SRETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release objects from the per-cpu magazine back to their slab. The flush
|
||||
* argument contains the max number of entries to remove from the magazine.
|
||||
*/
|
||||
static void
|
||||
__spl_cache_flush(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flush)
|
||||
{
|
||||
int i, count = MIN(flush, skm->skm_avail);
|
||||
SENTRY;
|
||||
|
||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||
ASSERT(skm->skm_magic == SKM_MAGIC);
|
||||
ASSERT(spin_is_locked(&skc->skc_lock));
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
spl_cache_shrink(skc, skm->skm_objs[i]);
|
||||
|
||||
skm->skm_avail -= count;
|
||||
memmove(skm->skm_objs, &(skm->skm_objs[count]),
|
||||
sizeof(void *) * skm->skm_avail);
|
||||
|
||||
SEXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
spl_cache_flush(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flush)
|
||||
{
|
||||
spin_lock(&skc->skc_lock);
|
||||
__spl_cache_flush(skc, skm, flush);
|
||||
spin_unlock(&skc->skc_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
spl_magazine_age(void *data)
|
||||
{
|
||||
@ -1252,10 +1283,23 @@ spl_magazine_age(void *data)
|
||||
|
||||
ASSERT(skm->skm_magic == SKM_MAGIC);
|
||||
ASSERT(skm->skm_cpu == smp_processor_id());
|
||||
ASSERT(irqs_disabled());
|
||||
|
||||
if (skm->skm_avail > 0)
|
||||
if (time_after(jiffies, skm->skm_age + skc->skc_delay * HZ))
|
||||
(void) spl_cache_flush(skc, skm, skm->skm_refill);
|
||||
/* There are no available objects or they are too young to age out */
|
||||
if ((skm->skm_avail == 0) ||
|
||||
time_before(jiffies, skm->skm_age + skc->skc_delay * HZ))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Because we're executing in interrupt context we may have
|
||||
* interrupted the holder of this lock. To avoid a potential
|
||||
* deadlock return if the lock is contended.
|
||||
*/
|
||||
if (!spin_trylock(&skc->skc_lock))
|
||||
return;
|
||||
|
||||
__spl_cache_flush(skc, skm, skm->skm_refill);
|
||||
spin_unlock(&skc->skc_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1451,7 +1495,7 @@ spl_magazine_destroy(spl_kmem_cache_t *skc)
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
skm = skc->skc_mag[i];
|
||||
(void)spl_cache_flush(skc, skm, skm->skm_avail);
|
||||
spl_cache_flush(skc, skm, skm->skm_avail);
|
||||
spl_magazine_free(skm);
|
||||
}
|
||||
|
||||
@ -1931,42 +1975,6 @@ spl_cache_shrink(spl_kmem_cache_t *skc, void *obj)
|
||||
SEXIT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release a batch of objects from a per-cpu magazine back to their
|
||||
* respective slabs. This occurs when we exceed the magazine size,
|
||||
* are under memory pressure, when the cache is idle, or during
|
||||
* cache cleanup. The flush argument contains the number of entries
|
||||
* to remove from the magazine.
|
||||
*/
|
||||
static int
|
||||
spl_cache_flush(spl_kmem_cache_t *skc, spl_kmem_magazine_t *skm, int flush)
|
||||
{
|
||||
int i, count = MIN(flush, skm->skm_avail);
|
||||
SENTRY;
|
||||
|
||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||
ASSERT(skm->skm_magic == SKM_MAGIC);
|
||||
|
||||
/*
|
||||
* XXX: Currently we simply return objects from the magazine to
|
||||
* the slabs in fifo order. The ideal thing to do from a memory
|
||||
* fragmentation standpoint is to cheaply determine the set of
|
||||
* objects in the magazine which will result in the largest
|
||||
* number of free slabs if released from the magazine.
|
||||
*/
|
||||
spin_lock(&skc->skc_lock);
|
||||
for (i = 0; i < count; i++)
|
||||
spl_cache_shrink(skc, skm->skm_objs[i]);
|
||||
|
||||
skm->skm_avail -= count;
|
||||
memmove(skm->skm_objs, &(skm->skm_objs[count]),
|
||||
sizeof(void *) * skm->skm_avail);
|
||||
|
||||
spin_unlock(&skc->skc_lock);
|
||||
|
||||
SRETURN(count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate an object from the per-cpu magazine, or if the magazine
|
||||
* is empty directly allocate from a slab and repopulate the magazine.
|
||||
@ -2053,7 +2061,7 @@ spl_kmem_cache_free(spl_kmem_cache_t *skc, void *obj)
|
||||
|
||||
/* Per-CPU cache full, flush it to make space */
|
||||
if (unlikely(skm->skm_avail >= skm->skm_size))
|
||||
(void)spl_cache_flush(skc, skm, skm->skm_refill);
|
||||
spl_cache_flush(skc, skm, skm->skm_refill);
|
||||
|
||||
/* Available space in cache, use it */
|
||||
skm->skm_objs[skm->skm_avail++] = obj;
|
||||
|
@ -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);
|
||||
|
||||
#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,
|
||||
bfp->l_start, bfp->l_len);
|
||||
if (!error)
|
||||
if (error == 0)
|
||||
SRETURN(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INODE_TRUNCATE_RANGE
|
||||
|
@ -166,7 +166,7 @@ splat_linux_drop_slab(struct file *file)
|
||||
NULL };
|
||||
int rc;
|
||||
|
||||
rc = call_usermodehelper(argv[0], argv, envp, 1);
|
||||
rc = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
|
||||
if (rc)
|
||||
splat_vprint(file, SPLAT_LINUX_TEST3_NAME,
|
||||
"Failed user helper '%s %s %s', rc = %d\n",
|
||||
|
@ -75,7 +75,7 @@ splat_vnode_user_cmd(struct file *file, void *arg,
|
||||
NULL };
|
||||
int rc;
|
||||
|
||||
rc = call_usermodehelper(sh_path, argv, envp, 1);
|
||||
rc = call_usermodehelper(sh_path, argv, envp, UMH_WAIT_PROC);
|
||||
if (rc) {
|
||||
splat_vprint(file, name,
|
||||
"Failed command: %s %s %s (%d)\n",
|
||||
|
Loading…
Reference in New Issue
Block a user