zfs: implement AT_RENAME_NOREPLACE
Reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D55539
This commit is contained in:
@@ -42,8 +42,8 @@ extern int zfs_rmdir(znode_t *dzp, const char *name, znode_t *cwd,
|
||||
extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr,
|
||||
zidmap_t *mnt_ns);
|
||||
extern int zfs_rename(znode_t *sdzp, const char *snm, znode_t *tdzp,
|
||||
const char *tnm, cred_t *cr, int flags, uint64_t rflags, vattr_t *wo_vap,
|
||||
zidmap_t *mnt_ns);
|
||||
const char *tnm, cred_t *cr, int flags, uint64_t rflags, u_int at_flags,
|
||||
vattr_t *wo_vap, zidmap_t *mnt_ns);
|
||||
extern int zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
|
||||
const char *link, znode_t **zpp, cred_t *cr, int flags, zidmap_t *mnt_ns);
|
||||
extern int zfs_link(znode_t *tdzp, znode_t *sp,
|
||||
|
||||
@@ -3256,7 +3256,7 @@ zfs_rename_check(znode_t *szp, znode_t *sdzp, znode_t *tdzp)
|
||||
static int
|
||||
zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
|
||||
vnode_t *tdvp, vnode_t **tvpp, struct componentname *tcnp,
|
||||
cred_t *cr);
|
||||
cred_t *cr, u_int at_flags);
|
||||
|
||||
/*
|
||||
* Move an entry from the provided source directory to the target
|
||||
@@ -3267,6 +3267,7 @@ zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
|
||||
* tdvp - Target directory to contain the "new entry".
|
||||
* tcnp - New entry name.
|
||||
* cr - credentials of caller.
|
||||
* at_flags - AT_RENAME_*
|
||||
* INOUT: svpp - Source file
|
||||
* tvpp - Target file, may point to NULL initially
|
||||
*
|
||||
@@ -3278,7 +3279,7 @@ zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
|
||||
static int
|
||||
zfs_do_rename(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
|
||||
vnode_t *tdvp, vnode_t **tvpp, struct componentname *tcnp,
|
||||
cred_t *cr)
|
||||
cred_t *cr, u_int at_flags)
|
||||
{
|
||||
int error;
|
||||
|
||||
@@ -3307,7 +3308,8 @@ zfs_do_rename(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = zfs_do_rename_impl(sdvp, svpp, scnp, tdvp, tvpp, tcnp, cr);
|
||||
error = zfs_do_rename_impl(sdvp, svpp, scnp, tdvp, tvpp, tcnp, cr,
|
||||
at_flags);
|
||||
VOP_UNLOCK(sdvp);
|
||||
VOP_UNLOCK(*svpp);
|
||||
out:
|
||||
@@ -3322,7 +3324,7 @@ zfs_do_rename(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
|
||||
static int
|
||||
zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
|
||||
vnode_t *tdvp, vnode_t **tvpp, struct componentname *tcnp,
|
||||
cred_t *cr)
|
||||
cred_t *cr, u_int at_flags)
|
||||
{
|
||||
dmu_tx_t *tx;
|
||||
zfsvfs_t *zfsvfs;
|
||||
@@ -3431,6 +3433,11 @@ zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
|
||||
* Does target exist?
|
||||
*/
|
||||
if (tzp) {
|
||||
if ((at_flags & AT_RENAME_NOREPLACE) != 0) {
|
||||
error = SET_ERROR(EEXIST);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Source and target must be the same type.
|
||||
*/
|
||||
@@ -3551,7 +3558,8 @@ zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
|
||||
|
||||
int
|
||||
zfs_rename(znode_t *sdzp, const char *sname, znode_t *tdzp, const char *tname,
|
||||
cred_t *cr, int flags, uint64_t rflags, vattr_t *wo_vap, zidmap_t *mnt_ns)
|
||||
cred_t *cr, int flags, uint64_t rflags, u_int at_flags, vattr_t *wo_vap,
|
||||
zidmap_t *mnt_ns)
|
||||
{
|
||||
struct componentname scn, tcn;
|
||||
vnode_t *sdvp, *tdvp;
|
||||
@@ -3583,7 +3591,8 @@ zfs_rename(znode_t *sdzp, const char *sname, znode_t *tdzp, const char *tname,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = zfs_do_rename(sdvp, &svp, &scn, tdvp, &tvp, &tcn, cr);
|
||||
error = zfs_do_rename(sdvp, &svp, &scn, tdvp, &tvp, &tcn, cr,
|
||||
at_flags);
|
||||
fail:
|
||||
if (svp != NULL)
|
||||
vrele(svp);
|
||||
@@ -5527,12 +5536,12 @@ zfs_freebsd_rename(struct vop_rename_args *ap)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (error == 0 && ap->a_flags != 0)
|
||||
if (error == 0 && (ap->a_flags & ~(AT_RENAME_NOREPLACE)) != 0)
|
||||
error = EOPNOTSUPP;
|
||||
|
||||
if (error == 0) {
|
||||
error = zfs_do_rename(fdvp, &fvp, ap->a_fcnp, tdvp, &tvp,
|
||||
ap->a_tcnp, ap->a_fcnp->cn_cred);
|
||||
ap->a_tcnp, ap->a_fcnp->cn_cred, ap->a_flags);
|
||||
vrele(fdvp);
|
||||
vrele(fvp);
|
||||
vrele(tdvp);
|
||||
|
||||
@@ -710,7 +710,7 @@ do_zfs_replay_rename(zfsvfs_t *zfsvfs, _lr_rename_t *lr, char *sname,
|
||||
wo_vap, zfs_init_idmap);
|
||||
#else
|
||||
error = zfs_rename(sdzp, sname, tdzp, tname, kcred, vflg, rflags,
|
||||
wo_vap, NULL);
|
||||
0, wo_vap, NULL);
|
||||
#endif
|
||||
|
||||
zrele(tdzp);
|
||||
|
||||
Reference in New Issue
Block a user