Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F169594255
D30041.id90444.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D30041.id90444.diff
View Options
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1328,6 +1328,7 @@
}
if (error != 0)
return (error);
+ NDPREINIT(&nd);
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
@@ -1436,6 +1437,7 @@
int error;
AUDIT_ARG_MODE(mode);
+ NDPREINIT(&nd);
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
@@ -1566,6 +1568,7 @@
struct nameidata nd;
int error;
+ NDPREINIT(&nd);
do {
bwillwrite();
NDINIT_ATRIGHTS(&nd, LOOKUP, AUDITVNODE1 | at2cnpflags(flag,
@@ -1714,6 +1717,7 @@
syspath = tmppath;
}
AUDIT_ARG_TEXT(syspath);
+ NDPREINIT(&nd);
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
@@ -1778,6 +1782,7 @@
struct nameidata nd;
int error;
+ NDPREINIT(&nd);
restart:
bwillwrite();
NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | AUDITVNODE1,
@@ -1891,6 +1896,7 @@
return (error);
}
+ NDPREINIT(&nd);
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
@@ -3422,6 +3428,7 @@
if (length < 0)
return (EINVAL);
+ NDPREINIT(&nd);
retry:
NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, td);
if ((error = namei(&nd)) != 0)
@@ -3789,6 +3796,7 @@
int error;
AUDIT_ARG_MODE(mode);
+ NDPREINIT(&nd);
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
@@ -3859,6 +3867,7 @@
return (error);
}
+ NDPREINIT(&nd);
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
diff --git a/sys/sys/namei.h b/sys/sys/namei.h
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -38,6 +38,7 @@
#include <sys/caprights.h>
#include <sys/filedesc.h>
#include <sys/queue.h>
+#include <sys/_seqc.h>
#include <sys/_uio.h>
enum nameiop { LOOKUP, CREATE, DELETE, RENAME };
@@ -111,6 +112,12 @@
*/
struct componentname ni_cnd;
struct nameicap_tracker_head ni_cap_tracker;
+ /*
+ * Private helper data for UFS, must be at the end. See
+ * NDINIT_PREFILL().
+ */
+ seqc_t ni_dvp_seqc;
+ seqc_t ni_vp_seqc;
};
#ifdef _KERNEL
@@ -224,7 +231,8 @@
* Note the constant pattern may *hide* bugs.
*/
#ifdef INVARIANTS
-#define NDINIT_PREFILL(arg) memset(arg, 0xff, sizeof(*arg))
+#define NDINIT_PREFILL(arg) memset(arg, 0xff, sizeof(struct nameidata) - \
+ offsetof(struct nameidata, ni_dvp_seqc))
#define NDINIT_DBG(arg) { (arg)->ni_debugflags = NAMEI_DBG_INITED; }
#define NDREINIT_DBG(arg) { \
if (((arg)->ni_debugflags & NAMEI_DBG_INITED) == 0) \
@@ -265,6 +273,11 @@
_ndp->ni_startdir = NULL; \
} while (0)
+#define NDPREINIT(ndp) do { \
+ (ndp)->ni_dvp_seqc = SEQC_MOD; \
+ (ndp)->ni_vp_seqc = SEQC_MOD; \
+} while (0)
+
#define NDF_NO_DVP_RELE 0x00000001
#define NDF_NO_DVP_UNLOCK 0x00000002
#define NDF_NO_DVP_PUT 0x00000003
diff --git a/sys/sys/seqc.h b/sys/sys/seqc.h
--- a/sys/sys/seqc.h
+++ b/sys/sys/seqc.h
@@ -45,13 +45,15 @@
#include <machine/cpu.h>
+#define SEQC_MOD 1
+
/*
* Predicts from inline functions are not honored by clang.
*/
#define seqc_in_modify(seqc) ({ \
seqc_t __seqc = (seqc); \
\
- __predict_false(__seqc & 1); \
+ __predict_false(__seqc & SEQC_MOD); \
})
static __inline void
@@ -60,7 +62,7 @@
critical_enter();
MPASS(!seqc_in_modify(*seqcp));
- *seqcp += 1;
+ *seqcp += SEQC_MOD;
atomic_thread_fence_rel();
}
@@ -69,7 +71,7 @@
{
atomic_thread_fence_rel();
- *seqcp += 1;
+ *seqcp += SEQC_MOD;
MPASS(!seqc_in_modify(*seqcp));
critical_exit();
}
@@ -85,7 +87,7 @@
seqc_read_notmodify(const seqc_t *seqcp)
{
- return (atomic_load_acq_int(__DECONST(seqc_t *, seqcp)) & ~1);
+ return (atomic_load_acq_int(__DECONST(seqc_t *, seqcp)) & ~SEQC_MOD);
}
static __inline seqc_t
@@ -126,7 +128,7 @@
{
MPASS(!seqc_in_modify(*seqcp));
- *seqcp += 1;
+ *seqcp += SEQC_MOD;
atomic_thread_fence_rel();
}
@@ -135,7 +137,7 @@
{
atomic_thread_fence_rel();
- *seqcp += 1;
+ *seqcp += SEQC_MOD;
MPASS(!seqc_in_modify(*seqcp));
}
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -517,6 +517,7 @@
} */ *ap;
{
struct ufsmount *ump;
+ int error;
/*
* We used to skip reallocating the blocks of a file into a
@@ -546,9 +547,11 @@
if (DOINGSUJ(ap->a_vp))
if (softdep_prealloc(ap->a_vp, MNT_NOWAIT) != 0)
return (ENOSPC);
- if (ump->um_fstype == UFS1)
- return (ffs_reallocblks_ufs1(ap));
- return (ffs_reallocblks_ufs2(ap));
+ vn_seqc_write_begin(ap->a_vp);
+ error = ump->um_fstype == UFS1 ? ffs_reallocblks_ufs1(ap) :
+ ffs_reallocblks_ufs2(ap);
+ vn_seqc_write_end(ap->a_vp);
+ return (error);
}
static int
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
--- a/sys/ufs/ffs/ffs_balloc.c
+++ b/sys/ufs/ffs/ffs_balloc.c
@@ -128,6 +128,8 @@
return (EFBIG);
gbflags = (flags & BA_UNMAPPED) != 0 ? GB_UNMAPPED : 0;
+ vn_seqc_write_begin(vp);
+
/*
* If the next write will extend the file into a new block,
* and the file is currently composed of a fragment
@@ -144,7 +146,7 @@
&dp->di_db[0]), osize, (int)fs->fs_bsize, flags,
cred, &bp);
if (error)
- return (error);
+ goto done;
if (DOINGSOFTDEP(vp))
softdep_setup_allocdirect(ip, nb,
dbtofsb(fs, bp->b_blkno), dp->di_db[nb],
@@ -174,17 +176,20 @@
error = bread(vp, lbn, fs->fs_bsize, NOCRED,
&bp);
if (error != 0)
- return (error);
+ goto done;
} else {
bp = getblk(vp, lbn, fs->fs_bsize, 0, 0,
gbflags);
- if (bp == NULL)
- return (EIO);
+ if (bp == NULL) {
+ error = EIO;
+ goto done;
+ }
vfs_bio_clrbuf(bp);
}
bp->b_blkno = fsbtodb(fs, nb);
*bpp = bp;
- return (0);
+ error = 0;
+ goto done;
}
if (nb != 0) {
/*
@@ -194,9 +199,8 @@
nsize = fragroundup(fs, size);
if (nsize <= osize) {
error = bread(vp, lbn, osize, NOCRED, &bp);
- if (error) {
- return (error);
- }
+ if (error)
+ goto done;
bp->b_blkno = fsbtodb(fs, nb);
} else {
UFS_LOCK(ump);
@@ -205,7 +209,7 @@
&dp->di_db[0]), osize, nsize, flags,
cred, &bp);
if (error)
- return (error);
+ goto done;
if (DOINGSOFTDEP(vp))
softdep_setup_allocdirect(ip, lbn,
dbtofsb(fs, bp->b_blkno), nb,
@@ -221,7 +225,7 @@
ffs_blkpref_ufs1(ip, lbn, (int)lbn, &dp->di_db[0]),
nsize, flags, cred, &newb);
if (error)
- return (error);
+ goto done;
bp = getblk(vp, lbn, nsize, 0, 0, gbflags);
bp->b_blkno = fsbtodb(fs, newb);
if (flags & BA_CLRBUF)
@@ -233,14 +237,15 @@
dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE | IN_IBLKDATA);
*bpp = bp;
- return (0);
+ error = 0;
+ goto done;
}
/*
* Determine the number of levels of indirection.
*/
pref = 0;
if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
- return(error);
+ goto done;
#ifdef INVARIANTS
if (num < 1)
panic ("ffs_balloc_ufs1: ufs_getlbns returned indirect block");
@@ -261,7 +266,7 @@
if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
flags, cred, &newb)) != 0) {
curthread_pflags_restore(saved_inbdflush);
- return (error);
+ goto done;
}
pref = newb + fs->fs_frag;
nb = newb;
@@ -387,7 +392,8 @@
if (flags & BA_METAONLY) {
curthread_pflags_restore(saved_inbdflush);
*bpp = bp;
- return (0);
+ error = 0;
+ goto done;
}
/*
* Get the data block, allocating if necessary.
@@ -453,7 +459,8 @@
}
curthread_pflags_restore(saved_inbdflush);
*bpp = nbp;
- return (0);
+ error = 0;
+ goto done;
}
brelse(bp);
if (flags & BA_CLRBUF) {
@@ -478,7 +485,8 @@
}
curthread_pflags_restore(saved_inbdflush);
*bpp = nbp;
- return (0);
+ error = 0;
+ goto done;
fail:
curthread_pflags_restore(saved_inbdflush);
/*
@@ -486,7 +494,7 @@
* This is the usual case and avoids the need to fsync the file.
*/
if (allocblk == allociblk && allocib == NULL && unwindidx == -1)
- return (error);
+ goto done;
/*
* If we have failed part way through block allocation, we
* have to deallocate any indirect blocks that we have allocated.
@@ -574,6 +582,8 @@
ffs_blkfree(ump, fs, ump->um_devvp, *blkp, fs->fs_bsize,
ip->i_number, vp->v_type, NULL, SINGLETON_KEY);
}
+done:
+ vn_seqc_write_end(vp);
return (error);
}
@@ -619,12 +629,17 @@
return (EFBIG);
gbflags = (flags & BA_UNMAPPED) != 0 ? GB_UNMAPPED : 0;
+ vn_seqc_write_begin(vp);
+
/*
* Check for allocating external data.
*/
if (flags & IO_EXT) {
- if (lbn >= UFS_NXADDR)
- return (EFBIG);
+ if (lbn >= UFS_NXADDR) {
+ error = EFBIG;
+ goto done;
+ }
+
/*
* If the next write will extend the data into a new block,
* and the data is currently composed of a fragment
@@ -642,7 +657,7 @@
&dp->di_extb[0]), osize,
(int)fs->fs_bsize, flags, cred, &bp);
if (error)
- return (error);
+ goto done;
if (DOINGSOFTDEP(vp))
softdep_setup_allocext(ip, nb,
dbtofsb(fs, bp->b_blkno),
@@ -668,13 +683,12 @@
if (nb != 0 && dp->di_extsize >= smalllblktosize(fs, lbn + 1)) {
error = bread_gb(vp, -1 - lbn, fs->fs_bsize, NOCRED,
gbflags, &bp);
- if (error) {
- return (error);
- }
+ if (error)
+ goto done;
bp->b_blkno = fsbtodb(fs, nb);
bp->b_xflags |= BX_ALTDATA;
*bpp = bp;
- return (0);
+ goto done;
}
if (nb != 0) {
/*
@@ -685,9 +699,8 @@
if (nsize <= osize) {
error = bread_gb(vp, -1 - lbn, osize, NOCRED,
gbflags, &bp);
- if (error) {
- return (error);
- }
+ if (error)
+ goto done;
bp->b_blkno = fsbtodb(fs, nb);
bp->b_xflags |= BX_ALTDATA;
} else {
@@ -698,7 +711,7 @@
&dp->di_extb[0]), osize, nsize, flags,
cred, &bp);
if (error)
- return (error);
+ goto done;
bp->b_xflags |= BX_ALTDATA;
if (DOINGSOFTDEP(vp))
softdep_setup_allocext(ip, lbn,
@@ -715,7 +728,7 @@
ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]),
nsize, flags, cred, &newb);
if (error)
- return (error);
+ goto done;
bp = getblk(vp, -1 - lbn, nsize, 0, 0, gbflags);
bp->b_blkno = fsbtodb(fs, newb);
bp->b_xflags |= BX_ALTDATA;
@@ -728,7 +741,8 @@
dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno);
UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_IBLKDATA);
*bpp = bp;
- return (0);
+ error = 0;
+ goto done;
}
/*
* If the next write will extend the file into a new block,
@@ -746,7 +760,7 @@
&dp->di_db[0]), osize, (int)fs->fs_bsize,
flags, cred, &bp);
if (error)
- return (error);
+ goto done;
if (DOINGSOFTDEP(vp))
softdep_setup_allocdirect(ip, nb,
dbtofsb(fs, bp->b_blkno),
@@ -775,17 +789,20 @@
error = bread_gb(vp, lbn, fs->fs_bsize, NOCRED,
gbflags, &bp);
if (error != 0)
- return (error);
+ goto done;
} else {
bp = getblk(vp, lbn, fs->fs_bsize, 0, 0,
gbflags);
- if (bp == NULL)
- return (EIO);
+ if (bp == NULL) {
+ error = EIO;
+ goto done;
+ }
vfs_bio_clrbuf(bp);
}
bp->b_blkno = fsbtodb(fs, nb);
*bpp = bp;
- return (0);
+ error = 0;
+ goto done;
}
if (nb != 0) {
/*
@@ -796,9 +813,8 @@
if (nsize <= osize) {
error = bread_gb(vp, lbn, osize, NOCRED,
gbflags, &bp);
- if (error) {
- return (error);
- }
+ if (error)
+ goto done;
bp->b_blkno = fsbtodb(fs, nb);
} else {
UFS_LOCK(ump);
@@ -807,7 +823,7 @@
&dp->di_db[0]), osize, nsize, flags,
cred, &bp);
if (error)
- return (error);
+ goto done;
if (DOINGSOFTDEP(vp))
softdep_setup_allocdirect(ip, lbn,
dbtofsb(fs, bp->b_blkno), nb,
@@ -823,7 +839,7 @@
ffs_blkpref_ufs2(ip, lbn, (int)lbn,
&dp->di_db[0]), nsize, flags, cred, &newb);
if (error)
- return (error);
+ goto done;
bp = getblk(vp, lbn, nsize, 0, 0, gbflags);
bp->b_blkno = fsbtodb(fs, newb);
if (flags & BA_CLRBUF)
@@ -835,14 +851,15 @@
dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE | IN_IBLKDATA);
*bpp = bp;
- return (0);
+ error = 0;
+ goto done;
}
/*
* Determine the number of levels of indirection.
*/
pref = 0;
if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
- return(error);
+ goto done;
#ifdef INVARIANTS
if (num < 1)
panic ("ffs_balloc_ufs2: ufs_getlbns returned indirect block");
@@ -863,7 +880,7 @@
if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
flags, cred, &newb)) != 0) {
curthread_pflags_restore(saved_inbdflush);
- return (error);
+ goto done;
}
pref = newb + fs->fs_frag;
nb = newb;
@@ -991,7 +1008,8 @@
if (flags & BA_METAONLY) {
curthread_pflags_restore(saved_inbdflush);
*bpp = bp;
- return (0);
+ error = 0;
+ goto done;
}
/*
* Get the data block, allocating if necessary.
@@ -1057,7 +1075,8 @@
}
curthread_pflags_restore(saved_inbdflush);
*bpp = nbp;
- return (0);
+ error = 0;
+ goto done;
}
brelse(bp);
/*
@@ -1088,7 +1107,8 @@
}
curthread_pflags_restore(saved_inbdflush);
*bpp = nbp;
- return (0);
+ error = 0;
+ goto done;
fail:
curthread_pflags_restore(saved_inbdflush);
/*
@@ -1096,7 +1116,7 @@
* This is the usual case and avoids the need to fsync the file.
*/
if (allocblk == allociblk && allocib == NULL && unwindidx == -1)
- return (error);
+ goto done;
/*
* If we have failed part way through block allocation, we
* have to deallocate any indirect blocks that we have allocated.
@@ -1184,5 +1204,7 @@
ffs_blkfree(ump, fs, ump->um_devvp, *blkp, fs->fs_bsize,
ip->i_number, vp->v_type, NULL, SINGLETON_KEY);
}
+done:
+ vn_seqc_write_end(vp);
return (error);
}
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -181,7 +181,8 @@
struct ucred *, int);
int softdep_prerename(struct vnode *, struct vnode *, struct vnode *,
struct vnode *);
-int softdep_prelink(struct vnode *, struct vnode *);
+int softdep_prelink(struct vnode *, struct vnode *,
+ struct componentname *);
void softdep_setup_freeblocks(struct inode *, off_t, int);
void softdep_setup_inomapdep(struct buf *, struct inode *, ino_t, int);
void softdep_setup_blkmapdep(struct buf *, struct mount *, ufs2_daddr_t,
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -621,9 +621,10 @@
}
int
-softdep_prelink(dvp, vp)
+softdep_prelink(dvp, vp, cnp)
struct vnode *dvp;
struct vnode *vp;
+ struct componentname *cnp;
{
panic("softdep_prelink called");
@@ -3384,11 +3385,13 @@
* syscall must be restarted at top level from the lookup.
*/
int
-softdep_prelink(dvp, vp)
+softdep_prelink(dvp, vp, cnp)
struct vnode *dvp;
struct vnode *vp;
+ struct componentname *cnp;
{
struct ufsmount *ump;
+ struct nameidata *ndp;
ASSERT_VOP_ELOCKED(dvp, "prelink dvp");
if (vp != NULL)
@@ -3404,37 +3407,42 @@
if (journal_space(ump, 0) || (vp != NULL && IS_SNAPSHOT(VTOI(vp))))
return (0);
+ ndp = __containerof(cnp, struct nameidata, ni_cnd);
+ if (!seqc_in_modify(ndp->ni_dvp_seqc) &&
+ vn_seqc_consistent(dvp, ndp->ni_dvp_seqc) &&
+ (vp == NULL || (!seqc_in_modify(ndp->ni_vp_seqc) &&
+ vn_seqc_consistent(vp, ndp->ni_vp_seqc))))
+ return (0);
+
stat_journal_low++;
if (vp != NULL) {
VOP_UNLOCK(dvp);
ffs_syncvnode(vp, MNT_NOWAIT, 0);
vn_lock_pair(dvp, false, vp, true);
if (dvp->v_data == NULL)
- return (ERELOOKUP);
+ goto out;
}
if (vp != NULL)
VOP_UNLOCK(vp);
ffs_syncvnode(dvp, MNT_WAIT, 0);
- VOP_UNLOCK(dvp);
-
/* Process vp before dvp as it may create .. removes. */
if (vp != NULL) {
+ VOP_UNLOCK(dvp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
if (vp->v_data == NULL) {
vn_lock_pair(dvp, false, vp, true);
- return (ERELOOKUP);
+ goto out;
}
ACQUIRE_LOCK(ump);
process_removes(vp);
process_truncates(vp);
FREE_LOCK(ump);
VOP_UNLOCK(vp);
- }
-
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
- if (dvp->v_data == NULL) {
- vn_lock_pair(dvp, true, vp, false);
- return (ERELOOKUP);
+ vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
+ if (dvp->v_data == NULL) {
+ vn_lock_pair(dvp, true, vp, false);
+ goto out;
+ }
}
ACQUIRE_LOCK(ump);
@@ -3452,6 +3460,10 @@
FREE_LOCK(ump);
vn_lock_pair(dvp, false, vp, false);
+out:
+ ndp->ni_dvp_seqc = vn_seqc_read_any(dvp);
+ if (vp != NULL)
+ ndp->ni_vp_seqc = vn_seqc_read_any(vp);
return (ERELOOKUP);
}
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -105,14 +105,16 @@
static vop_accessx_t ufs_accessx;
static vop_fplookup_vexec_t ufs_fplookup_vexec;
static int ufs_chmod(struct vnode *, int, struct ucred *, struct thread *);
-static int ufs_chown(struct vnode *, uid_t, gid_t, struct ucred *, struct thread *);
+static int ufs_chown(struct vnode *, uid_t, gid_t, struct ucred *,
+ struct thread *);
static vop_close_t ufs_close;
static vop_create_t ufs_create;
static vop_stat_t ufs_stat;
static vop_getattr_t ufs_getattr;
static vop_ioctl_t ufs_ioctl;
static vop_link_t ufs_link;
-static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *, const char *);
+static int ufs_makeinode(int mode, struct vnode *, struct vnode **,
+ struct componentname *, const char *);
static vop_mmapped_t ufs_mmapped;
static vop_mkdir_t ufs_mkdir;
static vop_mknod_t ufs_mknod;
@@ -1008,7 +1010,7 @@
(VTOI(dvp)->i_flags & APPEND))
return (EPERM);
if (DOINGSUJ(dvp)) {
- error = softdep_prelink(dvp, vp);
+ error = softdep_prelink(dvp, vp, ap->a_cnp);
if (error != 0) {
MPASS(error == ERELOOKUP);
return (error);
@@ -1073,7 +1075,7 @@
#endif
if (DOINGSUJ(tdvp)) {
- error = softdep_prelink(tdvp, vp);
+ error = softdep_prelink(tdvp, vp, cnp);
if (error != 0) {
MPASS(error == ERELOOKUP);
return (error);
@@ -1145,7 +1147,7 @@
if (DOINGSUJ(dvp) && (ap->a_flags == CREATE ||
ap->a_flags == DELETE)) {
- error = softdep_prelink(dvp, NULL);
+ error = softdep_prelink(dvp, NULL, cnp);
if (error != 0) {
MPASS(error == ERELOOKUP);
return (error);
@@ -1246,6 +1248,7 @@
int error = 0;
struct mount *mp;
ino_t ino;
+ seqc_t fdvp_s, fvp_s, tdvp_s, tvp_s;
bool want_seqc_end;
want_seqc_end = false;
@@ -1269,6 +1272,8 @@
mp = NULL;
goto releout;
}
+
+ fdvp_s = fvp_s = tdvp_s = tvp_s = SEQC_MOD;
relock:
/*
* We need to acquire 2 to 4 locks depending on whether tvp is NULL
@@ -1362,10 +1367,20 @@
}
}
- if (DOINGSOFTDEP(fdvp)) {
+ if (DOINGSUJ(fdvp) &&
+ (seqc_in_modify(fdvp_s) || !vn_seqc_consistent(fdvp, fdvp_s) ||
+ seqc_in_modify(fvp_s) || !vn_seqc_consistent(fvp, fvp_s) ||
+ seqc_in_modify(tdvp_s) || !vn_seqc_consistent(tdvp, tdvp_s) ||
+ (tvp != NULL && (seqc_in_modify(tvp_s) ||
+ !vn_seqc_consistent(tvp, tvp_s))))) {
error = softdep_prerename(fdvp, fvp, tdvp, tvp);
if (error != 0) {
if (error == ERELOOKUP) {
+ fdvp_s = vn_seqc_read_any(fdvp);
+ fvp_s = vn_seqc_read_any(fvp);
+ tdvp_s = vn_seqc_read_any(tdvp);
+ if (tvp != NULL)
+ tvp_s = vn_seqc_read_any(tvp);
atomic_add_int(&rename_restarts, 1);
goto relock;
}
@@ -1947,7 +1962,7 @@
}
if (DOINGSUJ(dvp)) {
- error = softdep_prelink(dvp, NULL);
+ error = softdep_prelink(dvp, NULL, cnp);
if (error != 0) {
MPASS(error == ERELOOKUP);
return (error);
@@ -2211,7 +2226,7 @@
goto out;
}
if (DOINGSUJ(dvp)) {
- error = softdep_prelink(dvp, vp);
+ error = softdep_prelink(dvp, vp, cnp);
if (error != 0) {
MPASS(error == ERELOOKUP);
return (error);
@@ -2736,7 +2751,7 @@
return (EINVAL);
}
if (DOINGSUJ(dvp)) {
- error = softdep_prelink(dvp, NULL);
+ error = softdep_prelink(dvp, NULL, cnp);
if (error != 0) {
MPASS(error == ERELOOKUP);
return (error);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Sep 3, 12:41 AM (14 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38038501
Default Alt Text
D30041.id90444.diff (19 KB)
Attached To
Mode
D30041: ufs: avoid unneeded calls to softdep_prerename() and softdep_prelink()
Attached
Detach File
Event Timeline
Log In to Comment