1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2005-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 #include "opt_ufs.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/buf.h> 37 #include <sys/kernel.h> 38 #include <sys/vnode.h> 39 #include <sys/lock.h> 40 #include <sys/mount.h> 41 #include <sys/mutex.h> 42 43 #include <ufs/ufs/extattr.h> 44 #include <ufs/ufs/quota.h> 45 #include <ufs/ufs/inode.h> 46 #include <ufs/ufs/ufsmount.h> 47 #include <ufs/ufs/gjournal.h> 48 49 #include <ufs/ffs/fs.h> 50 #include <ufs/ffs/ffs_extern.h> 51 52 /* 53 * Change the number of unreferenced inodes. 54 */ 55 static int 56 ufs_gjournal_modref(struct vnode *vp, int count) 57 { 58 struct cg *cgp; 59 struct buf *bp; 60 int error, cg; 61 struct cdev *dev; 62 struct inode *ip; 63 struct ufsmount *ump; 64 struct fs *fs; 65 struct vnode *devvp; 66 ino_t ino; 67 68 ip = VTOI(vp); 69 ump = VFSTOUFS(vp->v_mount); 70 fs = ump->um_fs; 71 devvp = ump->um_devvp; 72 ino = ip->i_number; 73 74 cg = ino_to_cg(fs, ino); 75 if (devvp->v_type == VREG) { 76 /* devvp is a snapshot */ 77 dev = VFSTOUFS(devvp->v_mount)->um_devvp->v_rdev; 78 } else if (devvp->v_type == VCHR) { 79 /* devvp is a normal disk device */ 80 dev = devvp->v_rdev; 81 } else { 82 bp = NULL; 83 return (EIO); 84 } 85 if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) 86 panic("ufs_gjournal_modref: range: dev = %s, ino = %lu, fs = %s", 87 devtoname(dev), (u_long)ino, fs->fs_fsmnt); 88 if ((error = ffs_getcg(fs, devvp, cg, 0, &bp, &cgp)) != 0) 89 return (error); 90 cgp->cg_unrefs += count; 91 UFS_LOCK(ump); 92 fs->fs_unrefs += count; 93 fs->fs_fmod = 1; 94 ACTIVECLEAR(fs, cg); 95 UFS_UNLOCK(ump); 96 bdwrite(bp); 97 return (0); 98 } 99 100 void 101 ufs_gjournal_orphan(struct vnode *vp) 102 { 103 struct inode *ip; 104 105 if (vp->v_mount->mnt_gjprovider == NULL) 106 return; 107 if (vp->v_usecount < 2 || (vp->v_vflag & VV_DELETED)) 108 return; 109 ip = VTOI(vp); 110 if ((vp->v_type == VDIR && ip->i_nlink > 2) || 111 (vp->v_type != VDIR && ip->i_nlink > 1)) { 112 return; 113 } 114 vp->v_vflag |= VV_DELETED; 115 116 ufs_gjournal_modref(vp, 1); 117 } 118 119 void 120 ufs_gjournal_close(struct vnode *vp) 121 { 122 struct inode *ip; 123 124 if (vp->v_mount->mnt_gjprovider == NULL) 125 return; 126 if (!(vp->v_vflag & VV_DELETED)) 127 return; 128 ip = VTOI(vp); 129 if (ip->i_nlink > 0) 130 return; 131 ufs_gjournal_modref(vp, -1); 132 } 133