Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F158884432
D28697.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D28697.diff
View Options
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -423,10 +423,25 @@
vop_stdadvlock(struct vop_advlock_args *ap)
{
struct vnode *vp;
+ struct mount *mp;
struct vattr vattr;
int error;
vp = ap->a_vp;
+
+ /*
+ * Provide atomicity of open(O_CREAT | O_EXCL | O_EXLOCK) for
+ * local filesystems. See vn_open_cred() for reciprocal part.
+ */
+ mp = vp->v_mount;
+ if (mp != NULL && (mp->mnt_flag & MNT_LOCAL) != 0 &&
+ ap->a_op == F_SETLK && (ap->a_flags & F_FIRSTOPEN) == 0) {
+ VI_LOCK(vp);
+ while ((vp->v_iflag & VI_FOPENING) != 0)
+ msleep(vp, VI_MTX(vp), PLOCK, "lockfo", 0);
+ VI_UNLOCK(vp);
+ }
+
if (ap->a_fl->l_whence == SEEK_END) {
/*
* The NFSv4 server must avoid doing a vn_lock() here, since it
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -228,8 +228,10 @@
struct vattr vat;
struct vattr *vap = &vat;
int fmode, error;
+ bool first_open;
restart:
+ first_open = false;
fmode = *flagp;
if ((fmode & (O_CREAT | O_EXCL | O_DIRECTORY)) == (O_CREAT |
O_EXCL | O_DIRECTORY))
@@ -275,8 +277,16 @@
#endif
error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp,
&ndp->ni_cnd, vap);
- VOP_VPUT_PAIR(ndp->ni_dvp, error == 0 ? &ndp->ni_vp :
- NULL, false);
+ vp = ndp->ni_vp;
+ if (error == 0 && (fmode & O_EXCL) != 0 &&
+ (fmode & (O_EXLOCK | O_SHLOCK)) != 0) {
+ VI_LOCK(vp);
+ vp->v_iflag |= VI_FOPENING;
+ VI_UNLOCK(vp);
+ first_open = true;
+ }
+ VOP_VPUT_PAIR(ndp->ni_dvp, error == 0 ? &vp : NULL,
+ false);
vn_finished_write(mp);
if (error) {
NDFREE(ndp, NDF_ONLY_PNBUF);
@@ -287,7 +297,6 @@
return (error);
}
fmode &= ~O_TRUNC;
- vp = ndp->ni_vp;
} else {
if (ndp->ni_dvp == ndp->ni_vp)
vrele(ndp->ni_dvp);
@@ -317,6 +326,12 @@
vp = ndp->ni_vp;
}
error = vn_open_vnode(vp, fmode, cred, td, fp);
+ if (first_open) {
+ VI_LOCK(vp);
+ vp->v_iflag &= ~VI_FOPENING;
+ wakeup(vp);
+ VI_UNLOCK(vp);
+ }
if (error)
goto bad;
*flagp = fmode;
@@ -352,6 +367,8 @@
type = F_FLOCK;
if ((fmode & FNONBLOCK) == 0)
type |= F_WAIT;
+ if ((fmode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+ type |= F_FIRSTOPEN;
error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type);
if (error == 0)
fp->f_flag |= FHASLOCK;
diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h
--- a/sys/sys/fcntl.h
+++ b/sys/sys/fcntl.h
@@ -287,6 +287,7 @@
#define F_POSIX 0x040 /* Use POSIX semantics for lock */
#define F_REMOTE 0x080 /* Lock owner is remote NFS client */
#define F_NOINTR 0x100 /* Ignore signals when waiting */
+#define F_FIRSTOPEN 0x200 /* First right to advlock file */
#endif
/*
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -254,6 +254,8 @@
#define VI_DOINGINACT 0x0004 /* VOP_INACTIVE is in progress */
#define VI_OWEINACT 0x0008 /* Need to call inactive */
#define VI_DEFINACT 0x0010 /* deferred inactive */
+#define VI_FOPENING 0x0020 /* In open, with opening process having the
+ first right to advlock file */
#define VV_ROOT 0x0001 /* root of its filesystem */
#define VV_ISTTY 0x0002 /* vnode represents a tty */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jun 8, 7:24 AM (14 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33795897
Default Alt Text
D28697.diff (3 KB)
Attached To
Mode
D28697: lockf: ensure atomicity of lockf for open(O_CREAT|O_EXCL|O_EXLOCK)
Attached
Detach File
Event Timeline
Log In to Comment