Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_subr.c
Show First 20 Lines • Show All 301 Lines • ▼ Show 20 Lines | |||||
static u_long gapvnodes; /* gap between wanted and desired */ | static u_long gapvnodes; /* gap between wanted and desired */ | ||||
static u_long vhiwat; /* enough extras after expansion */ | static u_long vhiwat; /* enough extras after expansion */ | ||||
static u_long vlowat; /* minimal extras before expansion */ | static u_long vlowat; /* minimal extras before expansion */ | ||||
static u_long vstir; /* nonzero to stir non-free vnodes */ | static u_long vstir; /* nonzero to stir non-free vnodes */ | ||||
static volatile int vsmalltrigger = 8; /* pref to keep if > this many pages */ | static volatile int vsmalltrigger = 8; /* pref to keep if > this many pages */ | ||||
static u_long vnlru_read_freevnodes(void); | 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. | * Note that no attempt is made to sanitize these parameters. | ||||
*/ | */ | ||||
static int | static int | ||||
sysctl_maxvnodes(SYSCTL_HANDLER_ARGS) | sysctl_maxvnodes(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
u_long val; | u_long val; | ||||
int error; | int error; | ||||
▲ Show 20 Lines • Show All 4,358 Lines • ▼ Show 20 Lines | #undef XV_COPY | ||||
free(xvn, M_TEMP); | free(xvn, M_TEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_kern, KERN_VNODE, vnode, CTLTYPE_OPAQUE | CTLFLAG_RD | | SYSCTL_PROC(_kern, KERN_VNODE, vnode, CTLTYPE_OPAQUE | CTLFLAG_RD | | ||||
CTLFLAG_MPSAFE, 0, 0, sysctl_vnode, "S,xvnode", | CTLFLAG_MPSAFE, 0, 0, sysctl_vnode, "S,xvnode", | ||||
""); | ""); | ||||
#endif | #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); | |||||
se: The first argument of fget_unlocked() must be a thread pointer ... | |||||
} | |||||
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 | static void | ||||
unmount_or_warn(struct mount *mp) | unmount_or_warn(struct mount *mp) | ||||
{ | { | ||||
int error; | int error; | ||||
error = dounmount(mp, MNT_FORCE, curthread); | error = dounmount(mp, MNT_FORCE, curthread); | ||||
if (error != 0) { | if (error != 0) { | ||||
▲ Show 20 Lines • Show All 2,307 Lines • Show Last 20 Lines |
The first argument of fget_unlocked() must be a thread pointer ...