2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * SOLARIS inode operations
16 #include "../afs/param.h" /* Should be always first */
17 #include <afsconfig.h>
21 #include "../afs/sysincludes.h" /* Standard vendor system headers */
22 #include "../afs/afsincludes.h" /* Afs-based standard headers */
23 #include "../afs/osi_inode.h"
24 #include "../afs/afs_stats.h" /* statistics stuff */
26 extern int (*ufs_iallocp)(), (*ufs_iupdatp)(), (*ufs_igetp)(),
27 (*ufs_itimes_nolockp)();
29 #define AFS_ITIMES(ip) { \
30 mutex_enter(&(ip)->i_tlock); \
31 (*ufs_itimes_nolockp)(ip); \
32 mutex_exit(&(ip)->i_tlock); \
35 getinode(vfsp, dev, inode, ipp, credp,perror)
37 struct AFS_UCRED *credp;
44 register afs_int32 code;
48 struct ufsvfs *ufsvfsp;
50 AFS_STATCNT(getinode);
55 #if !defined(AFS_SUN58_ENV)
56 && !(vfsp = vfs_devsearch(dev))
58 && !(vfsp = vfs_dev2vfsp(dev))
63 ufsvfsp = (struct ufsvfs *)vfsp->vfs_data;
65 #if defined(AFS_SUN57_ENV)
66 rw_enter(&ufsvfsp->vfs_dqrwlock, RW_READER);
68 code = (*ufs_igetp)(vfsp, inode, &ip, credp);
69 #if defined(AFS_SUN57_ENV)
70 rw_exit(&ufsvfsp->vfs_dqrwlock);
81 /* get an existing inode. Common code for iopen, iread/write, iinc/dec. */
82 igetinode(vfsp, dev, inode, ipp, credp,perror)
83 struct AFS_UCRED *credp;
90 struct inode *pip, *ip;
91 extern struct osi_dev cacheDev;
92 register int code = 0;
96 AFS_STATCNT(igetinode);
98 code = getinode(vfsp, dev, inode, &ip, credp,perror);
102 rw_enter(&ip->i_contents, RW_READER);
104 if (ip->i_mode == 0) {
105 /* Not an allocated inode */
107 rw_exit(&ip->i_contents);
112 if (ip->i_nlink == 0 || (ip->i_mode&IFMT) != IFREG) {
114 rw_exit(&ip->i_contents);
119 /* On VFS40 systems, iput does major synchronous write action, but only
120 when the reference count on the vnode goes to 0. Normally, Sun users
121 don't notice this because the DNLC keep references for them, but we
122 notice 'cause we don't. So, we make a fake dnlc entry which gets
123 cleaned up by iget when it needs the space. */
124 if (dev != cacheDev.dev) {
126 * Don't call dnlc for the cm inodes since it's a big performance
129 dnlc_enter(ITOV(ip), "a", ITOV(ip), (struct AFS_UCRED *) 0);
133 rw_exit(&ip->i_contents);
139 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, rvp, credp)
141 struct AFS_UCRED *credp;
142 long near_inode, param1, param2, param3, param4;
146 struct inode *ip, *newip;
149 struct ufsvfs *ufsvfsp;
151 AFS_STATCNT(afs_syscall_icreate);
153 if (!afs_suser(credp))
156 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
157 * This conversion is needed only for the 64 bit OS.
160 #ifdef AFS_SUN57_64BIT_ENV
161 newdev = expldev( (dev32_t) dev);
166 code = getinode(0, (dev_t)newdev, 2, &ip, credp,&dummy);
171 ufsvfsp = ip->i_ufsvfs;
172 rw_enter(&ip->i_rwlock, RW_WRITER);
173 #if defined(AFS_SUN57_ENV)
174 rw_enter(&ufsvfsp->vfs_dqrwlock, RW_READER);
176 rw_enter(&ip->i_contents, RW_WRITER);
177 code = (*ufs_iallocp)(ip, near_inode, 0, &newip, credp);
178 #if defined(AFS_SUN57_ENV)
179 rw_exit(&ufsvfsp->vfs_dqrwlock);
181 rw_exit(&ip->i_rwlock);
184 rw_exit(&ip->i_contents);
190 rw_enter(&newip->i_contents, RW_WRITER);
191 mutex_enter(&newip->i_tlock);
192 newip->i_flag |= IACC|IUPD|ICHG;
193 mutex_exit(&newip->i_tlock);
196 #if defined(AFS_SUN56_ENV)
197 newip->i_vicemagic = VICEMAGIC;
203 newip->i_mode = IFREG;
204 newip->i_vnode.v_type = VREG;
206 newip->i_vicep1 = param1;
207 if (param2 == 0x1fffffff/*INODESPECIAL*/) {
208 newip->i_vicep2 = ((0x1fffffff << 3) + (param4 & 0x3));
209 newip->i_vicep3 = param3;
211 newip->i_vicep2 = (((param2 >> 16) & 0x1f) << 27) +
212 (((param4 >> 16) & 0x1f) << 22) +
214 newip->i_vicep3 = ((param4 << 16) + (param2 & 0xffff));
216 #ifdef AFS_SUN57_64BIT_ENV
217 rvp->r_vals = newip->i_number;
219 rvp->r_val1 = newip->i_number;
223 * We're being conservative and sync to the disk
226 (*ufs_iupdatp)(newip, 1);
228 rw_exit(&newip->i_contents);
229 VN_RELE(ITOV(newip));
233 afs_syscall_iopen(dev, inode, usrmod, rvp, credp)
235 struct AFS_UCRED *credp;
241 struct vnode *vp = (struct vnode *)0;
247 AFS_STATCNT(afs_syscall_iopen);
249 if (!afs_suser(credp))
252 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
253 * This conversion is needed only for the 64 bit OS.
256 #ifdef AFS_SUN57_64BIT_ENV
257 newdev = expldev( (dev32_t) dev);
262 code = igetinode(0, (dev_t)newdev, (ino_t)inode, &ip, credp,&dummy);
266 code = falloc((struct vnode *)NULL, FWRITE|FREAD, &fp, &fd);
268 rw_enter(&ip->i_contents, RW_READER);
270 rw_exit(&ip->i_contents);
275 /* fp->f_count, f_audit_data are set by falloc */
276 fp->f_vnode = ITOV(ip);
278 fp->f_flag = (usrmod+1) & (FMASK);
280 /* fp->f_count, f_msgcount are set by falloc */
282 /* fp->f_offset zeroed by falloc */
283 /* f_cred set by falloc */
285 * falloc returns the fp write locked
287 mutex_exit(&fp->f_tlock);
289 * XXX We should set the fp to null since we don't need it in the icalls
292 #ifdef AFS_SUN57_64BIT_ENV
303 afs_syscall_iincdec(dev, inode, inode_p1, amount, rvp, credp)
305 struct AFS_UCRED *credp;
306 int inode, inode_p1, amount;
311 register afs_int32 code;
314 if (!afs_suser(credp))
317 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
318 * This conversion is needed only for the 64 bit OS.
321 #ifdef AFS_SUN57_64BIT_ENV
322 newdev = expldev( (dev32_t) dev);
327 code = igetinode(0, (dev_t)newdev, (ino_t)inode, &ip, credp,&dummy);
331 if (!IS_VICEMAGIC(ip)) {
333 rw_enter(&ip->i_contents, RW_READER);
335 rw_exit(&ip->i_contents);
338 rw_enter(&ip->i_contents, RW_WRITER);
339 ip->i_nlink += amount;
340 if (ip->i_nlink == 0) {
341 /* remove the "a" name added by igetinode so that the space is reclaimed. */
342 dnlc_remove(ITOV(ip), "a");
345 mutex_enter(&ip->i_tlock);
347 mutex_exit(&ip->i_tlock);
348 /* We may want to force the inode to the disk in case of crashes, other references, etc. */
350 (*ufs_iupdatp)(ip, 1);
352 rw_exit(&ip->i_contents);