/*ARGSUSED*/ int zfsctl_snapdir_rename(struct inode *sdip, char *sname, struct inode *tdip, char *tname, cred_t *cr, int flags) { zfs_sb_t *zsb = ITOZSB(sdip); zfs_snapentry_t search, *sep; avl_index_t where; char *to, *from, *real; int error; ZFS_ENTER(zsb); to = kmem_alloc(MAXNAMELEN, KM_SLEEP); from = kmem_alloc(MAXNAMELEN, KM_SLEEP); real = kmem_alloc(MAXNAMELEN, KM_SLEEP); if (zsb->z_case == ZFS_CASE_INSENSITIVE) { error = dmu_snapshot_realname(zsb->z_os, sname, real, MAXNAMELEN, NULL); if (error == 0) { sname = real; } else if (error != ENOTSUP) { goto out; } } error = zfsctl_snapshot_zname(sdip, sname, MAXNAMELEN, from); if (!error) error = zfsctl_snapshot_zname(tdip, tname, MAXNAMELEN, to); if (!error) error = zfs_secpolicy_rename_perms(from, to, cr); if (error) goto out; /* * Cannot move snapshots out of the snapdir. */ if (sdip != tdip) { error = EINVAL; goto out; } /* * No-op when names are identical. */ if (strcmp(sname, tname) == 0) { error = 0; goto out; } mutex_enter(&zsb->z_ctldir_lock); error = dmu_objset_rename(from, to, B_FALSE); if (error) goto out_unlock; search.se_name = (char *)sname; sep = avl_find(&zsb->z_ctldir_snaps, &search, &where); if (sep) zfsctl_rename_snap(zsb, sep, tname); out_unlock: mutex_exit(&zsb->z_ctldir_lock); out: kmem_free(from, MAXNAMELEN); kmem_free(to, MAXNAMELEN); kmem_free(real, MAXNAMELEN); ZFS_EXIT(zsb); return (error); }
/*ARGSUSED*/ static int zfsctl_snapdir_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, cred_t *cr, caller_context_t *ct, int flags) { zfsctl_snapdir_t *sdp = sdvp->v_data; zfs_snapentry_t search, *sep; zfsvfs_t *zfsvfs; avl_index_t where; char from[MAXNAMELEN], to[MAXNAMELEN]; char real[MAXNAMELEN]; int err; zfsvfs = sdvp->v_vfsp->vfs_data; ZFS_ENTER(zfsvfs); if ((flags & FIGNORECASE) || zfsvfs->z_case == ZFS_CASE_INSENSITIVE) { err = dmu_snapshot_realname(zfsvfs->z_os, snm, real, MAXNAMELEN, NULL); if (err == 0) { snm = real; } else if (err != ENOTSUP) { ZFS_EXIT(zfsvfs); return (err); } } ZFS_EXIT(zfsvfs); err = zfsctl_snapshot_zname(sdvp, snm, MAXNAMELEN, from); if (!err) err = zfsctl_snapshot_zname(tdvp, tnm, MAXNAMELEN, to); if (!err) err = zfs_secpolicy_rename_perms(from, to, cr); if (err) return (err); /* * Cannot move snapshots out of the snapdir. */ if (sdvp != tdvp) return (EINVAL); if (strcmp(snm, tnm) == 0) return (0); mutex_enter(&sdp->sd_lock); search.se_name = (char *)snm; if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) == NULL) { mutex_exit(&sdp->sd_lock); return (ENOENT); } err = dmu_objset_rename(from, to, B_FALSE); if (err == 0) zfsctl_rename_snap(sdp, sep, tnm); mutex_exit(&sdp->sd_lock); return (err); }