ufs_xattr.c revision 4662:9c48274ded8b
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#pragma ident "%Z%%M% %I% %E% SMI" 27 28#include <sys/t_lock.h> 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/signal.h> 32#include <sys/cred.h> 33#include <sys/proc.h> 34#include <sys/disp.h> 35#include <sys/user.h> 36#include <sys/vfs.h> 37#include <sys/vnode.h> 38#include <sys/stat.h> 39#include <sys/mode.h> 40#include <sys/buf.h> 41#include <sys/uio.h> 42#include <sys/dnlc.h> 43#include <sys/pathname.h> 44#include <sys/fs/ufs_inode.h> 45#include <sys/fs/ufs_fs.h> 46#include <sys/mount.h> 47#include <sys/fs/ufs_fsdir.h> 48#include <sys/fs/ufs_trans.h> 49#include <sys/fs/ufs_panic.h> 50#include <sys/fs/ufs_quota.h> 51#include <sys/errno.h> 52#include <sys/debug.h> 53#include <vm/seg.h> 54#include <sys/sysmacros.h> 55#include <sys/cmn_err.h> 56#include <sys/cpuvar.h> 57#include <sys/unistd.h> 58 59int 60ufs_xattr_getattrdir( 61 vnode_t *dvp, 62 struct inode **sip, 63 int flags, 64 struct cred *cr) 65{ 66 struct vfs *vfsp; 67 struct inode *ip, *sdp; 68 int error; 69 70 ip = VTOI(dvp); 71 if (flags & LOOKUP_XATTR) { 72 if (ip && ((ip->i_oeftflag) != 0)) { 73 vfsp = dvp->v_vfsp; 74 75 error = ufs_iget(vfsp, ip->i_oeftflag, sip, cr); 76 if (error) 77 return (error); 78 79 sdp = *sip; 80 81 /* 82 * Make sure it really is an ATTRDIR 83 */ 84 if ((sdp->i_mode & IFMT) != IFATTRDIR) { 85 cmn_err(CE_NOTE, "ufs_getattrdir: inode %d" 86 " points to attribute directory %d " 87 "which is not an attribute directory;" 88 "run fsck on file system", 89 (int)ip->i_number, (int)sdp->i_number); 90 VN_RELE(ITOV(sdp)); 91 return (ENOENT); 92 } 93 ITOV(sdp)->v_type = VDIR; 94 ITOV(sdp)->v_flag |= V_XATTRDIR; 95 error = 0; 96 goto out; 97 } else if (flags & CREATE_XATTR_DIR) { 98 error = ufs_xattrmkdir(ip, sip, 1, cr); 99 } else { 100 error = ENOENT; 101 goto out; 102 } 103 104 } else if (flags & CREATE_XATTR_DIR) { 105 error = ufs_xattrmkdir(ip, sip, 1, cr); 106 } else { 107 error = ENOENT; 108 } 109out: 110 return (error); 111} 112 113 114/* 115 * Unhook an attribute directory from a parent file/dir 116 * Only do so, if we are the only user of the vnode. 117 */ 118void 119ufs_unhook_shadow(struct inode *ip, struct inode *sip) 120{ 121 struct vnode *datavp = ITOV(ip); 122 struct vnode *dirvp = ITOV(sip); 123 int hno; 124 kmutex_t *ihm; 125 126 ASSERT(RW_WRITE_HELD(&sip->i_contents)); 127 ASSERT(RW_WRITE_HELD(&ip->i_contents)); 128 129 if (vn_is_readonly(ITOV(ip))) 130 return; 131 132 if (ip->i_ufsvfs == NULL || sip->i_ufsvfs == NULL) 133 return; 134 135 hno = INOHASH(ip->i_number); 136 ihm = &ih_lock[hno]; 137 mutex_enter(ihm); 138 139 mutex_enter(&datavp->v_lock); 140 mutex_enter(&dirvp->v_lock); 141 142 if (dirvp->v_count != 1 && datavp->v_count != 1) { 143 mutex_exit(&dirvp->v_lock); 144 mutex_exit(&datavp->v_lock); 145 mutex_exit(ihm); 146 return; 147 } 148 149 /* 150 * Delete shadow from ip 151 */ 152 153 sip->i_nlink -= 2; 154 ufs_setreclaim(sip); 155 TRANS_INODE(sip->i_ufsvfs, sip); 156 sip->i_flag |= ICHG; 157 sip->i_seq++; 158 ITIMES_NOLOCK(sip); 159 160 /* 161 * Update src file 162 */ 163 ip->i_oeftflag = 0; 164 TRANS_INODE(ip->i_ufsvfs, ip); 165 ip->i_flag |= ICHG; 166 ip->i_seq++; 167 ufs_iupdat(ip, 1); 168 mutex_exit(&dirvp->v_lock); 169 mutex_exit(&datavp->v_lock); 170 mutex_exit(ihm); 171} 172