1 /*- 2 * Copyright (c) 2005-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/vnode.h> 33 #include <sys/mount.h> 34 35 #include <ufs/ufs/extattr.h> 36 #include <ufs/ufs/quota.h> 37 #include <ufs/ufs/inode.h> 38 #include <ufs/ufs/ufs_extern.h> 39 #include <ufs/ufs/ufsmount.h> 40 41 #include <ufs/ffs/fs.h> 42 #include <ufs/ffs/ffs_extern.h> 43 44 #include <geom/geom.h> 45 #include <geom/journal/g_journal.h> 46 47 static const int superblocks[] = SBLOCKSEARCH; 48 49 static int 50 g_journal_ufs_clean(struct mount *mp) 51 { 52 struct ufsmount *ump; 53 struct fs *fs; 54 int flags; 55 56 ump = VFSTOUFS(mp); 57 fs = ump->um_fs; 58 59 flags = fs->fs_flags; 60 fs->fs_flags &= ~(FS_UNCLEAN | FS_NEEDSFSCK); 61 ffs_sbupdate(ump, MNT_WAIT, 1); 62 fs->fs_flags = flags; 63 64 return (0); 65 } 66 67 static void 68 g_journal_ufs_dirty(struct g_consumer *cp) 69 { 70 struct fs *fs; 71 int error, i, sb; 72 73 if (SBLOCKSIZE % cp->provider->sectorsize != 0) 74 return; 75 for (i = 0; (sb = superblocks[i]) != -1; i++) { 76 if (sb % cp->provider->sectorsize != 0) 77 continue; 78 fs = g_read_data(cp, sb, SBLOCKSIZE, NULL); 79 if (fs == NULL) 80 continue; 81 if (fs->fs_magic != FS_UFS1_MAGIC && 82 fs->fs_magic != FS_UFS2_MAGIC) { 83 g_free(fs); 84 continue; 85 } 86 GJ_DEBUG(0, "clean=%d flags=0x%x", fs->fs_clean, fs->fs_flags); 87 fs->fs_clean = 0; 88 fs->fs_flags |= FS_NEEDSFSCK | FS_UNCLEAN; 89 error = g_write_data(cp, sb, fs, SBLOCKSIZE); 90 g_free(fs); 91 if (error != 0) { 92 GJ_DEBUG(0, "Cannot mark file system %s as dirty " 93 "(error=%d).", cp->provider->name, error); 94 } else { 95 GJ_DEBUG(0, "File system %s marked as dirty.", 96 cp->provider->name); 97 } 98 } 99 } 100 101 const struct g_journal_desc g_journal_ufs = { 102 .jd_fstype = "ufs", 103 .jd_clean = g_journal_ufs_clean, 104 .jd_dirty = g_journal_ufs_dirty 105 }; 106 107 MODULE_DEPEND(g_journal, ufs, 1, 1, 1); 108