Page MenuHomeFreeBSD

D49455.1786433138.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D49455.1786433138.diff

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
@@ -751,8 +751,8 @@
}
#if OFF_MAX <= LONG_MAX
-off_t
-foffset_lock(struct file *fp, int flags)
+static int
+foffset_lock1(struct file *fp, int flags, off_t *offp)
{
volatile short *flagsp;
off_t res;
@@ -760,16 +760,22 @@
KASSERT((flags & FOF_OFFSET) == 0, ("FOF_OFFSET passed"));
- if ((flags & FOF_NOLOCK) != 0)
- return (atomic_load_long(&fp->f_offset));
+ if ((flags & FOF_NOLOCK) != 0) {
+ *offp = atomic_load_long(&fp->f_offset);
+ return (0);
+ }
/*
* According to McKusick the vn lock was protecting f_offset here.
* It is now protected by the FOFFSET_LOCKED flag.
*/
flagsp = &fp->f_vnread_flags;
- if (atomic_cmpset_acq_16(flagsp, 0, FOFFSET_LOCKED))
- return (atomic_load_long(&fp->f_offset));
+ if (atomic_cmpset_acq_16(flagsp, 0, FOFFSET_LOCKED)) {
+ *offp = atomic_load_long(&fp->f_offset);
+ return (0);
+ }
+ if ((flags & FOF_NONBLOCK) != 0)
+ return (EAGAIN);
sleepq_lock(&fp->f_vnread_flags);
state = atomic_load_16(flagsp);
@@ -794,7 +800,8 @@
}
res = atomic_load_long(&fp->f_offset);
sleepq_release(&fp->f_vnread_flags);
- return (res);
+ *offp = res;
+ return (0);
}
void
@@ -836,8 +843,8 @@
return (atomic_load_long(&fp->f_offset));
}
#else
-off_t
-foffset_lock(struct file *fp, int flags)
+static int
+foffset_lock1(struct file *fp, int flags, off_t *offp)
{
struct mtx *mtxp;
off_t res;
@@ -848,6 +855,10 @@
mtx_lock(mtxp);
if ((flags & FOF_NOLOCK) == 0) {
while (fp->f_vnread_flags & FOFFSET_LOCKED) {
+ if ((flags & FOF_NONBLOCK) != 0) {
+ mtx_unlock(mtxp);
+ return (EAGAIN);
+ }
fp->f_vnread_flags |= FOFFSET_LOCK_WAITING;
msleep(&fp->f_vnread_flags, mtxp, PUSER -1,
"vofflock", 0);
@@ -856,7 +867,8 @@
}
res = fp->f_offset;
mtx_unlock(mtxp);
- return (res);
+ *offp = res;
+ return (0);
}
void
@@ -892,6 +904,20 @@
}
#endif
+off_t
+foffset_lock(struct file *fp, int flags)
+{
+ off_t ret;
+ int error __diagused;
+
+ KASSERT((flags & FOF_NONBLOCK) == 0,
+ ("FOF_NONBLOCK passed to foffset_lock()"));
+
+ error = foffset_lock1(fp, flags, &ret);
+ KASSERT(error == 0, ("foffset_lock1() failed: %d", error));
+ return (ret);
+}
+
void
foffset_lock_uio(struct file *fp, struct uio *uio, int flags)
{
@@ -900,6 +926,13 @@
uio->uio_offset = foffset_lock(fp, flags);
}
+int
+foffset_trylock(struct file *fp, int flags, off_t *offp)
+{
+
+ return (foffset_lock1(fp, flags | FOF_NONBLOCK, offp));
+}
+
void
foffset_unlock_uio(struct file *fp, struct uio *uio, int flags)
{
diff --git a/sys/sys/file.h b/sys/sys/file.h
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -85,7 +85,9 @@
#define FOF_NEXTOFF_R 0x04 /* Also update f_nextoff[UIO_READ] */
#define FOF_NEXTOFF_W 0x08 /* Also update f_nextoff[UIO_WRITE] */
#define FOF_NOUPDATE 0x10 /* Do not update f_offset */
+#define FOF_NONBLOCK 0x20 /* Do not block if the offset is locked */
off_t foffset_lock(struct file *fp, int flags);
+int foffset_trylock(struct file *fp, int flags, off_t *offp);
void foffset_lock_uio(struct file *fp, struct uio *uio, int flags);
void foffset_unlock(struct file *fp, off_t val, int flags);
void foffset_unlock_uio(struct file *fp, struct uio *uio, int flags);

File Metadata

Mime Type
text/plain
Expires
Tue, Aug 11, 7:25 AM (22 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29394583
Default Alt Text
D49455.1786433138.diff (3 KB)

Event Timeline