Home | History | Annotate | Download | only in ufs
      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 
     59 int
     60 ufs_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 	}
    109 out:
    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  */
    118 void
    119 ufs_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