1 /* Copyright (C) 1995 Transarc Corporation - All rights reserved. */
3 * SOLARIS inode operations
8 #include "../afs/param.h" /* Should be always first */
9 #include "../afs/sysincludes.h" /* Standard vendor system headers */
10 #include "../afs/afsincludes.h" /* Afs-based standard headers */
11 #include "../afs/osi_inode.h"
12 #include "../afs/afs_stats.h" /* statistics stuff */
14 extern int (*ufs_iputp)(), (*ufs_iallocp)(), (*ufs_iupdatp)(), (*ufs_igetp)();
16 getinode(vfsp, dev, inode, ipp, credp,perror)
18 struct AFS_UCRED *credp;
25 register afs_int32 code;
30 AFS_STATCNT(getinode);
34 if (!vfsp && !(vfsp = vfs_devsearch(dev))) {
37 if (code = (*ufs_igetp)(vfsp, inode, &ip, credp)) {
45 /* get an existing inode. Common code for iopen, iread/write, iinc/dec. */
46 igetinode(vfsp, dev, inode, ipp, credp,perror)
47 struct AFS_UCRED *credp;
54 struct inode *pip, *ip;
55 extern struct osi_dev cacheDev;
56 register int code = 0;
60 AFS_STATCNT(igetinode);
62 code = getinode(vfsp, dev, inode, &ip, credp,perror);
66 rw_enter(&ip->i_contents, RW_READER);
68 if (ip->i_mode == 0) {
69 /* Not an allocated inode */
70 rw_exit(&ip->i_contents);
75 if (ip->i_nlink == 0 || (ip->i_mode&IFMT) != IFREG) {
76 rw_exit(&ip->i_contents);
81 /* On VFS40 systems, iput does major synchronous write action, but only
82 when the reference count on the vnode goes to 0. Normally, Sun users
83 don't notice this because the DNLC keep references for them, but we
84 notice 'cause we don't. So, we make a fake dnlc entry which gets
85 cleaned up by iget when it needs the space. */
86 if (dev != cacheDev.dev) {
88 * Don't call dnlc for the cm inodes since it's a big performance
91 dnlc_enter(ITOV(ip), "a", ITOV(ip), (struct AFS_UCRED *) 0);
95 rw_exit(&ip->i_contents);
101 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, rvp, credp)
103 struct AFS_UCRED *credp;
104 long near_inode, param1, param2, param3, param4;
108 struct inode *ip, *newip;
112 AFS_STATCNT(afs_syscall_icreate);
114 if (!afs_suser(credp))
117 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
118 * This conversion is needed only for the 64 bit OS.
121 #ifdef AFS_SUN57_64BIT_ENV
122 newdev = expldev( (dev32_t) dev);
127 code = getinode(0, (dev_t)newdev, 2, &ip, credp,&dummy);
131 if (code = (*ufs_iallocp)(ip, near_inode, 0, &newip, credp)) {
136 rw_enter(&newip->i_contents, RW_WRITER);
137 mutex_enter(&newip->i_tlock);
138 newip->i_flag |= IACC|IUPD|ICHG;
139 mutex_exit(&newip->i_tlock);
142 #if defined(AFS_SUN56_ENV)
143 newip->i_vicemagic = VICEMAGIC;
149 newip->i_mode = IFREG;
150 newip->i_vnode.v_type = VREG;
152 newip->i_vicep1 = param1;
153 if (param2 == 0x1fffffff/*INODESPECIAL*/) {
154 newip->i_vicep2 = ((0x1fffffff << 3) + (param4 & 0x3));
155 newip->i_vicep3 = param3;
157 newip->i_vicep2 = (((param2 >> 16) & 0x1f) << 27) +
158 (((param4 >> 16) & 0x1f) << 22) +
160 newip->i_vicep3 = ((param4 << 16) + (param2 & 0xffff));
162 #ifdef AFS_SUN57_64BIT_ENV
163 rvp->r_vals = newip->i_number;
165 rvp->r_val1 = newip->i_number;
169 * We're being conservative and sync to the disk
172 (*ufs_iupdatp)(newip, 1);
173 rw_exit(&newip->i_contents);
178 afs_syscall_iopen(dev, inode, usrmod, rvp, credp)
180 struct AFS_UCRED *credp;
186 struct vnode *vp = (struct vnode *)0;
192 AFS_STATCNT(afs_syscall_iopen);
194 if (!afs_suser(credp))
197 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
198 * This conversion is needed only for the 64 bit OS.
201 #ifdef AFS_SUN57_64BIT_ENV
202 newdev = expldev( (dev32_t) dev);
207 code = igetinode(0, (dev_t)newdev, (ino_t)inode, &ip, credp,&dummy);
211 code = falloc((struct vnode *)NULL, FWRITE|FREAD, &fp, &fd);
217 /* fp->f_count, f_audit_data are set by falloc */
218 fp->f_vnode = ITOV(ip);
220 fp->f_flag = (usrmod+1) & (FMASK);
222 /* fp->f_count, f_msgcount are set by falloc */
224 /* fp->f_offset zeroed by falloc */
225 /* f_cred set by falloc */
227 * falloc returns the fp write locked
229 mutex_exit(&fp->f_tlock);
231 * XXX We should set the fp to null since we don't need it in the icalls
234 #ifdef AFS_SUN57_64BIT_ENV
245 afs_syscall_iincdec(dev, inode, inode_p1, amount, rvp, credp)
247 struct AFS_UCRED *credp;
248 int inode, inode_p1, amount;
253 register afs_int32 code;
256 if (!afs_suser(credp))
259 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
260 * This conversion is needed only for the 64 bit OS.
263 #ifdef AFS_SUN57_64BIT_ENV
264 newdev = expldev( (dev32_t) dev);
269 code = igetinode(0, (dev_t)newdev, (ino_t)inode, &ip, credp,&dummy);
273 if (!IS_VICEMAGIC(ip))
276 rw_enter(&ip->i_contents, RW_WRITER);
277 ip->i_nlink += amount;
278 if (ip->i_nlink == 0) {
279 /* remove the "a" name added by igetinode so that the space is reclaimed. */
280 dnlc_remove(ITOV(ip), "a");
283 mutex_enter(&ip->i_tlock);
285 mutex_exit(&ip->i_tlock);
286 /* We may want to force the inode to the disk in case of crashes, other references, etc. */
288 (*ufs_iupdatp)(ip, 1);
289 rw_exit(&ip->i_contents);