Autofs softc needs to be global anyway, so don't pass it as a local
variable, and don't store in autofs_mount. Also rename it from 'sc' to 'autofs_softc', since it's global and extern. MFC after: 2 weeks Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
a32ba4e63e
commit
f81018caf2
@ -115,7 +115,7 @@ int autofs_sig_set[] = {
|
||||
SIGQUIT
|
||||
};
|
||||
|
||||
struct autofs_softc *sc;
|
||||
struct autofs_softc *autofs_softc;
|
||||
|
||||
SYSCTL_NODE(_vfs, OID_AUTO, autofs, CTLFLAG_RD, 0, "Automounter filesystem");
|
||||
int autofs_debug = 1;
|
||||
@ -153,7 +153,11 @@ autofs_init(struct vfsconf *vfsp)
|
||||
{
|
||||
int error;
|
||||
|
||||
sc = malloc(sizeof(*sc), M_AUTOFS, M_WAITOK | M_ZERO);
|
||||
KASSERT(autofs_softc == NULL,
|
||||
("softc %p, should be NULL", autofs_softc));
|
||||
|
||||
autofs_softc = malloc(sizeof(*autofs_softc), M_AUTOFS,
|
||||
M_WAITOK | M_ZERO);
|
||||
|
||||
autofs_request_zone = uma_zcreate("autofs_request",
|
||||
sizeof(struct autofs_request), NULL, NULL, NULL, NULL,
|
||||
@ -162,18 +166,21 @@ autofs_init(struct vfsconf *vfsp)
|
||||
sizeof(struct autofs_node), NULL, NULL, NULL, NULL,
|
||||
UMA_ALIGN_PTR, 0);
|
||||
|
||||
TAILQ_INIT(&sc->sc_requests);
|
||||
cv_init(&sc->sc_cv, "autofscv");
|
||||
sx_init(&sc->sc_lock, "autofslk");
|
||||
TAILQ_INIT(&autofs_softc->sc_requests);
|
||||
cv_init(&autofs_softc->sc_cv, "autofscv");
|
||||
sx_init(&autofs_softc->sc_lock, "autofslk");
|
||||
|
||||
error = make_dev_p(MAKEDEV_CHECKNAME, &sc->sc_cdev, &autofs_cdevsw,
|
||||
NULL, UID_ROOT, GID_WHEEL, 0600, "autofs");
|
||||
error = make_dev_p(MAKEDEV_CHECKNAME, &autofs_softc->sc_cdev,
|
||||
&autofs_cdevsw, NULL, UID_ROOT, GID_WHEEL, 0600, "autofs");
|
||||
if (error != 0) {
|
||||
AUTOFS_WARN("failed to create device node, error %d", error);
|
||||
free(sc, M_AUTOFS);
|
||||
uma_zdestroy(autofs_request_zone);
|
||||
uma_zdestroy(autofs_node_zone);
|
||||
free(autofs_softc, M_AUTOFS);
|
||||
|
||||
return (error);
|
||||
}
|
||||
sc->sc_cdev->si_drv1 = sc;
|
||||
autofs_softc->sc_cdev->si_drv1 = autofs_softc;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -182,22 +189,22 @@ int
|
||||
autofs_uninit(struct vfsconf *vfsp)
|
||||
{
|
||||
|
||||
sx_xlock(&sc->sc_lock);
|
||||
if (sc->sc_dev_opened) {
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xlock(&autofs_softc->sc_lock);
|
||||
if (autofs_softc->sc_dev_opened) {
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
return (EBUSY);
|
||||
}
|
||||
if (sc->sc_cdev != NULL)
|
||||
destroy_dev(sc->sc_cdev);
|
||||
if (autofs_softc->sc_cdev != NULL)
|
||||
destroy_dev(autofs_softc->sc_cdev);
|
||||
|
||||
uma_zdestroy(autofs_request_zone);
|
||||
uma_zdestroy(autofs_node_zone);
|
||||
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
/*
|
||||
* XXX: Race with open?
|
||||
*/
|
||||
free(sc, M_AUTOFS);
|
||||
free(autofs_softc, M_AUTOFS);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -209,11 +216,11 @@ autofs_ignore_thread(const struct thread *td)
|
||||
|
||||
p = td->td_proc;
|
||||
|
||||
if (sc->sc_dev_opened == false)
|
||||
if (autofs_softc->sc_dev_opened == false)
|
||||
return (false);
|
||||
|
||||
PROC_LOCK(p);
|
||||
if (p->p_session->s_sid == sc->sc_dev_sid) {
|
||||
if (p->p_session->s_sid == autofs_softc->sc_dev_sid) {
|
||||
PROC_UNLOCK(p);
|
||||
return (true);
|
||||
}
|
||||
@ -256,12 +263,10 @@ static void
|
||||
autofs_callout(void *context)
|
||||
{
|
||||
struct autofs_request *ar;
|
||||
struct autofs_softc *sc;
|
||||
|
||||
ar = context;
|
||||
sc = ar->ar_mount->am_softc;
|
||||
|
||||
sx_xlock(&sc->sc_lock);
|
||||
sx_xlock(&autofs_softc->sc_lock);
|
||||
AUTOFS_WARN("request %d for %s timed out after %d seconds",
|
||||
ar->ar_id, ar->ar_path, autofs_timeout);
|
||||
/*
|
||||
@ -270,8 +275,8 @@ autofs_callout(void *context)
|
||||
ar->ar_error = ETIMEDOUT;
|
||||
ar->ar_done = true;
|
||||
ar->ar_in_progress = false;
|
||||
cv_broadcast(&sc->sc_cv);
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
cv_broadcast(&autofs_softc->sc_cv);
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -356,16 +361,14 @@ autofs_trigger_one(struct autofs_node *anp,
|
||||
{
|
||||
sigset_t oldset;
|
||||
struct autofs_mount *amp;
|
||||
struct autofs_softc *sc;
|
||||
struct autofs_node *firstanp;
|
||||
struct autofs_request *ar;
|
||||
char *key, *path;
|
||||
int error = 0, request_error, last;
|
||||
|
||||
amp = VFSTOAUTOFS(anp->an_vnode->v_mount);
|
||||
sc = amp->am_softc;
|
||||
|
||||
sx_assert(&sc->sc_lock, SA_XLOCKED);
|
||||
sx_assert(&autofs_softc->sc_lock, SA_XLOCKED);
|
||||
|
||||
if (anp->an_parent == NULL) {
|
||||
key = strndup(component, componentlen, M_AUTOFS);
|
||||
@ -378,7 +381,7 @@ autofs_trigger_one(struct autofs_node *anp,
|
||||
|
||||
path = autofs_path(anp);
|
||||
|
||||
TAILQ_FOREACH(ar, &sc->sc_requests, ar_next) {
|
||||
TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) {
|
||||
if (strcmp(ar->ar_path, path) != 0)
|
||||
continue;
|
||||
if (strcmp(ar->ar_key, key) != 0)
|
||||
@ -402,7 +405,8 @@ autofs_trigger_one(struct autofs_node *anp,
|
||||
ar = uma_zalloc(autofs_request_zone, M_WAITOK | M_ZERO);
|
||||
ar->ar_mount = amp;
|
||||
|
||||
ar->ar_id = atomic_fetchadd_int(&sc->sc_last_request_id, 1);
|
||||
ar->ar_id =
|
||||
atomic_fetchadd_int(&autofs_softc->sc_last_request_id, 1);
|
||||
strlcpy(ar->ar_from, amp->am_from, sizeof(ar->ar_from));
|
||||
strlcpy(ar->ar_path, path, sizeof(ar->ar_path));
|
||||
strlcpy(ar->ar_prefix, amp->am_prefix, sizeof(ar->ar_prefix));
|
||||
@ -414,14 +418,15 @@ autofs_trigger_one(struct autofs_node *anp,
|
||||
callout_reset(&ar->ar_callout,
|
||||
autofs_timeout * hz, autofs_callout, ar);
|
||||
refcount_init(&ar->ar_refcount, 1);
|
||||
TAILQ_INSERT_TAIL(&sc->sc_requests, ar, ar_next);
|
||||
TAILQ_INSERT_TAIL(&autofs_softc->sc_requests, ar, ar_next);
|
||||
}
|
||||
|
||||
cv_broadcast(&sc->sc_cv);
|
||||
cv_broadcast(&autofs_softc->sc_cv);
|
||||
while (ar->ar_done == false) {
|
||||
if (autofs_interruptible != 0) {
|
||||
autofs_set_sigmask(&oldset);
|
||||
error = cv_wait_sig(&sc->sc_cv, &sc->sc_lock);
|
||||
error = cv_wait_sig(&autofs_softc->sc_cv,
|
||||
&autofs_softc->sc_lock);
|
||||
autofs_restore_sigmask(&oldset);
|
||||
if (error != 0) {
|
||||
/*
|
||||
@ -434,7 +439,7 @@ autofs_trigger_one(struct autofs_node *anp,
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
cv_wait(&sc->sc_cv, &sc->sc_lock);
|
||||
cv_wait(&autofs_softc->sc_cv, &autofs_softc->sc_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,13 +451,13 @@ autofs_trigger_one(struct autofs_node *anp,
|
||||
|
||||
last = refcount_release(&ar->ar_refcount);
|
||||
if (last) {
|
||||
TAILQ_REMOVE(&sc->sc_requests, ar, ar_next);
|
||||
TAILQ_REMOVE(&autofs_softc->sc_requests, ar, ar_next);
|
||||
/*
|
||||
* XXX: Is it safe?
|
||||
*/
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
callout_drain(&ar->ar_callout);
|
||||
sx_xlock(&sc->sc_lock);
|
||||
sx_xlock(&autofs_softc->sc_lock);
|
||||
uma_zfree(autofs_request_zone, ar);
|
||||
}
|
||||
|
||||
@ -507,21 +512,21 @@ autofs_trigger(struct autofs_node *anp,
|
||||
AUTOFS_DEBUG("trigger failed with error %d; will retry in "
|
||||
"%d seconds, %d attempts left", error, autofs_retry_delay,
|
||||
autofs_retry_attempts - anp->an_retries);
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
pause("autofs_retry", autofs_retry_delay * hz);
|
||||
sx_xlock(&sc->sc_lock);
|
||||
sx_xlock(&autofs_softc->sc_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
autofs_ioctl_request(struct autofs_softc *sc, struct autofs_daemon_request *adr)
|
||||
autofs_ioctl_request(struct autofs_daemon_request *adr)
|
||||
{
|
||||
struct autofs_request *ar;
|
||||
int error;
|
||||
|
||||
sx_xlock(&sc->sc_lock);
|
||||
sx_xlock(&autofs_softc->sc_lock);
|
||||
for (;;) {
|
||||
TAILQ_FOREACH(ar, &sc->sc_requests, ar_next) {
|
||||
TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) {
|
||||
if (ar->ar_done)
|
||||
continue;
|
||||
if (ar->ar_in_progress)
|
||||
@ -533,21 +538,22 @@ autofs_ioctl_request(struct autofs_softc *sc, struct autofs_daemon_request *adr)
|
||||
if (ar != NULL)
|
||||
break;
|
||||
|
||||
error = cv_wait_sig(&sc->sc_cv, &sc->sc_lock);
|
||||
error = cv_wait_sig(&autofs_softc->sc_cv,
|
||||
&autofs_softc->sc_lock);
|
||||
if (error != 0) {
|
||||
/*
|
||||
* XXX: For some reson this returns -1 instead
|
||||
* of EINTR, wtf?!
|
||||
*/
|
||||
error = EINTR;
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
AUTOFS_DEBUG("failed with error %d", error);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
ar->ar_in_progress = true;
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
|
||||
adr->adr_id = ar->ar_id;
|
||||
strlcpy(adr->adr_from, ar->ar_from, sizeof(adr->adr_from));
|
||||
@ -557,25 +563,25 @@ autofs_ioctl_request(struct autofs_softc *sc, struct autofs_daemon_request *adr)
|
||||
strlcpy(adr->adr_options, ar->ar_options, sizeof(adr->adr_options));
|
||||
|
||||
PROC_LOCK(curproc);
|
||||
sc->sc_dev_sid = curproc->p_session->s_sid;
|
||||
autofs_softc->sc_dev_sid = curproc->p_session->s_sid;
|
||||
PROC_UNLOCK(curproc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
autofs_ioctl_done(struct autofs_softc *sc, struct autofs_daemon_done *add)
|
||||
autofs_ioctl_done(struct autofs_daemon_done *add)
|
||||
{
|
||||
struct autofs_request *ar;
|
||||
|
||||
sx_xlock(&sc->sc_lock);
|
||||
TAILQ_FOREACH(ar, &sc->sc_requests, ar_next) {
|
||||
sx_xlock(&autofs_softc->sc_lock);
|
||||
TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) {
|
||||
if (ar->ar_id == add->add_id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ar == NULL) {
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
AUTOFS_DEBUG("id %d not found", add->add_id);
|
||||
return (ESRCH);
|
||||
}
|
||||
@ -583,9 +589,9 @@ autofs_ioctl_done(struct autofs_softc *sc, struct autofs_daemon_done *add)
|
||||
ar->ar_error = add->add_error;
|
||||
ar->ar_done = true;
|
||||
ar->ar_in_progress = false;
|
||||
cv_broadcast(&sc->sc_cv);
|
||||
cv_broadcast(&autofs_softc->sc_cv);
|
||||
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -594,7 +600,7 @@ static int
|
||||
autofs_open(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||
{
|
||||
|
||||
sx_xlock(&sc->sc_lock);
|
||||
sx_xlock(&autofs_softc->sc_lock);
|
||||
/*
|
||||
* We must never block automountd(8) and its descendants, and we use
|
||||
* session ID to determine that: we store session id of the process
|
||||
@ -603,13 +609,13 @@ autofs_open(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||
* instance would break the previous one. The check below prevents
|
||||
* it from happening.
|
||||
*/
|
||||
if (sc->sc_dev_opened) {
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
if (autofs_softc->sc_dev_opened) {
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
sc->sc_dev_opened = true;
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
autofs_softc->sc_dev_opened = true;
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -618,10 +624,10 @@ static int
|
||||
autofs_close(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
{
|
||||
|
||||
sx_xlock(&sc->sc_lock);
|
||||
KASSERT(sc->sc_dev_opened, ("not opened?"));
|
||||
sc->sc_dev_opened = false;
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xlock(&autofs_softc->sc_lock);
|
||||
KASSERT(autofs_softc->sc_dev_opened, ("not opened?"));
|
||||
autofs_softc->sc_dev_opened = false;
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -631,14 +637,14 @@ autofs_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode,
|
||||
struct thread *td)
|
||||
{
|
||||
|
||||
KASSERT(sc->sc_dev_opened, ("not opened?"));
|
||||
KASSERT(autofs_softc->sc_dev_opened, ("not opened?"));
|
||||
|
||||
switch (cmd) {
|
||||
case AUTOFSREQUEST:
|
||||
return (autofs_ioctl_request(sc,
|
||||
return (autofs_ioctl_request(
|
||||
(struct autofs_daemon_request *)arg));
|
||||
case AUTOFSDONE:
|
||||
return (autofs_ioctl_done(sc,
|
||||
return (autofs_ioctl_done(
|
||||
(struct autofs_daemon_done *)arg));
|
||||
default:
|
||||
AUTOFS_DEBUG("invalid cmd %lx", cmd);
|
||||
|
@ -75,7 +75,6 @@ struct autofs_node {
|
||||
|
||||
struct autofs_mount {
|
||||
TAILQ_ENTRY(autofs_mount) am_next;
|
||||
struct autofs_softc *am_softc;
|
||||
struct autofs_node *am_root;
|
||||
struct mount *am_mp;
|
||||
struct sx am_lock;
|
||||
|
@ -48,7 +48,7 @@ static const char *autofs_opts[] = {
|
||||
"from", "master_options", "master_prefix", NULL
|
||||
};
|
||||
|
||||
extern struct autofs_softc *sc;
|
||||
extern struct autofs_softc *autofs_softc;
|
||||
|
||||
static int
|
||||
autofs_mount(struct mount *mp)
|
||||
@ -78,7 +78,6 @@ autofs_mount(struct mount *mp)
|
||||
amp = malloc(sizeof(*amp), M_AUTOFS, M_WAITOK | M_ZERO);
|
||||
mp->mnt_data = amp;
|
||||
amp->am_mp = mp;
|
||||
amp->am_softc = sc;
|
||||
strlcpy(amp->am_from, from, sizeof(amp->am_from));
|
||||
strlcpy(amp->am_mountpoint, fspath, sizeof(amp->am_mountpoint));
|
||||
strlcpy(amp->am_options, options, sizeof(amp->am_options));
|
||||
@ -129,8 +128,8 @@ autofs_unmount(struct mount *mp, int mntflags)
|
||||
*/
|
||||
for (;;) {
|
||||
found = false;
|
||||
sx_xlock(&sc->sc_lock);
|
||||
TAILQ_FOREACH(ar, &sc->sc_requests, ar_next) {
|
||||
sx_xlock(&autofs_softc->sc_lock);
|
||||
TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) {
|
||||
if (ar->ar_mount != amp)
|
||||
continue;
|
||||
ar->ar_error = ENXIO;
|
||||
@ -138,11 +137,11 @@ autofs_unmount(struct mount *mp, int mntflags)
|
||||
ar->ar_in_progress = false;
|
||||
found = true;
|
||||
}
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
if (found == false)
|
||||
break;
|
||||
|
||||
cv_broadcast(&sc->sc_cv);
|
||||
cv_broadcast(&autofs_softc->sc_cv);
|
||||
pause("autofs_umount", 1);
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$");
|
||||
static int autofs_trigger_vn(struct vnode *vp, const char *path,
|
||||
int pathlen, struct vnode **newvp);
|
||||
|
||||
extern struct autofs_softc *autofs_softc;
|
||||
|
||||
static int
|
||||
autofs_access(struct vop_access_args *ap)
|
||||
{
|
||||
@ -134,12 +136,10 @@ autofs_trigger_vn(struct vnode *vp, const char *path, int pathlen,
|
||||
{
|
||||
struct autofs_node *anp;
|
||||
struct autofs_mount *amp;
|
||||
struct autofs_softc *sc;
|
||||
int error, lock_flags;
|
||||
|
||||
anp = vp->v_data;
|
||||
amp = VFSTOAUTOFS(vp->v_mount);
|
||||
sc = amp->am_softc;
|
||||
|
||||
/*
|
||||
* Release the vnode lock, so that other operations, in partcular
|
||||
@ -151,7 +151,7 @@ autofs_trigger_vn(struct vnode *vp, const char *path, int pathlen,
|
||||
vref(vp);
|
||||
VOP_UNLOCK(vp, 0);
|
||||
|
||||
sx_xlock(&sc->sc_lock);
|
||||
sx_xlock(&autofs_softc->sc_lock);
|
||||
|
||||
/*
|
||||
* XXX: Workaround for mounting the same thing multiple times; revisit.
|
||||
@ -163,7 +163,7 @@ autofs_trigger_vn(struct vnode *vp, const char *path, int pathlen,
|
||||
|
||||
error = autofs_trigger(anp, path, pathlen);
|
||||
mounted:
|
||||
sx_xunlock(&sc->sc_lock);
|
||||
sx_xunlock(&autofs_softc->sc_lock);
|
||||
vn_lock(vp, lock_flags | LK_RETRY);
|
||||
vunref(vp);
|
||||
if ((vp->v_iflag & VI_DOOMED) != 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user