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 "../afs/sysincludes.h" /* Standard vendor system headers */
18 #include "../afs/afsincludes.h" /* Afs-based standard headers */
19 #include "../afs/osi_inode.h"
20 #include "../afs/afs_stats.h" /* statistics stuff */
22 extern int (*ufs_iputp)(), (*ufs_iallocp)(), (*ufs_iupdatp)(), (*ufs_igetp)();
24 getinode(vfsp, dev, inode, ipp, credp,perror)
26 struct AFS_UCRED *credp;
33 register afs_int32 code;
38 AFS_STATCNT(getinode);
43 #if !defined(AFS_SUN58_ENV)
44 && !(vfsp = vfs_devsearch(dev))
46 && !(vfsp = vfs_dev2vfsp(dev))
51 if (code = (*ufs_igetp)(vfsp, inode, &ip, credp)) {
59 /* get an existing inode. Common code for iopen, iread/write, iinc/dec. */
60 igetinode(vfsp, dev, inode, ipp, credp,perror)
61 struct AFS_UCRED *credp;
68 struct inode *pip, *ip;
69 extern struct osi_dev cacheDev;
70 register int code = 0;
74 AFS_STATCNT(igetinode);
76 code = getinode(vfsp, dev, inode, &ip, credp,perror);
80 rw_enter(&ip->i_contents, RW_READER);
82 if (ip->i_mode == 0) {
83 /* Not an allocated inode */
84 rw_exit(&ip->i_contents);
89 if (ip->i_nlink == 0 || (ip->i_mode&IFMT) != IFREG) {
90 rw_exit(&ip->i_contents);
95 /* On VFS40 systems, iput does major synchronous write action, but only
96 when the reference count on the vnode goes to 0. Normally, Sun users
97 don't notice this because the DNLC keep references for them, but we
98 notice 'cause we don't. So, we make a fake dnlc entry which gets
99 cleaned up by iget when it needs the space. */
100 if (dev != cacheDev.dev) {
102 * Don't call dnlc for the cm inodes since it's a big performance
105 dnlc_enter(ITOV(ip), "a", ITOV(ip), (struct AFS_UCRED *) 0);
109 rw_exit(&ip->i_contents);
115 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, rvp, credp)
117 struct AFS_UCRED *credp;
118 long near_inode, param1, param2, param3, param4;
122 struct inode *ip, *newip;
126 AFS_STATCNT(afs_syscall_icreate);
128 if (!afs_suser(credp))
131 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
132 * This conversion is needed only for the 64 bit OS.
135 #ifdef AFS_SUN57_64BIT_ENV
136 newdev = expldev( (dev32_t) dev);
141 code = getinode(0, (dev_t)newdev, 2, &ip, credp,&dummy);
145 if (code = (*ufs_iallocp)(ip, near_inode, 0, &newip, credp)) {
150 rw_enter(&newip->i_contents, RW_WRITER);
151 mutex_enter(&newip->i_tlock);
152 newip->i_flag |= IACC|IUPD|ICHG;
153 mutex_exit(&newip->i_tlock);
156 #if defined(AFS_SUN56_ENV)
157 newip->i_vicemagic = VICEMAGIC;
163 newip->i_mode = IFREG;
164 newip->i_vnode.v_type = VREG;
166 newip->i_vicep1 = param1;
167 if (param2 == 0x1fffffff/*INODESPECIAL*/) {
168 newip->i_vicep2 = ((0x1fffffff << 3) + (param4 & 0x3));
169 newip->i_vicep3 = param3;
171 newip->i_vicep2 = (((param2 >> 16) & 0x1f) << 27) +
172 (((param4 >> 16) & 0x1f) << 22) +
174 newip->i_vicep3 = ((param4 << 16) + (param2 & 0xffff));
176 #ifdef AFS_SUN57_64BIT_ENV
177 rvp->r_vals = newip->i_number;
179 rvp->r_val1 = newip->i_number;
183 * We're being conservative and sync to the disk
186 (*ufs_iupdatp)(newip, 1);
187 rw_exit(&newip->i_contents);
192 afs_syscall_iopen(dev, inode, usrmod, rvp, credp)
194 struct AFS_UCRED *credp;
200 struct vnode *vp = (struct vnode *)0;
206 AFS_STATCNT(afs_syscall_iopen);
208 if (!afs_suser(credp))
211 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
212 * This conversion is needed only for the 64 bit OS.
215 #ifdef AFS_SUN57_64BIT_ENV
216 newdev = expldev( (dev32_t) dev);
221 code = igetinode(0, (dev_t)newdev, (ino_t)inode, &ip, credp,&dummy);
225 code = falloc((struct vnode *)NULL, FWRITE|FREAD, &fp, &fd);
231 /* fp->f_count, f_audit_data are set by falloc */
232 fp->f_vnode = ITOV(ip);
234 fp->f_flag = (usrmod+1) & (FMASK);
236 /* fp->f_count, f_msgcount are set by falloc */
238 /* fp->f_offset zeroed by falloc */
239 /* f_cred set by falloc */
241 * falloc returns the fp write locked
243 mutex_exit(&fp->f_tlock);
245 * XXX We should set the fp to null since we don't need it in the icalls
248 #ifdef AFS_SUN57_64BIT_ENV
259 afs_syscall_iincdec(dev, inode, inode_p1, amount, rvp, credp)
261 struct AFS_UCRED *credp;
262 int inode, inode_p1, amount;
267 register afs_int32 code;
270 if (!afs_suser(credp))
273 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
274 * This conversion is needed only for the 64 bit OS.
277 #ifdef AFS_SUN57_64BIT_ENV
278 newdev = expldev( (dev32_t) dev);
283 code = igetinode(0, (dev_t)newdev, (ino_t)inode, &ip, credp,&dummy);
287 if (!IS_VICEMAGIC(ip))
290 rw_enter(&ip->i_contents, RW_WRITER);
291 ip->i_nlink += amount;
292 if (ip->i_nlink == 0) {
293 /* remove the "a" name added by igetinode so that the space is reclaimed. */
294 dnlc_remove(ITOV(ip), "a");
297 mutex_enter(&ip->i_tlock);
299 mutex_exit(&ip->i_tlock);
300 /* We may want to force the inode to the disk in case of crashes, other references, etc. */
302 (*ufs_iupdatp)(ip, 1);
303 rw_exit(&ip->i_contents);