diff options
author | phk <phk@FreeBSD.org> | 2005-09-15 08:50:16 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2005-09-15 08:50:16 +0000 |
commit | eafa84f647542c3749340df5617561b979945594 (patch) | |
tree | 9c093e190a5fb313a1ef8acea97554f7358295f6 /sys | |
parent | 1a7de63bbb6ec885b914b9b3d077642dd4350220 (diff) | |
download | FreeBSD-src-eafa84f647542c3749340df5617561b979945594.zip FreeBSD-src-eafa84f647542c3749340df5617561b979945594.tar.gz |
Protect the devfs rule internal global lists with a sx lock, the per
mount locks are not enough. Finer granularity (x)locking could be
implemented, but I prefer to keep it simple for now.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/devfs/devfs_rule.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/fs/devfs/devfs_rule.c b/sys/fs/devfs/devfs_rule.c index 684ce53..5e25f4e 100644 --- a/sys/fs/devfs/devfs_rule.c +++ b/sys/fs/devfs/devfs_rule.c @@ -72,6 +72,7 @@ #include <sys/dirent.h> #include <sys/vnode.h> #include <sys/ioccom.h> +#include <sys/sx.h> #include <fs/devfs/devfs.h> @@ -123,6 +124,7 @@ static void devfs_ruleset_destroy(struct devfs_ruleset **dsp); static void devfs_ruleset_reap(struct devfs_ruleset **dsp); static int devfs_ruleset_use(devfs_rsnum rsnum, struct devfs_mount *dm); +static struct sx sx_rules; static SLIST_HEAD(, devfs_ruleset) devfs_rulesets; /* @@ -135,9 +137,11 @@ devfs_rules_apply(struct devfs_mount *dm, struct devfs_dirent *de) { struct devfs_ruleset *ds; + sx_slock(&sx_rules); ds = devfs_ruleset_bynum(dm->dm_ruleset); KASSERT(ds != NULL, ("mount-point has NULL ruleset")); devfs_ruleset_applyde(ds, de, devfs_rule_depth); + sx_sunlock(&sx_rules); } /* @@ -148,6 +152,7 @@ devfs_rules_init(void *junk __unused) { struct devfs_ruleset *ds; + sx_init(&sx_rules, "devfsrules"); SLIST_INIT(&devfs_rulesets); ds = devfs_ruleset_create(0); @@ -179,6 +184,7 @@ devfs_rules_ioctl(struct devfs_mount *dm, u_long cmd, caddr_t data, struct threa if (error != 0) return (error); + sx_xlock(&sx_rules); switch (cmd) { case DEVFSIO_RADD: dr = (struct devfs_rule *)data; @@ -310,6 +316,7 @@ devfs_rules_ioctl(struct devfs_mount *dm, u_long cmd, caddr_t data, struct threa } out: + sx_xunlock(&sx_rules); return (error); } @@ -327,10 +334,12 @@ devfs_rules_newmount(struct devfs_mount *dm, struct thread *td) * old ruleset. Making some value of ds_ruleset "special" to * mean "don't decrement refcount" is uglier than this. */ + sx_slock(&sx_rules); ds = devfs_ruleset_bynum(0); KASSERT(ds != NULL, ("no ruleset 0")); ++ds->ds_refcount; dm->dm_ruleset = 0; + sx_sunlock(&sx_rules); } /* @@ -799,4 +808,3 @@ devfs_ruleset_use(devfs_rsnum rsnum, struct devfs_mount *dm) devfs_ruleset_reap(&cds); return (0); } - |