Page MenuHomeFreeBSD

D8030.diff
No OneTemporary

D8030.diff

Index: head/sys/kern/vfs_syscalls.c
===================================================================
--- head/sys/kern/vfs_syscalls.c
+++ head/sys/kern/vfs_syscalls.c
@@ -446,16 +446,19 @@
size_t *countp, enum uio_seg bufseg, int flags)
{
struct mount *mp, *nmp;
- struct statfs *sfsp, *sp, sb;
+ struct statfs *sfsp, *sp, sb, *tofree;
size_t count, maxcount;
int error;
+restart:
maxcount = bufsize / sizeof(struct statfs);
- if (bufsize == 0)
+ if (bufsize == 0) {
sfsp = NULL;
- else if (bufseg == UIO_USERSPACE)
+ tofree = NULL;
+ } else if (bufseg == UIO_USERSPACE) {
sfsp = *buf;
- else /* if (bufseg == UIO_SYSSPACE) */ {
+ tofree = NULL;
+ } else /* if (bufseg == UIO_SYSSPACE) */ {
count = 0;
mtx_lock(&mountlist_mtx);
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
@@ -464,8 +467,8 @@
mtx_unlock(&mountlist_mtx);
if (maxcount > count)
maxcount = count;
- sfsp = *buf = malloc(maxcount * sizeof(struct statfs), M_TEMP,
- M_WAITOK);
+ tofree = sfsp = *buf = malloc(maxcount * sizeof(struct statfs),
+ M_TEMP, M_WAITOK);
}
count = 0;
mtx_lock(&mountlist_mtx);
@@ -480,9 +483,24 @@
continue;
}
#endif
- if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) {
- nmp = TAILQ_NEXT(mp, mnt_list);
- continue;
+ if (flags == MNT_WAIT) {
+ if (vfs_busy(mp, MBF_MNTLSTLOCK) != 0) {
+ /*
+ * If vfs_busy() failed, and MBF_NOWAIT
+ * wasn't passed, then the mp is gone.
+ * Furthermore, because of MBF_MNTLSTLOCK,
+ * the mountlist_mtx was dropped. We have
+ * no other choice than to start over.
+ */
+ mtx_unlock(&mountlist_mtx);
+ free(tofree, M_TEMP);
+ goto restart;
+ }
+ } else {
+ if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK) != 0) {
+ nmp = TAILQ_NEXT(mp, mnt_list);
+ continue;
+ }
}
if (sfsp && count < maxcount) {
sp = &mp->mnt_stat;

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 16, 8:26 PM (16 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29786019
Default Alt Text
D8030.diff (1 KB)

Event Timeline