1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/t_lock.h> 27 #include <sys/param.h> 28 #include <sys/systm.h> 29 #include <sys/signal.h> 30 #include <sys/cred.h> 31 #include <sys/proc.h> 32 #include <sys/disp.h> 33 #include <sys/user.h> 34 #include <sys/vfs.h> 35 #include <sys/vnode.h> 36 #include <sys/stat.h> 37 #include <sys/mode.h> 38 #include <sys/buf.h> 39 #include <sys/uio.h> 40 #include <sys/dnlc.h> 41 #include <sys/pathname.h> 42 #include <sys/fs/ufs_inode.h> 43 #include <sys/fs/ufs_fs.h> 44 #include <sys/mount.h> 45 #include <sys/fs/ufs_fsdir.h> 46 #include <sys/fs/ufs_trans.h> 47 #include <sys/fs/ufs_panic.h> 48 #include <sys/fs/ufs_quota.h> 49 #include <sys/errno.h> 50 #include <sys/debug.h> 51 #include <vm/seg.h> 52 #include <sys/sysmacros.h> 53 #include <sys/cmn_err.h> 54 #include <sys/cpuvar.h> 55 #include <sys/unistd.h> 56 57 int 58 ufs_xattr_getattrdir( 59 vnode_t *dvp, 60 struct inode **sip, 61 int flags, 62 struct cred *cr) 63 { 64 struct vfs *vfsp; 65 struct inode *ip, *sdp; 66 int error; 67 68 ip = VTOI(dvp); 69 if (flags & LOOKUP_XATTR) { 70 if (ip && ((ip->i_oeftflag) != 0)) { 71 vfsp = dvp->v_vfsp; 72 73 error = ufs_iget(vfsp, ip->i_oeftflag, sip, cr); 74 if (error) 75 return (error); 76 77 sdp = *sip; 78 79 /* 80 * Make sure it really is an ATTRDIR 81 */ 82 if ((sdp->i_mode & IFMT) != IFATTRDIR) { 83 cmn_err(CE_NOTE, "ufs_getattrdir: inode %d" 84 " points to attribute directory %d " 85 "which is not an attribute directory;" 86 "run fsck on file system", 87 (int)ip->i_number, (int)sdp->i_number); 88 VN_RELE(ITOV(sdp)); 89 return (ENOENT); 90 } 91 ITOV(sdp)->v_type = VDIR; 92 ITOV(sdp)->v_flag |= V_XATTRDIR; 93 error = 0; 94 goto out; 95 } else if (flags & CREATE_XATTR_DIR) { 96 error = ufs_xattrmkdir(ip, sip, 1, cr); 97 } else { 98 error = ENOENT; 99 goto out; 100 } 101 102 } else if (flags & CREATE_XATTR_DIR) { 103 error = ufs_xattrmkdir(ip, sip, 1, cr); 104 } else { 105 error = ENOENT; 106 } 107 out: 108 return (error); 109 } 110 111 112 /* 113 * Unhook an attribute directory from a parent file/dir 114 * Only do so, if we are the only user of the vnode. 115 */ 116 void 117 ufs_unhook_shadow(struct inode *ip, struct inode *sip) 118 { 119 struct vnode *datavp = ITOV(ip); 120 struct vnode *dirvp = ITOV(sip); 121 int hno; 122 kmutex_t *ihm; 123 124 ASSERT(RW_WRITE_HELD(&sip->i_contents)); 125 ASSERT(RW_WRITE_HELD(&ip->i_contents)); 126 127 if (vn_is_readonly(ITOV(ip))) 128 return; 129 130 if (ip->i_ufsvfs == NULL || sip->i_ufsvfs == NULL) 131 return; 132 133 hno = INOHASH(ip->i_number); 134 ihm = &ih_lock[hno]; 135 mutex_enter(ihm); 136 137 mutex_enter(&datavp->v_lock); 138 mutex_enter(&dirvp->v_lock); 139 140 if (dirvp->v_count != 1 && datavp->v_count != 1) { 141 mutex_exit(&dirvp->v_lock); 142 mutex_exit(&datavp->v_lock); 143 mutex_exit(ihm); 144 return; 145 } 146 147 /* 148 * Delete shadow from ip 149 */ 150 151 sip->i_nlink -= 2; 152 ufs_setreclaim(sip); 153 TRANS_INODE(sip->i_ufsvfs, sip); 154 sip->i_flag |= ICHG; 155 sip->i_seq++; 156 ITIMES_NOLOCK(sip); 157 158 /* 159 * Update src file 160 */ 161 ip->i_oeftflag = 0; 162 TRANS_INODE(ip->i_ufsvfs, ip); 163 ip->i_flag |= ICHG; 164 ip->i_seq++; 165 ufs_iupdat(ip, 1); 166 mutex_exit(&dirvp->v_lock); 167 mutex_exit(&datavp->v_lock); 168 mutex_exit(ihm); 169 } 170