Skip to content

Commit

Permalink
Add locks for vfs_mntpoint
Browse files Browse the repository at this point in the history
Signed-off-by: Umer Saleem <[email protected]>
  • Loading branch information
usaleem-ix committed Oct 9, 2024
1 parent 27f65ae commit e01dd2a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 23 deletions.
1 change: 1 addition & 0 deletions include/os/linux/zfs/sys/zfs_vfsops_os.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ typedef struct vfs {
boolean_t vfs_do_relatime;
boolean_t vfs_nbmand;
boolean_t vfs_do_nbmand;
kmutex_t vfs_mntpt_lock;
} vfs_t;

typedef struct zfs_mnt {
Expand Down
45 changes: 26 additions & 19 deletions module/os/linux/zfs/zfs_ctldir.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,9 +767,6 @@ zfsctl_snapshot_path_objset(zfsvfs_t *zfsvfs, uint64_t objsetid,
uint64_t id, pos = 0;
int error = 0;

if (zfsvfs->z_vfs->vfs_mntpoint == NULL)
return (SET_ERROR(ENOENT));

cookie = spl_fstrans_mark();
snapname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);

Expand All @@ -786,8 +783,14 @@ zfsctl_snapshot_path_objset(zfsvfs_t *zfsvfs, uint64_t objsetid,
break;
}

snprintf(full_path, path_len, "%s/.zfs/snapshot/%s",
zfsvfs->z_vfs->vfs_mntpoint, snapname);
mutex_enter(&zfsvfs->z_vfs->vfs_mntpt_lock);
if (zfsvfs->z_vfs->vfs_mntpoint != NULL) {
snprintf(full_path, path_len, "%s/.zfs/snapshot/%s",
zfsvfs->z_vfs->vfs_mntpoint, snapname);
} else
error = SET_ERROR(ENOENT);
mutex_exit(&zfsvfs->z_vfs->vfs_mntpt_lock);

out:
kmem_free(snapname, ZFS_MAX_DATASET_NAME_LEN);
spl_fstrans_unmark(cookie);
Expand Down Expand Up @@ -1182,21 +1185,22 @@ zfsctl_snapshot_mount(struct path *path, int flags)
/*
* Current process is not in chroot context
*/
if (zfsvfs->z_vfs->vfs_mntpoint != NULL) {
char *m = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
struct path mnt_path;
mnt_path.mnt = path->mnt;
mnt_path.dentry = path->mnt->mnt_root;

/*
* Get path to current mountpoint
*/
error = get_root_path(&mnt_path, m, MAXPATHLEN);
if (error != 0) {
kmem_free(m, MAXPATHLEN);
goto error;
}
char *m = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
struct path mnt_path;
mnt_path.mnt = path->mnt;
mnt_path.dentry = path->mnt->mnt_root;

/*
* Get path to current mountpoint
*/
error = get_root_path(&mnt_path, m, MAXPATHLEN);
if (error != 0) {
kmem_free(m, MAXPATHLEN);
goto error;
}
mutex_enter(&zfsvfs->z_vfs->vfs_mntpt_lock);
if (zfsvfs->z_vfs->vfs_mntpoint != NULL) {
/*
* If current mnountpoint and vfs_mntpoint are not same,
* store current mountpoint in vfs_mntpoint.
Expand All @@ -1205,18 +1209,21 @@ zfsctl_snapshot_mount(struct path *path, int flags)
kmem_strfree(zfsvfs->z_vfs->vfs_mntpoint);
zfsvfs->z_vfs->vfs_mntpoint = kmem_strdup(m);
}
kmem_free(m, MAXPATHLEN);
}
mutex_exit(&zfsvfs->z_vfs->vfs_mntpt_lock);
kmem_free(m, MAXPATHLEN);
}

/*
* Construct a mount point path from sb of the ctldir inode and dirent
* name, instead of from d_path(), so that chroot'd process doesn't fail
* on mount.zfs(8).
*/
mutex_enter(&zfsvfs->z_vfs->vfs_mntpt_lock);
snprintf(full_path, MAXPATHLEN, "%s/.zfs/snapshot/%s",
zfsvfs->z_vfs->vfs_mntpoint ? zfsvfs->z_vfs->vfs_mntpoint : "",
dname(dentry));
mutex_exit(&zfsvfs->z_vfs->vfs_mntpt_lock);

snprintf(options, 7, "%s",
zfs_snapshot_no_setuid ? "nosuid" : "suid");
Expand Down
15 changes: 11 additions & 4 deletions module/os/linux/zfs/zfs_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,12 @@ static void
zfsvfs_vfs_free(vfs_t *vfsp)
{
if (vfsp != NULL) {
if (vfsp->vfs_mntpoint != NULL)
mutex_enter(&vfsp->vfs_mntpt_lock);
if (vfsp->vfs_mntpoint != NULL) {
kmem_strfree(vfsp->vfs_mntpoint);

}
mutex_exit(&vfsp->vfs_mntpt_lock);
mutex_destroy(&vfsp->vfs_mntpt_lock);
kmem_free(vfsp, sizeof (vfs_t));
}
}
Expand Down Expand Up @@ -197,10 +200,13 @@ zfsvfs_parse_option(char *option, int token, substring_t *args, vfs_t *vfsp)
vfsp->vfs_do_nbmand = B_TRUE;
break;
case TOKEN_MNTPOINT:
mutex_enter(&vfsp->vfs_mntpt_lock);
vfsp->vfs_mntpoint = match_strdup(&args[0]);
if (vfsp->vfs_mntpoint == NULL)
if (vfsp->vfs_mntpoint == NULL) {
mutex_exit(&vfsp->vfs_mntpt_lock);
return (SET_ERROR(ENOMEM));

}
mutex_exit(&vfsp->vfs_mntpt_lock);
break;
default:
break;
Expand All @@ -219,6 +225,7 @@ zfsvfs_parse_options(char *mntopts, vfs_t **vfsp)
int error;

tmp_vfsp = kmem_zalloc(sizeof (vfs_t), KM_SLEEP);
mutex_init(&tmp_vfsp->vfs_mntpt_lock, NULL, MUTEX_DEFAULT, NULL);

if (mntopts != NULL) {
substring_t args[MAX_OPT_ARGS];
Expand Down

0 comments on commit e01dd2a

Please sign in to comment.