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 #include "opt_ufs.h" 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/buf.h> 35 #include <sys/kernel.h> 36 #include <sys/vnode.h> 37 #include <sys/lock.h> 38 #include <sys/mount.h> 39 #include <sys/mutex.h> 40 41 #include <ufs/ufs/extattr.h> 42 #include <ufs/ufs/quota.h> 43 #include <ufs/ufs/inode.h> 44 #include <ufs/ufs/ufsmount.h> 45 #include <ufs/ufs/gjournal.h> 46 47 #include <ufs/ffs/fs.h> 48 #include <ufs/ffs/ffs_extern.h> 49 50 /* 51 * Change the number of unreferenced inodes. 52 */ 53 static int 54 ufs_gjournal_modref(struct vnode *vp, int count) 55 { 56 struct cg *cgp; 57 struct buf *bp; 58 int error, cg; 59 struct cdev *dev; 60 struct inode *ip; 61 struct ufsmount *ump; 62 struct fs *fs; 63 struct vnode *devvp; 64 ino_t ino; 65 66 ip = VTOI(vp); 67 ump = VFSTOUFS(vp->v_mount); 68 fs = ump->um_fs; 69 devvp = ump->um_devvp; 70 ino = ip->i_number; 71 72 cg = ino_to_cg(fs, ino); 73 if (devvp->v_type == VREG) { 74 /* devvp is a snapshot */ 75 dev = VFSTOUFS(devvp->v_mount)->um_devvp->v_rdev; 76 } else if (devvp->v_type == VCHR) { 77 /* devvp is a normal disk device */ 78 dev = devvp->v_rdev; 79 } else { 80 bp = NULL; 81 return (EIO); 82 } 83 if ((uint64_t)ino >= fs->fs_ipg * fs->fs_ncg) 84 panic("ufs_gjournal_modref: range: dev = %s, ino = %ju, " 85 "fs = %s", devtoname(dev), (intmax_t)ino, fs->fs_fsmnt); 86 if ((error = ffs_getcg(fs, devvp, cg, 0, &bp, &cgp)) != 0) 87 return (error); 88 cgp->cg_unrefs += count; 89 UFS_LOCK(ump); 90 fs->fs_unrefs += count; 91 fs->fs_fmod = 1; 92 ACTIVECLEAR(fs, cg); 93 UFS_UNLOCK(ump); 94 bdwrite(bp); 95 return (0); 96 } 97 98 void 99 ufs_gjournal_orphan(struct vnode *vp) 100 { 101 struct inode *ip; 102 103 if (vp->v_mount->mnt_gjprovider == NULL) 104 return; 105 if (vp->v_usecount < 2 || (vp->v_vflag & VV_DELETED)) 106 return; 107 ip = VTOI(vp); 108 if ((vp->v_type == VDIR && ip->i_nlink > 2) || 109 (vp->v_type != VDIR && ip->i_nlink > 1)) { 110 return; 111 } 112 vp->v_vflag |= VV_DELETED; 113 114 ufs_gjournal_modref(vp, 1); 115 } 116 117 void 118 ufs_gjournal_close(struct vnode *vp) 119 { 120 struct inode *ip; 121 122 if (vp->v_mount->mnt_gjprovider == NULL) 123 return; 124 if (!(vp->v_vflag & VV_DELETED)) 125 return; 126 ip = VTOI(vp); 127 if (ip->i_nlink > 0) 128 return; 129 ufs_gjournal_modref(vp, -1); 130 } 131