summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sys/zfs_ctldir.h3
-rw-r--r--module/zfs/zfs_ctldir.c32
-rw-r--r--module/zfs/zpl_inode.c3
3 files changed, 26 insertions, 12 deletions
diff --git a/include/sys/zfs_ctldir.h b/include/sys/zfs_ctldir.h
index 960a9a629..65c44f3cc 100644
--- a/include/sys/zfs_ctldir.h
+++ b/include/sys/zfs_ctldir.h
@@ -77,7 +77,8 @@ extern int zfsctl_snapdir_mkdir(struct inode *dip, char *dirname, vattr_t *vap,
extern void zfsctl_snapdir_inactive(struct inode *ip);
extern int zfsctl_snapshot_mount(struct path *path, int flags);
extern int zfsctl_snapshot_unmount(char *snapname, int flags);
-extern int zfsctl_snapshot_unmount_delay(uint64_t objsetid, int delay);
+extern int zfsctl_snapshot_unmount_delay(spa_t *spa, uint64_t objsetid,
+ int delay);
extern int zfsctl_lookup_objset(struct super_block *sb, uint64_t objsetid,
zfs_sb_t **zsb);
diff --git a/module/zfs/zfs_ctldir.c b/module/zfs/zfs_ctldir.c
index 745a467b7..b03c4e5d0 100644
--- a/module/zfs/zfs_ctldir.c
+++ b/module/zfs/zfs_ctldir.c
@@ -81,6 +81,7 @@
#include <sys/zfs_vnops.h>
#include <sys/stat.h>
#include <sys/dmu.h>
+#include <sys/dmu_objset.h>
#include <sys/dsl_destroy.h>
#include <sys/dsl_deleg.h>
#include <sys/mount.h>
@@ -117,6 +118,7 @@ static taskq_t *zfs_expire_taskq;
typedef struct {
char *se_name; /* full snapshot name */
char *se_path; /* full mount path */
+ spa_t *se_spa; /* pool spa */
uint64_t se_objsetid; /* snapshot objset id */
struct dentry *se_root_dentry; /* snapshot root dentry */
taskqid_t se_taskqid; /* scheduled unmount taskqid */
@@ -132,8 +134,8 @@ static void zfsctl_snapshot_unmount_delay_impl(zfs_snapentry_t *se, int delay);
* the snapshot name and provided mount point. No reference is taken.
*/
static zfs_snapentry_t *
-zfsctl_snapshot_alloc(char *full_name, char *full_path, uint64_t objsetid,
- struct dentry *root_dentry)
+zfsctl_snapshot_alloc(char *full_name, char *full_path, spa_t *spa,
+ uint64_t objsetid, struct dentry *root_dentry)
{
zfs_snapentry_t *se;
@@ -141,6 +143,7 @@ zfsctl_snapshot_alloc(char *full_name, char *full_path, uint64_t objsetid,
se->se_name = strdup(full_name);
se->se_path = strdup(full_path);
+ se->se_spa = spa;
se->se_objsetid = objsetid;
se->se_root_dentry = root_dentry;
se->se_taskqid = -1;
@@ -242,6 +245,9 @@ snapentry_compare_by_objsetid(const void *a, const void *b)
const zfs_snapentry_t *se_a = a;
const zfs_snapentry_t *se_b = b;
+ if (se_a->se_spa != se_b->se_spa)
+ return ((ulong_t)se_a->se_spa < (ulong_t)se_b->se_spa ? -1 : 1);
+
if (se_a->se_objsetid < se_b->se_objsetid)
return (-1);
else if (se_a->se_objsetid > se_b->se_objsetid)
@@ -278,12 +284,13 @@ zfsctl_snapshot_find_by_name(char *snapname)
* as zfsctl_snapshot_find_by_name().
*/
static zfs_snapentry_t *
-zfsctl_snapshot_find_by_objsetid(uint64_t objsetid)
+zfsctl_snapshot_find_by_objsetid(spa_t *spa, uint64_t objsetid)
{
zfs_snapentry_t *se, search;
ASSERT(MUTEX_HELD(&zfs_snapshot_lock));
+ search.se_spa = spa;
search.se_objsetid = objsetid;
se = avl_find(&zfs_snapshots_by_objsetid, &search, NULL);
if (se)
@@ -323,6 +330,7 @@ static void
snapentry_expire(void *data)
{
zfs_snapentry_t *se = (zfs_snapentry_t *)data;
+ spa_t *spa = se->se_spa;
uint64_t objsetid = se->se_objsetid;
se->se_taskqid = -1;
@@ -334,7 +342,7 @@ snapentry_expire(void *data)
* This can occur when the snapshot is busy.
*/
mutex_enter(&zfs_snapshot_lock);
- if ((se = zfsctl_snapshot_find_by_objsetid(objsetid)) != NULL) {
+ if ((se = zfsctl_snapshot_find_by_objsetid(spa, objsetid)) != NULL) {
zfsctl_snapshot_unmount_delay_impl(se, zfs_expire_snapshot);
zfsctl_snapshot_rele(se);
}
@@ -377,13 +385,13 @@ zfsctl_snapshot_unmount_delay_impl(zfs_snapentry_t *se, int delay)
* and held until the outstanding task is handled or cancelled.
*/
int
-zfsctl_snapshot_unmount_delay(uint64_t objsetid, int delay)
+zfsctl_snapshot_unmount_delay(spa_t *spa, uint64_t objsetid, int delay)
{
zfs_snapentry_t *se;
int error = ENOENT;
mutex_enter(&zfs_snapshot_lock);
- if ((se = zfsctl_snapshot_find_by_objsetid(objsetid)) != NULL) {
+ if ((se = zfsctl_snapshot_find_by_objsetid(spa, objsetid)) != NULL) {
zfsctl_snapshot_unmount_cancel(se);
zfsctl_snapshot_unmount_delay_impl(se, delay);
zfsctl_snapshot_rele(se);
@@ -560,10 +568,12 @@ zfsctl_destroy(zfs_sb_t *zsb)
{
if (zsb->z_issnap) {
zfs_snapentry_t *se;
+ spa_t *spa = zsb->z_os->os_spa;
uint64_t objsetid = dmu_objset_id(zsb->z_os);
mutex_enter(&zfs_snapshot_lock);
- if ((se = zfsctl_snapshot_find_by_objsetid(objsetid)) != NULL) {
+ if ((se = zfsctl_snapshot_find_by_objsetid(spa, objsetid))
+ != NULL) {
zfsctl_snapshot_unmount_cancel(se);
zfsctl_snapshot_remove(se);
zfsctl_snapshot_rele(se);
@@ -1129,7 +1139,8 @@ zfsctl_snapshot_mount(struct path *path, int flags)
mutex_enter(&zfs_snapshot_lock);
se = zfsctl_snapshot_alloc(full_name, full_path,
- dmu_objset_id(snap_zsb->z_os), dentry);
+ snap_zsb->z_os->os_spa, dmu_objset_id(snap_zsb->z_os),
+ dentry);
zfsctl_snapshot_add(se);
zfsctl_snapshot_unmount_delay_impl(se, zfs_expire_snapshot);
mutex_exit(&zfs_snapshot_lock);
@@ -1152,6 +1163,7 @@ zfsctl_lookup_objset(struct super_block *sb, uint64_t objsetid, zfs_sb_t **zsbp)
{
zfs_snapentry_t *se;
int error;
+ spa_t *spa = ((zfs_sb_t *)(sb->s_fs_info))->z_os->os_spa;
/*
* Verify that the snapshot is mounted then lookup the mounted root
@@ -1161,7 +1173,7 @@ zfsctl_lookup_objset(struct super_block *sb, uint64_t objsetid, zfs_sb_t **zsbp)
* because we hold the zfs_snapshot_lock to prevent the race.
*/
mutex_enter(&zfs_snapshot_lock);
- if ((se = zfsctl_snapshot_find_by_objsetid(objsetid)) != NULL) {
+ if ((se = zfsctl_snapshot_find_by_objsetid(spa, objsetid)) != NULL) {
zfs_sb_t *zsb;
zsb = ITOZSB(se->se_root_dentry->d_inode);
@@ -1170,7 +1182,7 @@ zfsctl_lookup_objset(struct super_block *sb, uint64_t objsetid, zfs_sb_t **zsbp)
if (time_after(jiffies, zsb->z_snap_defer_time +
MAX(zfs_expire_snapshot * HZ / 2, HZ))) {
zsb->z_snap_defer_time = jiffies;
- zfsctl_snapshot_unmount_delay(objsetid,
+ zfsctl_snapshot_unmount_delay(spa, objsetid,
zfs_expire_snapshot);
}
diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
index 6475c72d7..e0e8ee3ac 100644
--- a/module/zfs/zpl_inode.c
+++ b/module/zfs/zpl_inode.c
@@ -28,6 +28,7 @@
#include <sys/zfs_vfsops.h>
#include <sys/zfs_vnops.h>
#include <sys/zfs_znode.h>
+#include <sys/dmu_objset.h>
#include <sys/vfs.h>
#include <sys/zpl.h>
@@ -500,7 +501,7 @@ zpl_revalidate(struct dentry *dentry, unsigned int flags)
if (time_after(jiffies, zsb->z_snap_defer_time +
MAX(zfs_expire_snapshot * HZ / 2, HZ))) {
zsb->z_snap_defer_time = jiffies;
- zfsctl_snapshot_unmount_delay(
+ zfsctl_snapshot_unmount_delay(zsb->z_os->os_spa,
dmu_objset_id(zsb->z_os), zfs_expire_snapshot);
}
}