Page MenuHomeFreeBSD

D34756.id104523.diff
No OneTemporary

D34756.id104523.diff

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
@@ -68,14 +68,18 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/hash.h>
+#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/sbuf.h>
+#include <sys/stat.h>
#include <sys/sx.h>
#include <sys/unistd.h>
+#include <sys/user.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/fcntl.h>
@@ -85,11 +89,6 @@
#ifdef LOCKF_DEBUG
#include <sys/sysctl.h>
-#include <ufs/ufs/extattr.h>
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/ufsmount.h>
-#include <ufs/ufs/inode.h>
-
static int lockf_debug = 0; /* control debug output */
SYSCTL_INT(_debug, OID_AUTO, lockf_debug, CTLFLAG_RW, &lockf_debug, 0, "");
#endif
@@ -571,13 +570,6 @@
vref(vp);
}
- /*
- * XXX The problem is that VTOI is ufs specific, so it will
- * break LOCKF_DEBUG for all other FS's other than UFS because
- * it casts the vnode->data ptr to struct inode *.
- */
-/* lock->lf_inode = VTOI(ap->a_vp); */
- lock->lf_inode = (struct inode *)0;
lock->lf_type = fl->l_type;
LIST_INIT(&lock->lf_outedges);
LIST_INIT(&lock->lf_inedges);
@@ -2471,6 +2463,125 @@
return (g);
}
+struct kinfo_lockf_linked {
+ struct kinfo_lockf kl;
+ struct vnode *vp;
+ STAILQ_ENTRY(kinfo_lockf_linked) link;
+};
+
+static int
+sysctl_kern_lockf_run(struct sbuf *sb)
+{
+ struct lockf *ls;
+ struct lockf_entry *lf;
+ struct kinfo_lockf_linked *klf;
+ struct vnode *vp;
+ struct ucred *ucred;
+ char *fullpath, *freepath;
+ struct stat stt;
+ fsid_t fsidx;
+ STAILQ_HEAD(, kinfo_lockf_linked) locks;
+ int error, gerror;
+
+ /*
+ * In order to keep the locking simple, we iterate over the
+ * active lock lists to build a list of locks that need
+ * releasing. We then call the iterator for each one in turn.
+ *
+ * We take an extra reference to the vnode for the duration to
+ * make sure it doesn't go away before we are finished.
+ */
+ STAILQ_INIT(&locks);
+ sx_slock(&lf_lock_states_lock);
+ LIST_FOREACH(ls, &lf_lock_states, ls_link) {
+ sx_slock(&ls->ls_lock);
+ LIST_FOREACH(lf, &ls->ls_active, lf_link) {
+ vp = lf->lf_vnode;
+ if (vp == NULL || VN_IS_DOOMED(vp))
+ continue;
+ vhold(vp);
+ klf = malloc(sizeof(struct kinfo_lockf_linked),
+ M_LOCKF, M_WAITOK | M_ZERO);
+ klf->vp = vp;
+ klf->kl.kl_structsize = sizeof(struct kinfo_lockf);
+ klf->kl.kl_start = lf->lf_start;
+ klf->kl.kl_len = lf->lf_end == OFF_MAX ? 0 :
+ lf->lf_end - lf->lf_start + 1;
+ klf->kl.kl_rw = lf->lf_type == F_RDLCK ? KLOCK_RW_READ :
+ KLOCK_RW_WRITE;
+ if (lf->lf_owner->lo_sysid != 0) {
+ klf->kl.kl_pid = lf->lf_owner->lo_pid;
+ klf->kl.kl_sysid = lf->lf_owner->lo_sysid;
+ klf->kl.kl_type = KLOCK_TYPE_REMOTE;
+ } else if (lf->lf_owner->lo_pid == -1) {
+ klf->kl.kl_pid = -1;
+ klf->kl.kl_sysid = 0;
+ klf->kl.kl_type = KLOCK_TYPE_FLOCK;
+ } else {
+ klf->kl.kl_pid = lf->lf_owner->lo_pid;
+ klf->kl.kl_sysid = 0;
+ klf->kl.kl_type = KLOCK_TYPE_PID;
+ }
+ memcpy(&klf->kl.kl_file_fsid, &fsidx, sizeof(fsidx));
+ STAILQ_INSERT_TAIL(&locks, klf, link);
+ }
+ sx_sunlock(&ls->ls_lock);
+ }
+ sx_sunlock(&lf_lock_states_lock);
+
+ gerror = 0;
+ ucred = curthread->td_ucred;
+ while ((klf = STAILQ_FIRST(&locks)) != NULL) {
+ STAILQ_REMOVE_HEAD(&locks, link);
+ vp = klf->vp;
+ if (gerror == 0 && vn_lock(vp, LK_SHARED | LK_RETRY) == 0) {
+ error = prison_canseemount(ucred, vp->v_mount);
+ if (error == 0)
+ error = VOP_STAT(vp, &stt, ucred, NOCRED);
+ if (error == 0)
+ fsidx = vp->v_mount->mnt_stat.f_fsid;
+ VOP_UNLOCK(vp);
+ if (error == 0) {
+ klf->kl.kl_file_rdev = stt.st_rdev;
+ klf->kl.kl_file_fileid = stt.st_ino;
+ freepath = NULL;
+ fullpath = "-";
+ error = vn_fullpath(vp, &fullpath, &freepath);
+ if (error == 0)
+ strlcpy(klf->kl.kl_path, fullpath,
+ sizeof(klf->kl.kl_path));
+ free(freepath, M_TEMP);
+ if (sbuf_bcat(sb, &klf->kl,
+ klf->kl.kl_structsize) != 0) {
+ gerror = sbuf_error(sb);
+ }
+ }
+ }
+ vdrop(vp);
+ free(klf, M_LOCKF);
+ }
+
+ return (gerror);
+}
+
+static int
+sysctl_kern_lockf(SYSCTL_HANDLER_ARGS)
+{
+ struct sbuf sb;
+ int error, error2;
+
+ sbuf_new_for_sysctl(&sb, NULL, sizeof(struct kinfo_lockf) * 5, req);
+ sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
+ error = sysctl_kern_lockf_run(&sb);
+ error2 = sbuf_finish(&sb);
+ sbuf_delete(&sb);
+ return (error != 0 ? error : error2);
+}
+SYSCTL_PROC(_kern, KERN_LOCKF, lockf,
+ CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ 0, 0, sysctl_kern_lockf, "S,lockf",
+ "Advisory locks table");
+
#ifdef LOCKF_DEBUG
/*
* Print description of a lock owner
@@ -2498,10 +2609,8 @@
printf("%s: lock %p for ", tag, (void *)lock);
lf_print_owner(lock->lf_owner);
- if (lock->lf_inode != (struct inode *)0)
- printf(" in ino %ju on dev <%s>,",
- (uintmax_t)lock->lf_inode->i_number,
- devtoname(ITODEV(lock->lf_inode)));
+ printf("\nvnode %p", lock->lf_vnode);
+ VOP_PRINT(lock->lf_vnode);
printf(" %s, start %jd, end ",
lock->lf_type == F_RDLCK ? "shared" :
lock->lf_type == F_WRLCK ? "exclusive" :
@@ -2524,12 +2633,8 @@
struct lockf_entry *lf, *blk;
struct lockf_edge *e;
- if (lock->lf_inode == (struct inode *)0)
- return;
-
- printf("%s: Lock list for ino %ju on dev <%s>:\n",
- tag, (uintmax_t)lock->lf_inode->i_number,
- devtoname(ITODEV(lock->lf_inode)));
+ printf("%s: Lock list for vnode %p:\n",
+ tag, lock->lf_vnode);
LIST_FOREACH(lf, &lock->lf_vnode->v_lockf->ls_active, lf_link) {
printf("\tlock %p for ",(void *)lf);
lf_print_owner(lock->lf_owner);
diff --git a/sys/sys/lockf.h b/sys/sys/lockf.h
--- a/sys/sys/lockf.h
+++ b/sys/sys/lockf.h
@@ -77,7 +77,6 @@
off_t lf_end; /* (s) Byte # of the end of the lock (OFF_MAX=EOF) */
struct lock_owner *lf_owner; /* (c) Owner of the lock */
struct vnode *lf_vnode; /* (c) File being locked (only valid for active lock) */
- struct inode *lf_inode; /* (c) Back pointer to the inode */
struct task *lf_async_task;/* (c) Async lock callback */
LIST_ENTRY(lockf_entry) lf_link; /* (s) Linkage for lock lists */
struct lockf_edge_list lf_outedges; /* (s) list of out-edges */
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -976,6 +976,7 @@
#define KERN_HOSTUUID 36 /* string: host UUID identifier */
#define KERN_ARND 37 /* int: from arc4rand() */
#define KERN_MAXPHYS 38 /* int: MAXPHYS value */
+#define KERN_LOCKF 39 /* struct: lockf reports */
/*
* KERN_PROC subtypes
*/
diff --git a/sys/sys/user.h b/sys/sys/user.h
--- a/sys/sys/user.h
+++ b/sys/sys/user.h
@@ -452,6 +452,28 @@
char kf_path[PATH_MAX]; /* Path to file, if any. */
};
+struct kinfo_lockf {
+ int kl_structsize; /* Variable size of record. */
+ int kl_rw;
+ int kl_type;
+ int kl_pid;
+ int kl_sysid;
+ int kl_pad0;
+ uint64_t kl_file_fsid;
+ uint64_t kl_file_rdev;
+ uint64_t kl_file_fileid;
+ off_t kl_start;
+ off_t kl_len; /* len == 0 till the EOF */
+ char kl_path[PATH_MAX];
+};
+
+#define KLOCK_RW_READ 0x01
+#define KLOCK_RW_WRITE 0x02
+
+#define KLOCK_TYPE_FLOCK 0x01
+#define KLOCK_TYPE_PID 0x02
+#define KLOCK_TYPE_REMOTE 0x03
+
/*
* The KERN_PROC_VMMAP sysctl allows a process to dump the VM layout of
* another process as a series of entries.
diff --git a/sys/ufs/ufs/acl.h b/sys/ufs/ufs/acl.h
--- a/sys/ufs/ufs/acl.h
+++ b/sys/ufs/ufs/acl.h
@@ -39,8 +39,12 @@
#ifdef _KERNEL
-int ufs_getacl_nfs4_internal(struct vnode *vp, struct acl *aclp, struct thread *td);
-int ufs_setacl_nfs4_internal(struct vnode *vp, struct acl *aclp, struct thread *td);
+struct inode;
+
+int ufs_getacl_nfs4_internal(struct vnode *vp, struct acl *aclp,
+ struct thread *td);
+int ufs_setacl_nfs4_internal(struct vnode *vp, struct acl *aclp,
+ struct thread *td);
void ufs_sync_acl_from_inode(struct inode *ip, struct acl *acl);
void ufs_sync_inode_from_acl(struct acl *acl, struct inode *ip);

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 21, 10:44 PM (14 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25819604
Default Alt Text
D34756.id104523.diff (7 KB)

Event Timeline