Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145321675
D34323.1777644201.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D34323.1777644201.diff
View Options
diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c
--- a/sys/kern/kern_lockf.c
+++ b/sys/kern/kern_lockf.c
@@ -1861,7 +1861,7 @@
struct lockdesc {
STAILQ_ENTRY(lockdesc) link;
struct vnode *vp;
- struct flock fl;
+ struct xlockf xl;
};
STAILQ_HEAD(lockdesclist, lockdesc);
@@ -1894,16 +1894,17 @@
M_WAITOK);
ldesc->vp = lf->lf_vnode;
vref(ldesc->vp);
- ldesc->fl.l_start = lf->lf_start;
+ ldesc->xl.xl_start = lf->lf_start;
if (lf->lf_end == OFF_MAX)
- ldesc->fl.l_len = 0;
+ ldesc->xl.xl_len = 0;
else
- ldesc->fl.l_len =
+ ldesc->xl.xl_len =
lf->lf_end - lf->lf_start + 1;
- ldesc->fl.l_whence = SEEK_SET;
- ldesc->fl.l_type = F_UNLCK;
- ldesc->fl.l_pid = lf->lf_owner->lo_pid;
- ldesc->fl.l_sysid = sysid;
+ ldesc->xl.xl_id = (kvaddr_t)lf->lf_owner->lo_id;
+ ldesc->xl.xl_whence = SEEK_SET;
+ ldesc->xl.xl_type = lf->lf_type;
+ ldesc->xl.xl_pid = lf->lf_owner->lo_pid;
+ ldesc->xl.xl_sysid = sysid;
STAILQ_INSERT_TAIL(&locks, ldesc, link);
}
sx_xunlock(&ls->ls_lock);
@@ -1919,7 +1920,7 @@
while ((ldesc = STAILQ_FIRST(&locks)) != NULL) {
STAILQ_REMOVE_HEAD(&locks, link);
if (!error)
- error = fn(ldesc->vp, &ldesc->fl, arg);
+ error = fn(ldesc->vp, &ldesc->xl, arg);
vrele(ldesc->vp);
free(ldesc, M_LOCKF);
}
@@ -1961,16 +1962,17 @@
M_WAITOK);
ldesc->vp = lf->lf_vnode;
vref(ldesc->vp);
- ldesc->fl.l_start = lf->lf_start;
+ ldesc->xl.xl_start = lf->lf_start;
if (lf->lf_end == OFF_MAX)
- ldesc->fl.l_len = 0;
+ ldesc->xl.xl_len = 0;
else
- ldesc->fl.l_len =
+ ldesc->xl.xl_len =
lf->lf_end - lf->lf_start + 1;
- ldesc->fl.l_whence = SEEK_SET;
- ldesc->fl.l_type = F_UNLCK;
- ldesc->fl.l_pid = lf->lf_owner->lo_pid;
- ldesc->fl.l_sysid = lf->lf_owner->lo_sysid;
+ ldesc->xl.xl_id = (kvaddr_t)lf->lf_owner->lo_id;
+ ldesc->xl.xl_whence = SEEK_SET;
+ ldesc->xl.xl_type = lf->lf_type;
+ ldesc->xl.xl_pid = lf->lf_owner->lo_pid;
+ ldesc->xl.xl_sysid = lf->lf_owner->lo_sysid;
STAILQ_INSERT_TAIL(&locks, ldesc, link);
}
sx_xunlock(&ls->ls_lock);
@@ -1989,7 +1991,7 @@
while ((ldesc = STAILQ_FIRST(&locks)) != NULL) {
STAILQ_REMOVE_HEAD(&locks, link);
if (!error)
- error = fn(ldesc->vp, &ldesc->fl, arg);
+ error = fn(ldesc->vp, &ldesc->xl, arg);
vrele(ldesc->vp);
free(ldesc, M_LOCKF);
}
@@ -1998,10 +2000,17 @@
}
static int
-lf_clearremotesys_iterator(struct vnode *vp, struct flock *fl, void *arg)
+lf_clearremotesys_iterator(struct vnode *vp, struct xlockf *xl, void *arg)
{
+ struct flock fl;
- VOP_ADVLOCK(vp, 0, F_UNLCK, fl, F_REMOTE);
+ fl.l_start = xl->xl_start;
+ fl.l_len = xl->xl_len;
+ fl.l_pid = xl->xl_pid;
+ fl.l_type = F_UNLCK;
+ fl.l_whence = xl->xl_whence;
+ fl.l_sysid = xl->xl_sysid;
+ VOP_ADVLOCK(vp, 0, F_UNLCK, &fl, F_REMOTE);
return (0);
}
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -307,6 +307,12 @@
static u_long vnlru_read_freevnodes(void);
+struct lockf_context {
+ struct sysctl_req *req;
+ pid_t pid;
+ int byte_size;
+};
+
/*
* Note that no attempt is made to sanitize these parameters.
*/
@@ -4682,6 +4688,85 @@
"");
#endif
+static int
+lockf_iterator(struct vnode *vn, struct xlockf *xl, void *arg)
+{
+ struct lockf_context *ctx = arg;
+ struct proc *p;
+ int error, visible;
+
+ /* local pids, excluding the (already locked!) original one, should be checked for visibility */
+ if (xl->xl_sysid == 0 && xl->xl_pid != -1 && xl->xl_pid != ctx->pid) {
+ error = pget(xl->xl_pid, 0, &p);
+ if (error == 0) {
+ visible = !p_cansee(ctx->req->td, p);
+ PROC_UNLOCK(p);
+ if (!visible)
+ return (0);
+ }
+ }
+ if (ctx->req->oldptr == NULL) {
+ ctx->byte_size += sizeof(*xl);
+ return (0);
+ }
+ return (SYSCTL_OUT(ctx->req, xl, sizeof(*xl)));
+}
+
+static int
+sysctl_lockf(SYSCTL_HANDLER_ARGS)
+{
+ int *name = (int *)arg1;
+ u_int namelen = arg2;
+ int error = 0;
+ pid_t pid;
+ int fd;
+ struct proc *p;
+ struct file *fp = NULL;
+ struct lockf_context ctx;
+
+ if (namelen != 2)
+ return (EINVAL);
+ if (req->newptr)
+ return (EPERM);
+
+ pid = name[0];
+ fd = name[1];
+
+ error = sysctl_wire_old_buffer(req, 0);
+ if (error)
+ return (error);
+
+ ctx.byte_size = 0;
+ ctx.req = req;
+ ctx.pid = pid;
+
+ error = pget(pid, 0, &p);
+ if (error == 0) {
+ error = p_cansee(req->td, p);
+ if (error == 0) {
+ error = fget_unlocked(p->p_fd, fd, &cap_no_rights, &fp);
+ }
+ PROC_UNLOCK(p);
+ if (error == 0) {
+ error = lf_iteratelocks_vnode(fp->f_vnode, lockf_iterator, &ctx);
+ }
+ if (fp != NULL)
+ fdrop(fp, curthread);
+ }
+ if (error)
+ return (error);
+
+ if (req->oldptr == NULL) {
+ return (SYSCTL_OUT(req, 0, ctx.byte_size));
+ }
+
+ return (0);
+}
+
+SYSCTL_NODE(_kern, OID_AUTO, lockf,
+ CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_lockf,
+ "Array of struct xlockf (byte-level advisory locks) for the given process and file descriptor");
+
static void
unmount_or_warn(struct mount *mp)
{
diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c
--- a/sys/nlm/nlm_advlock.c
+++ b/sys/nlm/nlm_advlock.c
@@ -451,15 +451,19 @@
}
static int
-nlm_reclaim_free_lock(struct vnode *vp, struct flock *fl, void *arg)
+nlm_reclaim_free_lock(struct vnode *vp, struct xlockf *xl, void *arg)
{
struct flock newfl;
struct thread *td = curthread;
struct ucred *oldcred;
int error;
- newfl = *fl;
+ newfl.l_start = xl->xl_start;
+ newfl.l_len = xl->xl_len;
+ newfl.l_pid = xl->xl_pid;
newfl.l_type = F_UNLCK;
+ newfl.l_whence = xl->xl_whence;
+ newfl.l_sysid = xl->xl_sysid;
oldcred = td->td_ucred;
nlm_set_creds_for_lock(td, &newfl);
@@ -488,12 +492,13 @@
};
static int
-nlm_client_recover_lock(struct vnode *vp, struct flock *fl, void *arg)
+nlm_client_recover_lock(struct vnode *vp, struct xlockf *xl, void *arg)
{
struct nlm_recovery_context *nr = (struct nlm_recovery_context *) arg;
struct thread *td = curthread;
struct ucred *oldcred;
int state, error;
+ struct flock fl;
/*
* If the remote NSM state changes during recovery, the host
@@ -508,10 +513,16 @@
if (error)
return (error);
+ fl.l_start = xl->xl_start;
+ fl.l_len = xl->xl_len;
+ fl.l_pid = xl->xl_pid;
+ fl.l_type = F_UNLCK;
+ fl.l_whence = xl->xl_whence;
+ fl.l_sysid = xl->xl_sysid;
oldcred = td->td_ucred;
- nlm_set_creds_for_lock(td, fl);
+ nlm_set_creds_for_lock(td, &fl);
- error = nlm_advlock_internal(vp, NULL, F_SETLK, fl, F_REMOTE,
+ error = nlm_advlock_internal(vp, NULL, F_SETLK, &fl, F_REMOTE,
TRUE, TRUE);
crfree(td->td_ucred);
diff --git a/sys/sys/lockf.h b/sys/sys/lockf.h
--- a/sys/sys/lockf.h
+++ b/sys/sys/lockf.h
@@ -122,7 +122,21 @@
};
LIST_HEAD(lockf_list, lockf);
-typedef int lf_iterator(struct vnode *, struct flock *, void *);
+/*
+ * Lock entry as exported to userland.
+ */
+struct xlockf {
+ off_t xl_start; /* starting offset */
+ off_t xl_len; /* xl_len = 0 means until end of file */
+ kvaddr_t xl_id; /* address of struct file, when xl_pid is -1 */
+ pid_t xl_pid; /* lock owner, or -1 to identify by xl_id instead */
+ short xl_type; /* lock type: read/write, etc. */
+ short xl_whence; /* type of xl_start */
+ int xl_sysid; /* the namespace for xl_pid: remote system id or zero for local */
+};
+
+
+typedef int lf_iterator(struct vnode *, struct xlockf *, void *);
int lf_advlock(struct vop_advlock_args *, struct lockf **, u_quad_t);
int lf_advlockasync(struct vop_advlockasync_args *, struct lockf **, u_quad_t);
diff --git a/sys/sys/param.h b/sys/sys/param.h
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -76,7 +76,7 @@
* cannot include sys/param.h and should only be updated here.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1400052
+#define __FreeBSD_version 1400053
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, May 1, 2:03 PM (26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28527353
Default Alt Text
D34323.1777644201.diff (7 KB)
Attached To
Mode
D34323: Add a kern.lockf sysctl to list the advisory byte-range locks on a specific vnode
Attached
Detach File
Event Timeline
Log In to Comment