]> granicus.if.org Git - zfs/commitdiff
Illumos 4039 - zfs_rename()/zfs_link() needs stronger test for XDEV
authorMarcel Telka <marcel.telka@nexenta.com>
Wed, 13 Jan 2016 23:35:55 +0000 (15:35 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 15 Jan 2016 23:38:35 +0000 (15:38 -0800)
4039 zfs_rename()/zfs_link() needs stronger test for XDEV
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Saso Kiselkov <skiselkov.ml@gmail.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@nexenta.com>

References:
  https://www.illumos.org/issues/4039
  https://github.com/illumos/illumos-gate/commit/18e6497

Porting notes:
- This check was updated in Linux in a similar fashion early on in
  the port.  Therefore, this patch just reorders the function and
  updates the comment so it flows the same way as the upstream code.

Ported-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #4218

module/zfs/zfs_vnops.c

index 64412a69dd2fcef19871916a3fa6dd20bb3c4bea..311613ae55c61c88156fba3d69bd9bfcce464e16 100644 (file)
@@ -3207,13 +3207,18 @@ zfs_rename(struct inode *sdip, char *snm, struct inode *tdip, char *tnm,
        ZFS_VERIFY_ZP(sdzp);
        zilog = zsb->z_log;
 
+       tdzp = ITOZ(tdip);
+       ZFS_VERIFY_ZP(tdzp);
+
+       /*
+        * We check i_sb because snapshots and the ctldir must have different
+        * super blocks.
+        */
        if (tdip->i_sb != sdip->i_sb || zfsctl_is_node(tdip)) {
                ZFS_EXIT(zsb);
                return (SET_ERROR(EXDEV));
        }
 
-       tdzp = ITOZ(tdip);
-       ZFS_VERIFY_ZP(tdzp);
        if (zsb->z_utf8 && u8_validate(tnm,
            strlen(tnm), NULL, U8_VALIDATE_ENTIRE, &error) < 0) {
                ZFS_EXIT(zsb);
@@ -3751,14 +3756,18 @@ zfs_link(struct inode *tdip, struct inode *sip, char *name, cred_t *cr)
                return (SET_ERROR(EPERM));
        }
 
+       szp = ITOZ(sip);
+       ZFS_VERIFY_ZP(szp);
+
+       /*
+        * We check i_sb because snapshots and the ctldir must have different
+        * super blocks.
+        */
        if (sip->i_sb != tdip->i_sb || zfsctl_is_node(sip)) {
                ZFS_EXIT(zsb);
                return (SET_ERROR(EXDEV));
        }
 
-       szp = ITOZ(sip);
-       ZFS_VERIFY_ZP(szp);
-
        /* Prevent links to .zfs/shares files */
 
        if ((error = sa_lookup(szp->z_sa_hdl, SA_ZPL_PARENT(zsb),