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