* Handling of buftargs.
*/
+/*
+ * Wait for any bufs with callbacks that have been submitted but
+ * have not yet returned... walk the hash list for the target.
+ */
+void
+xfs_wait_buftarg(
+ xfs_buftarg_t *target)
+{
+ xfs_buf_t *pb, *n;
+ pb_hash_t *h;
+ int i;
+
+ for (i = 0; i < NHASH; i++) {
+ h = &pbhash[i];
+again:
+ spin_lock(&h->pb_hash_lock);
+ list_for_each_entry_safe(pb, n, &h->pb_hash, pb_hash_list) {
+ if (pb->pb_target == target &&
+ !(pb->pb_flags & PBF_FS_MANAGED)) {
+ spin_unlock(&h->pb_hash_lock);
+ delay(100);
+ goto again;
+ }
+ }
+ spin_unlock(&h->pb_hash_lock);
+ }
+}
+
void
xfs_free_buftarg(
xfs_buftarg_t *btp,
extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *);
extern void xfs_free_buftarg(xfs_buftarg_t *, int);
+extern void xfs_wait_buftarg(xfs_buftarg_t *);
extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
extern void xfs_incore_relse(xfs_buftarg_t *, int, int);
extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
xfs_unmountfs_writesb(mp);
+ xfs_unmountfs_wait(mp); /* wait for async bufs */
+
xfs_log_unmount(mp); /* Done! No more fs ops. */
xfs_freesb(mp);
xfs_free_buftarg(mp->m_ddev_targp, 0);
}
+void
+xfs_unmountfs_wait(xfs_mount_t *mp)
+{
+ if (mp->m_logdev_targp != mp->m_ddev_targp)
+ xfs_wait_buftarg(mp->m_logdev_targp);
+ if (mp->m_rtdev_targp)
+ xfs_wait_buftarg(mp->m_rtdev_targp);
+ xfs_wait_buftarg(mp->m_ddev_targp);
+}
+
int
xfs_unmountfs_writesb(xfs_mount_t *mp)
{
extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int);
extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
+extern void xfs_unmountfs_wait(xfs_mount_t *);
extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *);
extern int xfs_unmountfs_writesb(xfs_mount_t *);
extern int xfs_unmount_flush(xfs_mount_t *, int);