Skip to content

Commit 8d83871

Browse files
Ryan Moellerandrewc12
Ryan Moeller
authored andcommitted
FreeBSD: libspl: Add locking around statfs globals
Makes getmntent and getmntany thread-safe for external consumers of libzfs zpool_disable_datasets, zfs_iter_mounted, libzfs_mnttab_update, libzfs_mnttab_find. Reviewed-by: Alexander Motin <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ryan Moeller <[email protected]> Closes openzfs#13484
1 parent 364a4a7 commit 8d83871

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

lib/libspl/os/freebsd/mnttab.c

+15-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
3939

4040
#include <ctype.h>
4141
#include <errno.h>
42+
#include <pthread.h>
4243
#include <stdio.h>
4344
#include <stdlib.h>
4445
#include <string.h>
@@ -136,6 +137,7 @@ statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
136137
mp->mnt_mntopts = gmntopts;
137138
}
138139

140+
static pthread_rwlock_t gsfs_lock = PTHREAD_RWLOCK_INITIALIZER;
139141
static struct statfs *gsfs = NULL;
140142
static int allfs = 0;
141143

@@ -145,6 +147,8 @@ statfs_init(void)
145147
struct statfs *sfs;
146148
int error;
147149

150+
(void) pthread_rwlock_wrlock(&gsfs_lock);
151+
148152
if (gsfs != NULL) {
149153
free(gsfs);
150154
gsfs = NULL;
@@ -162,13 +166,15 @@ statfs_init(void)
162166
sfs = realloc(gsfs, allfs * sizeof (gsfs[0]));
163167
if (sfs != NULL)
164168
gsfs = sfs;
169+
(void) pthread_rwlock_unlock(&gsfs_lock);
165170
return (0);
166171
fail:
167172
error = errno;
168173
if (gsfs != NULL)
169174
free(gsfs);
170175
gsfs = NULL;
171176
allfs = 0;
177+
(void) pthread_rwlock_unlock(&gsfs_lock);
172178
return (error);
173179
}
174180

@@ -181,6 +187,8 @@ getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
181187
if (error != 0)
182188
return (error);
183189

190+
(void) pthread_rwlock_rdlock(&gsfs_lock);
191+
184192
for (i = 0; i < allfs; i++) {
185193
if (mrefp->mnt_special != NULL &&
186194
strcmp(mrefp->mnt_special, gsfs[i].f_mntfromname) != 0) {
@@ -195,8 +203,10 @@ getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
195203
continue;
196204
}
197205
statfs2mnttab(&gsfs[i], mgetp);
206+
(void) pthread_rwlock_unlock(&gsfs_lock);
198207
return (0);
199208
}
209+
(void) pthread_rwlock_unlock(&gsfs_lock);
200210
return (-1);
201211
}
202212

@@ -214,9 +224,13 @@ getmntent(FILE *fp, struct mnttab *mp)
214224
if (error != 0)
215225
return (error);
216226
}
217-
if (nfs >= allfs)
227+
(void) pthread_rwlock_rdlock(&gsfs_lock);
228+
if (nfs >= allfs) {
229+
(void) pthread_rwlock_unlock(&gsfs_lock);
218230
return (-1);
231+
}
219232
statfs2mnttab(&gsfs[nfs], mp);
233+
(void) pthread_rwlock_unlock(&gsfs_lock);
220234
if (lseek(fileno(fp), 1, SEEK_CUR) == -1)
221235
return (errno);
222236
return (0);

0 commit comments

Comments
 (0)