Compare commits
15 Commits
master
...
zfs-0.6.4-
Author | SHA1 | Date |
---|---|---|
|
44b5ec8fd1 | |
|
464c506e3d | |
|
71fa174225 | |
|
3a25380b5e | |
|
c4dd92ad0d | |
|
4aa9d97f45 | |
|
aa5f4beb84 | |
|
04faa11e95 | |
|
4c05965578 | |
|
d1b9bc7a78 | |
|
7065e2dac6 | |
|
320e58d5a6 | |
|
4ec7b857a9 | |
|
e548a597d0 | |
|
7af63221dc |
2
META
2
META
|
@ -1,7 +1,7 @@
|
|||
Meta: 1
|
||||
Name: zfs
|
||||
Branch: 1.0
|
||||
Version: 0.6.4
|
||||
Version: 0.6.4.2
|
||||
Release: 1
|
||||
Release-Tags: relext
|
||||
License: CDDL
|
||||
|
|
|
@ -54,7 +54,7 @@ flock -x 8
|
|||
# Given a <pool> and <device> return the status, (ONLINE, FAULTED, etc...).
|
||||
vdev_status() {
|
||||
local POOL=$1
|
||||
local VDEV=$2
|
||||
local VDEV=`basename $2`
|
||||
local T=' ' # tab character since '\t' isn't portable
|
||||
|
||||
${ZPOOL} status ${POOL} | sed -n -e \
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
dnl #
|
||||
dnl # 2.6.12 API change
|
||||
dnl # d_prune_aliases() helper function available.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_D_PRUNE_ALIASES],
|
||||
[AC_MSG_CHECKING([whether d_prune_aliases() is available])
|
||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||
#include <linux/dcache.h>
|
||||
], [
|
||||
struct inode *ip = NULL;
|
||||
d_prune_aliases(ip);
|
||||
], [d_prune_aliases], [fs/dcache.c], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_D_PRUNE_ALIASES, 1,
|
||||
[d_prune_aliases() is available])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
|
@ -109,3 +109,25 @@ AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [
|
|||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 3.12 API change
|
||||
dnl # The nid member was added to struct shrink_control to support
|
||||
dnl # NUMA-aware shrinkers.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [
|
||||
AC_MSG_CHECKING([whether shrink_control has nid])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
],[
|
||||
struct shrink_control sc __attribute__ ((unused));
|
||||
unsigned long scnidsize __attribute__ ((unused)) =
|
||||
sizeof(sc.nid);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(SHRINK_CONTROL_HAS_NID, 1,
|
||||
[struct shrink_control has nid])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
dnl #
|
||||
dnl # Linux 4.1.x API
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
|
||||
[AC_MSG_CHECKING([whether fops->read/write_iter() are available])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
|
||||
ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to)
|
||||
{ return 0; }
|
||||
ssize_t test_write(struct kiocb *kiocb, struct iov_iter *from)
|
||||
{ return 0; }
|
||||
|
||||
static const struct file_operations
|
||||
fops __attribute__ ((unused)) = {
|
||||
.read_iter = test_read,
|
||||
.write_iter = test_write,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_VFS_RW_ITERATE, 1,
|
||||
[fops->read/write_iter() are available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
|
@ -79,6 +79,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||
ZFS_AC_KERNEL_INSERT_INODE_LOCKED
|
||||
ZFS_AC_KERNEL_D_MAKE_ROOT
|
||||
ZFS_AC_KERNEL_D_OBTAIN_ALIAS
|
||||
ZFS_AC_KERNEL_D_PRUNE_ALIASES
|
||||
ZFS_AC_KERNEL_D_SET_D_OP
|
||||
ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA
|
||||
ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS
|
||||
|
@ -88,6 +89,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||
ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY
|
||||
ZFS_AC_KERNEL_MOUNT_NODEV
|
||||
ZFS_AC_KERNEL_SHRINK
|
||||
ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID
|
||||
ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD
|
||||
ZFS_AC_KERNEL_S_D_OP
|
||||
ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER
|
||||
|
@ -96,6 +98,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||
ZFS_AC_KERNEL_5ARG_SGET
|
||||
ZFS_AC_KERNEL_LSEEK_EXECUTE
|
||||
ZFS_AC_KERNEL_VFS_ITERATE
|
||||
ZFS_AC_KERNEL_VFS_RW_ITERATE
|
||||
|
||||
AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
|
||||
KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
|
||||
|
|
|
@ -9,4 +9,5 @@ ConditionPathExists=@sysconfdir@/zfs/zpool.cache
|
|||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStartPre=/sbin/modprobe zfs
|
||||
ExecStart=@sbindir@/zpool import -c @sysconfdir@/zfs/zpool.cache -aN
|
||||
|
|
|
@ -9,4 +9,5 @@ ConditionPathExists=!@sysconfdir@/zfs/zpool.cache
|
|||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStartPre=/sbin/modprobe zfs
|
||||
ExecStart=@sbindir@/zpool import -d /dev/disk/by-id -aN
|
||||
|
|
|
@ -236,6 +236,7 @@ struct spa {
|
|||
uint64_t spa_feat_for_read_obj; /* required to read from pool */
|
||||
uint64_t spa_feat_desc_obj; /* Feature descriptions */
|
||||
uint64_t spa_feat_enabled_txg_obj; /* Feature enabled txg */
|
||||
kmutex_t spa_feat_stats_lock; /* protects spa_feat_stats */
|
||||
nvlist_t *spa_feat_stats; /* Cache of enabled features */
|
||||
/* cache feature refcounts */
|
||||
uint64_t spa_feat_refcount_cache[SPA_FEATURES];
|
||||
|
|
|
@ -660,23 +660,84 @@ libzfs_run_process(const char *path, char *argv[], int flags)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the required ZFS_DEV device is available and optionally attempt
|
||||
* to load the ZFS modules. Under normal circumstances the modules
|
||||
* should already have been loaded by some external mechanism.
|
||||
*
|
||||
* Environment variables:
|
||||
* - ZFS_MODULE_LOADING="YES|yes|ON|on" - Attempt to load modules.
|
||||
* - ZFS_MODULE_TIMEOUT="<seconds>" - Seconds to wait for ZFS_DEV
|
||||
*/
|
||||
int
|
||||
libzfs_load_module(const char *module)
|
||||
{
|
||||
char *argv[4] = {"/sbin/modprobe", "-q", (char *)module, (char *)0};
|
||||
char *load_str, *timeout_str;
|
||||
long timeout = 10; /* seconds */
|
||||
long busy_timeout = 10; /* milliseconds */
|
||||
int load = 1, fd;
|
||||
hrtime_t start;
|
||||
|
||||
if (libzfs_module_loaded(module))
|
||||
return (0);
|
||||
/* Optionally request module loading */
|
||||
if (!libzfs_module_loaded(module)) {
|
||||
load_str = getenv("ZFS_MODULE_LOADING");
|
||||
if (load_str) {
|
||||
if (!strncasecmp(load_str, "YES", strlen("YES")) ||
|
||||
!strncasecmp(load_str, "ON", strlen("ON")))
|
||||
load = 1;
|
||||
else
|
||||
load = 0;
|
||||
}
|
||||
|
||||
return (libzfs_run_process("/sbin/modprobe", argv, 0));
|
||||
if (load && libzfs_run_process("/sbin/modprobe", argv, 0))
|
||||
return (ENOEXEC);
|
||||
}
|
||||
|
||||
/* Module loading is synchronous it must be available */
|
||||
if (!libzfs_module_loaded(module))
|
||||
return (ENXIO);
|
||||
|
||||
/*
|
||||
* Device creation by udev is asynchronous and waiting may be
|
||||
* required. Busy wait for 10ms and then fall back to polling every
|
||||
* 10ms for the allowed timeout (default 10s, max 10m). This is
|
||||
* done to optimize for the common case where the device is
|
||||
* immediately available and to avoid penalizing the possible
|
||||
* case where udev is slow or unable to create the device.
|
||||
*/
|
||||
timeout_str = getenv("ZFS_MODULE_TIMEOUT");
|
||||
if (timeout_str) {
|
||||
timeout = strtol(timeout_str, NULL, 0);
|
||||
timeout = MAX(MIN(timeout, (10 * 60)), 0); /* 0 <= N <= 600 */
|
||||
}
|
||||
|
||||
start = gethrtime();
|
||||
do {
|
||||
fd = open(ZFS_DEV, O_RDWR);
|
||||
if (fd >= 0) {
|
||||
(void) close(fd);
|
||||
return (0);
|
||||
} else if (errno != ENOENT) {
|
||||
return (errno);
|
||||
} else if (NSEC2MSEC(gethrtime() - start) < busy_timeout) {
|
||||
sched_yield();
|
||||
} else {
|
||||
usleep(10 * MILLISEC);
|
||||
}
|
||||
} while (NSEC2MSEC(gethrtime() - start) < (timeout * MILLISEC));
|
||||
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
libzfs_handle_t *
|
||||
libzfs_init(void)
|
||||
{
|
||||
libzfs_handle_t *hdl;
|
||||
int error;
|
||||
|
||||
if (libzfs_load_module("zfs") != 0) {
|
||||
error = libzfs_load_module(ZFS_DRIVER);
|
||||
if (error) {
|
||||
(void) fprintf(stderr, gettext("Failed to load ZFS module "
|
||||
"stack.\nLoad the module manually by running "
|
||||
"'insmod <location>/zfs.ko' as root.\n"));
|
||||
|
|
|
@ -254,7 +254,7 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
|
|||
mutex_enter(&pd->pd_mtx);
|
||||
ASSERT(pd->pd_bytes_fetched >= 0);
|
||||
while (pd->pd_bytes_fetched < size && !pd->pd_exited)
|
||||
cv_wait(&pd->pd_cv, &pd->pd_mtx);
|
||||
cv_wait_interruptible(&pd->pd_cv, &pd->pd_mtx);
|
||||
pd->pd_bytes_fetched -= size;
|
||||
cv_broadcast(&pd->pd_cv);
|
||||
mutex_exit(&pd->pd_mtx);
|
||||
|
@ -461,7 +461,7 @@ traverse_prefetcher(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
|||
|
||||
mutex_enter(&pfd->pd_mtx);
|
||||
while (!pfd->pd_cancel && pfd->pd_bytes_fetched >= zfs_pd_bytes_max)
|
||||
cv_wait(&pfd->pd_cv, &pfd->pd_mtx);
|
||||
cv_wait_interruptible(&pfd->pd_cv, &pfd->pd_mtx);
|
||||
pfd->pd_bytes_fetched += BP_GET_LSIZE(bp);
|
||||
cv_broadcast(&pfd->pd_cv);
|
||||
mutex_exit(&pfd->pd_mtx);
|
||||
|
@ -566,7 +566,7 @@ traverse_impl(spa_t *spa, dsl_dataset_t *ds, uint64_t objset, blkptr_t *rootbp,
|
|||
pd->pd_cancel = B_TRUE;
|
||||
cv_broadcast(&pd->pd_cv);
|
||||
while (!pd->pd_exited)
|
||||
cv_wait(&pd->pd_cv, &pd->pd_mtx);
|
||||
cv_wait_interruptible(&pd->pd_cv, &pd->pd_mtx);
|
||||
mutex_exit(&pd->pd_mtx);
|
||||
|
||||
mutex_destroy(&pd->pd_mtx);
|
||||
|
|
|
@ -3264,10 +3264,13 @@ spa_feature_stats_from_cache(spa_t *spa, nvlist_t *features)
|
|||
static void
|
||||
spa_add_feature_stats(spa_t *spa, nvlist_t *config)
|
||||
{
|
||||
nvlist_t *features = spa->spa_feat_stats;
|
||||
nvlist_t *features;
|
||||
|
||||
ASSERT(spa_config_held(spa, SCL_CONFIG, RW_READER));
|
||||
|
||||
mutex_enter(&spa->spa_feat_stats_lock);
|
||||
features = spa->spa_feat_stats;
|
||||
|
||||
if (features != NULL) {
|
||||
spa_feature_stats_from_cache(spa, features);
|
||||
} else {
|
||||
|
@ -3278,6 +3281,8 @@ spa_add_feature_stats(spa_t *spa, nvlist_t *config)
|
|||
|
||||
VERIFY0(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS,
|
||||
features));
|
||||
|
||||
mutex_exit(&spa->spa_feat_stats_lock);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -531,6 +531,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
|
|||
mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
mutex_init(&spa->spa_suspend_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
mutex_init(&spa->spa_vdev_top_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
mutex_init(&spa->spa_feat_stats_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
|
||||
cv_init(&spa->spa_async_cv, NULL, CV_DEFAULT, NULL);
|
||||
cv_init(&spa->spa_proc_cv, NULL, CV_DEFAULT, NULL);
|
||||
|
@ -668,6 +669,7 @@ spa_remove(spa_t *spa)
|
|||
mutex_destroy(&spa->spa_scrub_lock);
|
||||
mutex_destroy(&spa->spa_suspend_lock);
|
||||
mutex_destroy(&spa->spa_vdev_top_lock);
|
||||
mutex_destroy(&spa->spa_feat_stats_lock);
|
||||
|
||||
kmem_free(spa, sizeof (spa_t));
|
||||
}
|
||||
|
|
|
@ -68,7 +68,6 @@
|
|||
#include <sys/zpl.h>
|
||||
#include "zfs_comutil.h"
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
zfs_sync(struct super_block *sb, int wait, cred_t *cr)
|
||||
|
@ -1074,6 +1073,67 @@ zfs_root(zfs_sb_t *zsb, struct inode **ipp)
|
|||
}
|
||||
EXPORT_SYMBOL(zfs_root);
|
||||
|
||||
#if !defined(HAVE_SPLIT_SHRINKER_CALLBACK) && !defined(HAVE_SHRINK) && \
|
||||
defined(HAVE_D_PRUNE_ALIASES)
|
||||
/*
|
||||
* Linux kernels older than 3.1 do not support a per-filesystem shrinker.
|
||||
* To accommodate this we must improvise and manually walk the list of znodes
|
||||
* attempting to prune dentries in order to be able to drop the inodes.
|
||||
*
|
||||
* To avoid scanning the same znodes multiple times they are always rotated
|
||||
* to the end of the z_all_znodes list. New znodes are inserted at the
|
||||
* end of the list so we're always scanning the oldest znodes first.
|
||||
*/
|
||||
static int
|
||||
zfs_sb_prune_aliases(zfs_sb_t *zsb, unsigned long nr_to_scan)
|
||||
{
|
||||
znode_t **zp_array, *zp;
|
||||
int max_array = MIN(nr_to_scan, PAGE_SIZE * 8 / sizeof (znode_t *));
|
||||
int objects = 0;
|
||||
int i = 0, j = 0;
|
||||
|
||||
zp_array = kmem_zalloc(max_array * sizeof (znode_t *), KM_SLEEP);
|
||||
|
||||
mutex_enter(&zsb->z_znodes_lock);
|
||||
while ((zp = list_head(&zsb->z_all_znodes)) != NULL) {
|
||||
|
||||
if ((i++ > nr_to_scan) || (j >= max_array))
|
||||
break;
|
||||
|
||||
ASSERT(list_link_active(&zp->z_link_node));
|
||||
list_remove(&zsb->z_all_znodes, zp);
|
||||
list_insert_tail(&zsb->z_all_znodes, zp);
|
||||
|
||||
/* Skip active znodes and .zfs entries */
|
||||
if (MUTEX_HELD(&zp->z_lock) || zp->z_is_ctldir)
|
||||
continue;
|
||||
|
||||
if (igrab(ZTOI(zp)) == NULL)
|
||||
continue;
|
||||
|
||||
zp_array[j] = zp;
|
||||
j++;
|
||||
}
|
||||
mutex_exit(&zsb->z_znodes_lock);
|
||||
|
||||
for (i = 0; i < j; i++) {
|
||||
zp = zp_array[i];
|
||||
|
||||
ASSERT3P(zp, !=, NULL);
|
||||
d_prune_aliases(ZTOI(zp));
|
||||
|
||||
if (atomic_read(&ZTOI(zp)->i_count) == 1)
|
||||
objects++;
|
||||
|
||||
iput(ZTOI(zp));
|
||||
}
|
||||
|
||||
kmem_free(zp_array, max_array * sizeof (znode_t *));
|
||||
|
||||
return (objects);
|
||||
}
|
||||
#endif /* HAVE_D_PRUNE_ALIASES */
|
||||
|
||||
/*
|
||||
* The ARC has requested that the filesystem drop entries from the dentry
|
||||
* and inode caches. This can occur when the ARC needs to free meta data
|
||||
|
@ -1094,22 +1154,24 @@ zfs_sb_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects)
|
|||
|
||||
ZFS_ENTER(zsb);
|
||||
|
||||
#if defined(HAVE_SPLIT_SHRINKER_CALLBACK)
|
||||
#if defined(HAVE_SPLIT_SHRINKER_CALLBACK) && \
|
||||
defined(SHRINK_CONTROL_HAS_NID) && \
|
||||
defined(SHRINKER_NUMA_AWARE)
|
||||
if (sb->s_shrink.flags & SHRINKER_NUMA_AWARE) {
|
||||
*objects = 0;
|
||||
for_each_online_node(sc.nid)
|
||||
*objects += (*shrinker->scan_objects)(shrinker, &sc);
|
||||
} else {
|
||||
*objects = (*shrinker->scan_objects)(shrinker, &sc);
|
||||
}
|
||||
#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK)
|
||||
*objects = (*shrinker->scan_objects)(shrinker, &sc);
|
||||
#elif defined(HAVE_SHRINK)
|
||||
*objects = (*shrinker->shrink)(shrinker, &sc);
|
||||
#elif defined(HAVE_D_PRUNE_ALIASES)
|
||||
*objects = zfs_sb_prune_aliases(zsb, nr_to_scan);
|
||||
#else
|
||||
/*
|
||||
* Linux kernels older than 3.1 do not support a per-filesystem
|
||||
* shrinker. Therefore, we must fall back to the only available
|
||||
* interface which is to discard all unused dentries and inodes.
|
||||
* This behavior clearly isn't ideal but it's required so the ARC
|
||||
* may free memory. The performance impact is mitigated by the
|
||||
* fact that the frequently accessed dentry and inode buffers will
|
||||
* still be in the ARC making them relatively cheap to recreate.
|
||||
*/
|
||||
*objects = 0;
|
||||
shrink_dcache_parent(sb->s_root);
|
||||
#error "No available dentry and inode cache pruning mechanism."
|
||||
#endif
|
||||
ZFS_EXIT(zsb);
|
||||
|
||||
|
@ -1137,8 +1199,28 @@ zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting)
|
|||
* drain the iput_taskq to ensure all active references to the
|
||||
* zfs_sb_t have been handled only then can it be safely destroyed.
|
||||
*/
|
||||
if (zsb->z_os)
|
||||
taskq_wait(dsl_pool_iput_taskq(dmu_objset_pool(zsb->z_os)));
|
||||
if (zsb->z_os) {
|
||||
/*
|
||||
* If we're unmounting we have to wait for the list to
|
||||
* drain completely.
|
||||
*
|
||||
* If we're not unmounting there's no guarantee the list
|
||||
* will drain completely, but iputs run from the taskq
|
||||
* may add the parents of dir-based xattrs to the taskq
|
||||
* so we want to wait for these.
|
||||
*
|
||||
* We can safely read z_nr_znodes without locking because the
|
||||
* VFS has already blocked operations which add to the
|
||||
* z_all_znodes list and thus increment z_nr_znodes.
|
||||
*/
|
||||
int round = 0;
|
||||
while (zsb->z_nr_znodes > 0) {
|
||||
taskq_wait(dsl_pool_iput_taskq(dmu_objset_pool(
|
||||
zsb->z_os)));
|
||||
if (++round > 1 && !unmounting)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rrw_enter(&zsb->z_teardown_lock, RW_WRITER, FTAG);
|
||||
|
||||
|
@ -1182,13 +1264,15 @@ zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting)
|
|||
*
|
||||
* Release all holds on dbufs.
|
||||
*/
|
||||
mutex_enter(&zsb->z_znodes_lock);
|
||||
for (zp = list_head(&zsb->z_all_znodes); zp != NULL;
|
||||
zp = list_next(&zsb->z_all_znodes, zp)) {
|
||||
if (zp->z_sa_hdl)
|
||||
zfs_znode_dmu_fini(zp);
|
||||
if (!unmounting) {
|
||||
mutex_enter(&zsb->z_znodes_lock);
|
||||
for (zp = list_head(&zsb->z_all_znodes); zp != NULL;
|
||||
zp = list_next(&zsb->z_all_znodes, zp)) {
|
||||
if (zp->z_sa_hdl)
|
||||
zfs_znode_dmu_fini(zp);
|
||||
}
|
||||
mutex_exit(&zsb->z_znodes_lock);
|
||||
}
|
||||
mutex_exit(&zsb->z_znodes_lock);
|
||||
|
||||
/*
|
||||
* If we are unmounting, set the unmounted flag and let new VFS ops
|
||||
|
|
|
@ -147,12 +147,14 @@ void
|
|||
zfs_znode_init(void)
|
||||
{
|
||||
/*
|
||||
* Initialize zcache
|
||||
* Initialize zcache. The KMC_SLAB hint is used in order that it be
|
||||
* backed by kmalloc() when on the Linux slab in order that any
|
||||
* wait_on_bit() operations on the related inode operate properly.
|
||||
*/
|
||||
ASSERT(znode_cache == NULL);
|
||||
znode_cache = kmem_cache_create("zfs_znode_cache",
|
||||
sizeof (znode_t), 0, zfs_znode_cache_constructor,
|
||||
zfs_znode_cache_destructor, NULL, NULL, NULL, KMC_KMEM);
|
||||
zfs_znode_cache_destructor, NULL, NULL, NULL, KMC_SLAB);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -948,6 +950,8 @@ again:
|
|||
mutex_exit(&zp->z_lock);
|
||||
sa_buf_rele(db, NULL);
|
||||
ZFS_OBJ_HOLD_EXIT(zsb, obj_num);
|
||||
/* inode might need this to finish evict */
|
||||
cond_resched();
|
||||
goto again;
|
||||
}
|
||||
*zpp = zp;
|
||||
|
|
|
@ -226,14 +226,17 @@ zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
|
|||
#endif
|
||||
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
cred_t *cr = CRED();
|
||||
struct inode *ip = NULL;
|
||||
int error;
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip,
|
||||
0, cr, NULL, NULL);
|
||||
ASSERT3S(error, <=, 0);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
|
||||
if (error && error != -ENOENT)
|
||||
|
@ -250,21 +253,23 @@ static int
|
|||
zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
||||
{
|
||||
zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
|
||||
fstrans_cookie_t cookie;
|
||||
char snapname[MAXNAMELEN];
|
||||
boolean_t case_conflict;
|
||||
uint64_t id, cookie;
|
||||
uint64_t id, pos;
|
||||
int error = 0;
|
||||
|
||||
ZFS_ENTER(zsb);
|
||||
cookie = spl_fstrans_mark();
|
||||
|
||||
if (!dir_emit_dots(filp, ctx))
|
||||
goto out;
|
||||
|
||||
cookie = ctx->pos;
|
||||
pos = ctx->pos;
|
||||
while (error == 0) {
|
||||
dsl_pool_config_enter(dmu_objset_pool(zsb->z_os), FTAG);
|
||||
error = -dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN,
|
||||
snapname, &id, &cookie, &case_conflict);
|
||||
snapname, &id, &pos, &case_conflict);
|
||||
dsl_pool_config_exit(dmu_objset_pool(zsb->z_os), FTAG);
|
||||
if (error)
|
||||
goto out;
|
||||
|
@ -273,9 +278,10 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
|||
ZFSCTL_INO_SHARES - id, DT_DIR))
|
||||
goto out;
|
||||
|
||||
ctx->pos = cookie;
|
||||
ctx->pos = pos;
|
||||
}
|
||||
out:
|
||||
spl_fstrans_unmark(cookie);
|
||||
ZFS_EXIT(zsb);
|
||||
|
||||
if (error == -ENOENT)
|
||||
|
@ -414,14 +420,17 @@ zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
|
|||
unsigned int flags)
|
||||
#endif
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
cred_t *cr = CRED();
|
||||
struct inode *ip = NULL;
|
||||
int error;
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfsctl_shares_lookup(dip, dname(dentry), &ip,
|
||||
0, cr, NULL, NULL);
|
||||
ASSERT3S(error, <=, 0);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
|
||||
if (error) {
|
||||
|
@ -437,12 +446,14 @@ zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
|
|||
static int
|
||||
zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
cred_t *cr = CRED();
|
||||
zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
|
||||
znode_t *dzp;
|
||||
int error = 0;
|
||||
|
||||
ZFS_ENTER(zsb);
|
||||
cookie = spl_fstrans_mark();
|
||||
|
||||
if (zsb->z_shares_dir == 0) {
|
||||
dir_emit_dots(filp, ctx);
|
||||
|
@ -459,6 +470,7 @@ zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
|
|||
|
||||
iput(ZTOI(dzp));
|
||||
out:
|
||||
spl_fstrans_unmark(cookie);
|
||||
ZFS_EXIT(zsb);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ zpl_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, int connectable)
|
|||
{
|
||||
struct inode *ip = dentry->d_inode;
|
||||
#endif /* HAVE_ENCODE_FH_WITH_INODE */
|
||||
fstrans_cookie_t cookie;
|
||||
fid_t *fid = (fid_t *)fh;
|
||||
int len_bytes, rc;
|
||||
|
||||
|
@ -48,12 +49,14 @@ zpl_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, int connectable)
|
|||
return (255);
|
||||
|
||||
fid->fid_len = len_bytes - offsetof(fid_t, fid_data);
|
||||
cookie = spl_fstrans_mark();
|
||||
|
||||
if (zfsctl_is_node(ip))
|
||||
rc = zfsctl_fid(ip, fid);
|
||||
else
|
||||
rc = zfs_fid(ip, fid);
|
||||
|
||||
spl_fstrans_unmark(cookie);
|
||||
len_bytes = offsetof(fid_t, fid_data) + fid->fid_len;
|
||||
*max_len = roundup(len_bytes, sizeof (__u32)) / sizeof (__u32);
|
||||
|
||||
|
@ -84,6 +87,7 @@ zpl_fh_to_dentry(struct super_block *sb, struct fid *fh,
|
|||
int fh_len, int fh_type)
|
||||
{
|
||||
fid_t *fid = (fid_t *)fh;
|
||||
fstrans_cookie_t cookie;
|
||||
struct inode *ip;
|
||||
int len_bytes, rc;
|
||||
|
||||
|
@ -94,7 +98,9 @@ zpl_fh_to_dentry(struct super_block *sb, struct fid *fh,
|
|||
len_bytes < offsetof(fid_t, fid_data) + fid->fid_len)
|
||||
return (ERR_PTR(-EINVAL));
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
rc = zfs_vget(sb, &ip, fid);
|
||||
spl_fstrans_unmark(cookie);
|
||||
|
||||
if (rc != 0)
|
||||
return (ERR_PTR(-rc));
|
||||
|
@ -108,11 +114,14 @@ static struct dentry *
|
|||
zpl_get_parent(struct dentry *child)
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
fstrans_cookie_t cookie;
|
||||
struct inode *ip;
|
||||
int error;
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_lookup(child->d_inode, "..", &ip, 0, cr, NULL, NULL);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
||||
|
@ -127,10 +136,13 @@ static int
|
|||
zpl_commit_metadata(struct inode *inode)
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
fstrans_cookie_t cookie;
|
||||
int error;
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_fsync(inode, 0, cr);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
||||
|
|
|
@ -196,8 +196,7 @@ zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
|
|||
static int
|
||||
zpl_aio_fsync(struct kiocb *kiocb, int datasync)
|
||||
{
|
||||
return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos,
|
||||
kiocb->ki_pos + kiocb->ki_nbytes, datasync));
|
||||
return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos, -1, datasync));
|
||||
}
|
||||
#else
|
||||
#error "Unsupported fops->fsync() implementation"
|
||||
|
@ -261,12 +260,11 @@ zpl_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
|
|||
}
|
||||
|
||||
static ssize_t
|
||||
zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
|
||||
unsigned long nr_segs, loff_t pos)
|
||||
zpl_iter_read_common(struct kiocb *kiocb, const struct iovec *iovp,
|
||||
unsigned long nr_segs, size_t count)
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
struct file *filp = kiocb->ki_filp;
|
||||
size_t count = kiocb->ki_nbytes;
|
||||
ssize_t read;
|
||||
size_t alloc_size = sizeof (struct iovec) * nr_segs;
|
||||
struct iovec *iov_tmp = kmem_alloc(alloc_size, KM_SLEEP);
|
||||
|
@ -284,6 +282,22 @@ zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
|
|||
return (read);
|
||||
}
|
||||
|
||||
#if defined(HAVE_VFS_RW_ITERATE)
|
||||
static ssize_t
|
||||
zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to)
|
||||
{
|
||||
return (zpl_iter_read_common(kiocb, to->iov, to->nr_segs,
|
||||
iov_iter_count(to)));
|
||||
}
|
||||
#else
|
||||
static ssize_t
|
||||
zpl_aio_read(struct kiocb *kiocb, const struct iovec *iovp,
|
||||
unsigned long nr_segs, loff_t pos)
|
||||
{
|
||||
return (zpl_iter_read_common(kiocb, iovp, nr_segs, kiocb->ki_nbytes));
|
||||
}
|
||||
#endif /* HAVE_VFS_RW_ITERATE */
|
||||
|
||||
static inline ssize_t
|
||||
zpl_write_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count,
|
||||
unsigned long nr_segs, loff_t *ppos, uio_seg_t segment,
|
||||
|
@ -344,12 +358,11 @@ zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
|
|||
}
|
||||
|
||||
static ssize_t
|
||||
zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
|
||||
unsigned long nr_segs, loff_t pos)
|
||||
zpl_iter_write_common(struct kiocb *kiocb, const struct iovec *iovp,
|
||||
unsigned long nr_segs, size_t count)
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
struct file *filp = kiocb->ki_filp;
|
||||
size_t count = kiocb->ki_nbytes;
|
||||
ssize_t wrote;
|
||||
size_t alloc_size = sizeof (struct iovec) * nr_segs;
|
||||
struct iovec *iov_tmp = kmem_alloc(alloc_size, KM_SLEEP);
|
||||
|
@ -367,6 +380,22 @@ zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
|
|||
return (wrote);
|
||||
}
|
||||
|
||||
#if defined(HAVE_VFS_RW_ITERATE)
|
||||
static ssize_t
|
||||
zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from)
|
||||
{
|
||||
return (zpl_iter_write_common(kiocb, from->iov, from->nr_segs,
|
||||
iov_iter_count(from)));
|
||||
}
|
||||
#else
|
||||
static ssize_t
|
||||
zpl_aio_write(struct kiocb *kiocb, const struct iovec *iovp,
|
||||
unsigned long nr_segs, loff_t pos)
|
||||
{
|
||||
return (zpl_iter_write_common(kiocb, iovp, nr_segs, kiocb->ki_nbytes));
|
||||
}
|
||||
#endif /* HAVE_VFS_RW_ITERATE */
|
||||
|
||||
static loff_t
|
||||
zpl_llseek(struct file *filp, loff_t offset, int whence)
|
||||
{
|
||||
|
@ -778,8 +807,13 @@ const struct file_operations zpl_file_operations = {
|
|||
.llseek = zpl_llseek,
|
||||
.read = zpl_read,
|
||||
.write = zpl_write,
|
||||
#ifdef HAVE_VFS_RW_ITERATE
|
||||
.read_iter = zpl_iter_read,
|
||||
.write_iter = zpl_iter_write,
|
||||
#else
|
||||
.aio_read = zpl_aio_read,
|
||||
.aio_write = zpl_aio_write,
|
||||
#endif
|
||||
.mmap = zpl_mmap,
|
||||
.fsync = zpl_fsync,
|
||||
.aio_fsync = zpl_aio_fsync,
|
||||
|
|
|
@ -106,13 +106,13 @@ zpl_create(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
|
|||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL);
|
||||
spl_fstrans_unmark(cookie);
|
||||
if (error == 0) {
|
||||
VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
|
||||
VERIFY0(zpl_init_acl(ip, dir));
|
||||
d_instantiate(dentry, ip);
|
||||
}
|
||||
|
||||
spl_fstrans_unmark(cookie);
|
||||
kmem_free(vap, sizeof (vattr_t));
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
@ -144,13 +144,13 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
|
|||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL);
|
||||
spl_fstrans_unmark(cookie);
|
||||
if (error == 0) {
|
||||
VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
|
||||
VERIFY0(zpl_init_acl(ip, dir));
|
||||
d_instantiate(dentry, ip);
|
||||
}
|
||||
|
||||
spl_fstrans_unmark(cookie);
|
||||
kmem_free(vap, sizeof (vattr_t));
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
@ -190,13 +190,13 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, zpl_umode_t mode)
|
|||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
|
||||
spl_fstrans_unmark(cookie);
|
||||
if (error == 0) {
|
||||
VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
|
||||
VERIFY0(zpl_init_acl(ip, dir));
|
||||
d_instantiate(dentry, ip);
|
||||
}
|
||||
|
||||
spl_fstrans_unmark(cookie);
|
||||
kmem_free(vap, sizeof (vattr_t));
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
@ -273,10 +273,10 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
|||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_setattr(ip, vap, 0, cr);
|
||||
spl_fstrans_unmark(cookie);
|
||||
if (!error && (ia->ia_valid & ATTR_MODE))
|
||||
error = zpl_chmod_acl(ip);
|
||||
|
||||
spl_fstrans_unmark(cookie);
|
||||
kmem_free(vap, sizeof (vattr_t));
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
@ -317,12 +317,12 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
|
|||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
|
||||
spl_fstrans_unmark(cookie);
|
||||
if (error == 0) {
|
||||
VERIFY0(zpl_xattr_security_init(ip, dir, &dentry->d_name));
|
||||
d_instantiate(dentry, ip);
|
||||
}
|
||||
|
||||
spl_fstrans_unmark(cookie);
|
||||
kmem_free(vap, sizeof (vattr_t));
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
@ -391,7 +391,6 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
|||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_link(dir, ip, dname(dentry), cr);
|
||||
spl_fstrans_unmark(cookie);
|
||||
if (error) {
|
||||
iput(ip);
|
||||
goto out;
|
||||
|
@ -399,6 +398,7 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
|||
|
||||
d_instantiate(dentry, ip);
|
||||
out:
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
||||
|
|
|
@ -57,13 +57,21 @@ zpl_inode_destroy(struct inode *ip)
|
|||
static void
|
||||
zpl_dirty_inode(struct inode *ip, int flags)
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
zfs_dirty_inode(ip, flags);
|
||||
spl_fstrans_unmark(cookie);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
zpl_dirty_inode(struct inode *ip)
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
zfs_dirty_inode(ip, 0);
|
||||
spl_fstrans_unmark(cookie);
|
||||
}
|
||||
#endif /* HAVE_DIRTY_INODE_WITH_FLAGS */
|
||||
|
||||
|
@ -136,20 +144,26 @@ zpl_inode_delete(struct inode *ip)
|
|||
static void
|
||||
zpl_put_super(struct super_block *sb)
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
int error;
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_umount(sb);
|
||||
spl_fstrans_unmark(cookie);
|
||||
ASSERT3S(error, <=, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
zpl_sync_fs(struct super_block *sb, int wait)
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
cred_t *cr = CRED();
|
||||
int error;
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_sync(sb, wait, cr);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
||||
|
@ -159,9 +173,12 @@ zpl_sync_fs(struct super_block *sb, int wait)
|
|||
static int
|
||||
zpl_statfs(struct dentry *dentry, struct kstatfs *statp)
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
int error;
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_statvfs(dentry, statp);
|
||||
spl_fstrans_unmark(cookie);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
||||
return (error);
|
||||
|
@ -170,8 +187,12 @@ zpl_statfs(struct dentry *dentry, struct kstatfs *statp)
|
|||
static int
|
||||
zpl_remount_fs(struct super_block *sb, int *flags, char *data)
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
int error;
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_remount(sb, flags, data);
|
||||
spl_fstrans_unmark(cookie);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
||||
return (error);
|
||||
|
@ -242,9 +263,12 @@ zpl_show_options(struct seq_file *seq, struct vfsmount *vfsp)
|
|||
static int
|
||||
zpl_fill_super(struct super_block *sb, void *data, int silent)
|
||||
{
|
||||
fstrans_cookie_t cookie;
|
||||
int error;
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_domount(sb, data, silent);
|
||||
spl_fstrans_unmark(cookie);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
||||
return (error);
|
||||
|
|
|
@ -209,9 +209,11 @@ zpl_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
|
|||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
xattr_filldir_t xf = { buffer_size, 0, buffer, dentry->d_inode };
|
||||
cred_t *cr = CRED();
|
||||
fstrans_cookie_t cookie;
|
||||
int error = 0;
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
rw_enter(&zp->z_xattr_lock, RW_READER);
|
||||
|
||||
if (zsb->z_use_sa && zp->z_is_sa) {
|
||||
|
@ -228,6 +230,7 @@ zpl_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
|
|||
out:
|
||||
|
||||
rw_exit(&zp->z_xattr_lock);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
|
||||
return (error);
|
||||
|
@ -337,12 +340,15 @@ zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size)
|
|||
{
|
||||
znode_t *zp = ITOZ(ip);
|
||||
cred_t *cr = CRED();
|
||||
fstrans_cookie_t cookie;
|
||||
int error;
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
rw_enter(&zp->z_xattr_lock, RW_READER);
|
||||
error = __zpl_xattr_get(ip, name, value, size, cr);
|
||||
rw_exit(&zp->z_xattr_lock);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
|
||||
return (error);
|
||||
|
@ -482,9 +488,11 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
|
|||
znode_t *zp = ITOZ(ip);
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
cred_t *cr = CRED();
|
||||
fstrans_cookie_t cookie;
|
||||
int error;
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
rw_enter(&ITOZ(ip)->z_xattr_lock, RW_WRITER);
|
||||
|
||||
/*
|
||||
|
@ -522,6 +530,7 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
|
|||
error = zpl_xattr_set_dir(ip, name, value, size, flags, cr);
|
||||
out:
|
||||
rw_exit(&ITOZ(ip)->z_xattr_lock);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
|
||||
|
|
|
@ -185,6 +185,20 @@ chmod u+x ${RPM_BUILD_ROOT}%{kmodinstdir_prefix}/*/extra/*/*/*
|
|||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%changelog
|
||||
* Wed Jun 24 2015 Ned Bass <bass6@llnl.gov> - 0.6.4.2-1
|
||||
- Fix panic due to corrupt nvlist when running utilities zfsonlinux/zfs#3335
|
||||
- Fix hard lockup due to infinite loop in zfs_zget() zfsonlinux/zfs#3349
|
||||
- Fix panic on unmount due to iput taskq zfsonlinux/zfs#3281
|
||||
- Improve metadata shrinker performance on pre-3.1 kernels zfsonlinux/zfs#3501
|
||||
- Linux 4.1 compat: use read_iter() / write_iter()
|
||||
- Linux 3.12 compat: NUMA-aware per-superblock shrinker
|
||||
- Fix spurious hung task watchdog stack traces zfsonlinux/zfs#3402
|
||||
- Fix module loading in zfs import systemd service zfsonlinux/zfs#3440
|
||||
- Fix intermittent libzfs_init() failure to open /dev/zfs zfsonlinux/zfs#2556
|
||||
* Thu Apr 23 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.4.1-1
|
||||
- Fix direct memory reclaim deadlocks zfsonlinux/zfs#3331 zfsonlinux/zfs#3225
|
||||
- Fix hot-disk sparing for disk vdevs zfsonlinux/zfs#3310
|
||||
- Fix system spinning during ARC reclaim zfsonlinux/zfs#3283
|
||||
* Wed Apr 8 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.4-1
|
||||
- Released 0.6.4-1
|
||||
* Thu Jun 12 2014 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.3-1
|
||||
|
|
|
@ -295,6 +295,20 @@ exit 0
|
|||
%{_dracutdir}/modules.d/*
|
||||
|
||||
%changelog
|
||||
* Wed Jun 24 2015 Ned Bass <bass6@llnl.gov> - 0.6.4.2-1
|
||||
- Fix panic due to corrupt nvlist when running utilities zfsonlinux/zfs#3335
|
||||
- Fix hard lockup due to infinite loop in zfs_zget() zfsonlinux/zfs#3349
|
||||
- Fix panic on unmount due to iput taskq zfsonlinux/zfs#3281
|
||||
- Improve metadata shrinker performance on pre-3.1 kernels zfsonlinux/zfs#3501
|
||||
- Linux 4.1 compat: use read_iter() / write_iter()
|
||||
- Linux 3.12 compat: NUMA-aware per-superblock shrinker
|
||||
- Fix spurious hung task watchdog stack traces zfsonlinux/zfs#3402
|
||||
- Fix module loading in zfs import systemd service zfsonlinux/zfs#3440
|
||||
- Fix intermittent libzfs_init() failure to open /dev/zfs zfsonlinux/zfs#2556
|
||||
* Thu Apr 23 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.4.1-1
|
||||
- Fix direct memory reclaim deadlocks zfsonlinux/zfs#3331 zfsonlinux/zfs#3225
|
||||
- Fix hot-disk sparing for disk vdevs zfsonlinux/zfs#3310
|
||||
- Fix system spinning during ARC reclaim zfsonlinux/zfs#3283
|
||||
* Wed Apr 8 2015 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.4-1
|
||||
- Released 0.6.4-1
|
||||
* Thu Jun 12 2014 Brian Behlendorf <behlendorf1@llnl.gov> - 0.6.3-1
|
||||
|
|
Loading…
Reference in New Issue