Module Name: src Committed By: hannken Date: Sun Jun 18 13:59:45 UTC 2017
Modified Files: src/sys/kern: vfs_trans.c Log Message: Clear fstrans entries whose mount is gone from the last fstrans_done() only. To generate a diff of this commit: cvs rdiff -u -r1.46 -r1.47 src/sys/kern/vfs_trans.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_trans.c diff -u src/sys/kern/vfs_trans.c:1.46 src/sys/kern/vfs_trans.c:1.47 --- src/sys/kern/vfs_trans.c:1.46 Sun Jun 4 08:05:42 2017 +++ src/sys/kern/vfs_trans.c Sun Jun 18 13:59:45 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_trans.c,v 1.46 2017/06/04 08:05:42 hannken Exp $ */ +/* $NetBSD: vfs_trans.c,v 1.47 2017/06/18 13:59:45 hannken Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.46 2017/06/04 08:05:42 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.47 2017/06/18 13:59:45 hannken Exp $"); /* * File system transaction operations. @@ -92,6 +92,7 @@ static LIST_HEAD(fstrans_lwp_head, fstra static inline struct mount *fstrans_normalize_mount(struct mount *); static void fstrans_lwp_dtor(void *); static void fstrans_mount_dtor(struct mount *); +static void fstrans_clear_lwp_info(void); static struct fstrans_lwp_info *fstrans_get_lwp_info(struct mount *, bool); static inline int _fstrans_start(struct mount *, enum fstrans_lock_type, int); static bool grant_lock(const enum fstrans_state, const enum fstrans_lock_type); @@ -227,31 +228,42 @@ fstrans_unmount(struct mount *mp) } /* - * Retrieve the per lwp info for this mount allocating if necessary. + * Clear mount entries whose mount is gone. */ -static struct fstrans_lwp_info * -fstrans_get_lwp_info(struct mount *mp, bool do_alloc) +static void +fstrans_clear_lwp_info(void) { - struct fstrans_lwp_info *fli, *res; - struct fstrans_mount_info *fmi; + struct fstrans_lwp_info *fli; /* - * Scan our list for a match clearing entries whose mount is gone. + * Scan our list clearing entries whose mount is gone. */ - res = NULL; for (fli = lwp_getspecific(lwp_data_key); fli; fli = fli->fli_succ) { - if (fli->fli_mount == mp) { - KASSERT(res == NULL); - res = fli; - } else if (fli->fli_mount != NULL && + if (fli->fli_mount != NULL && (fli->fli_mount->mnt_iflag & IMNT_GONE) != 0 && fli->fli_trans_cnt == 0 && fli->fli_cow_cnt == 0) { fstrans_mount_dtor(fli->fli_mount); fli->fli_mount = NULL; } } - if (__predict_true(res != NULL)) - return res; +} + +/* + * Retrieve the per lwp info for this mount allocating if necessary. + */ +static struct fstrans_lwp_info * +fstrans_get_lwp_info(struct mount *mp, bool do_alloc) +{ + struct fstrans_lwp_info *fli; + struct fstrans_mount_info *fmi; + + /* + * Scan our list for a match. + */ + for (fli = lwp_getspecific(lwp_data_key); fli; fli = fli->fli_succ) { + if (fli->fli_mount == mp) + return fli; + } if (! do_alloc) return NULL; @@ -421,6 +433,8 @@ fstrans_done(struct mount *mp) return; } + fstrans_clear_lwp_info(); + s = pserialize_read_enter(); fmi = mp->mnt_transinfo; if (__predict_true(fmi->fmi_state == FSTRANS_NORMAL)) {