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 #define AFS_ITIMES_NOLOCK(ip) \
36 (*ufs_itimes_nolockp)(ip);
38 getinode(vfsp, dev, inode, ipp, credp,perror)
40 struct AFS_UCRED *credp;
47 register afs_int32 code;
51 struct ufsvfs *ufsvfsp;
53 AFS_STATCNT(getinode);
58 #if !defined(AFS_SUN58_ENV)
59 && !(vfsp = vfs_devsearch(dev))
61 && !(vfsp = vfs_dev2vfsp(dev))
66 ufsvfsp = (struct ufsvfs *)vfsp->vfs_data;
68 #if defined(AFS_SUN57_ENV)
69 rw_enter(&ufsvfsp->vfs_dqrwlock, RW_READER);
71 code = (*ufs_igetp)(vfsp, inode, &ip, credp);
72 #if defined(AFS_SUN57_ENV)
73 rw_exit(&ufsvfsp->vfs_dqrwlock);
84 /* get an existing inode. Common code for iopen, iread/write, iinc/dec. */
85 igetinode(vfsp, dev, inode, ipp, credp,perror)
86 struct AFS_UCRED *credp;
93 struct inode *pip, *ip;
94 extern struct osi_dev cacheDev;
95 register int code = 0;
99 AFS_STATCNT(igetinode);
101 code = getinode(vfsp, dev, inode, &ip, credp,perror);
105 rw_enter(&ip->i_contents, RW_READER);
107 if (ip->i_mode == 0) {
108 /* Not an allocated inode */
110 rw_exit(&ip->i_contents);
115 if (ip->i_nlink == 0 || (ip->i_mode&IFMT) != IFREG) {
117 rw_exit(&ip->i_contents);
122 /* On VFS40 systems, iput does major synchronous write action, but only
123 when the reference count on the vnode goes to 0. Normally, Sun users
124 don't notice this because the DNLC keep references for them, but we
125 notice 'cause we don't. So, we make a fake dnlc entry which gets
126 cleaned up by iget when it needs the space. */
127 if (dev != cacheDev.dev) {
129 * Don't call dnlc for the cm inodes since it's a big performance
132 dnlc_enter(ITOV(ip), "a", ITOV(ip), (struct AFS_UCRED *) 0);
136 rw_exit(&ip->i_contents);
142 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, rvp, credp)
144 struct AFS_UCRED *credp;
145 long near_inode, param1, param2, param3, param4;
149 struct inode *ip, *newip;
152 struct ufsvfs *ufsvfsp;
154 AFS_STATCNT(afs_syscall_icreate);
156 if (!afs_suser(credp))
159 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
160 * This conversion is needed only for the 64 bit OS.
163 #ifdef AFS_SUN57_64BIT_ENV
164 newdev = expldev( (dev32_t) dev);
169 code = getinode(0, (dev_t)newdev, 2, &ip, credp,&dummy);
174 ufsvfsp = ip->i_ufsvfs;
175 rw_enter(&ip->i_rwlock, RW_WRITER);
176 #if defined(AFS_SUN57_ENV)
177 rw_enter(&ufsvfsp->vfs_dqrwlock, RW_READER);
179 rw_enter(&ip->i_contents, RW_WRITER);
180 code = (*ufs_iallocp)(ip, near_inode, 0, &newip, credp);
181 AFS_ITIMES_NOLOCK(ip);
182 rw_exit(&ip->i_contents);
183 #if defined(AFS_SUN57_ENV)
184 rw_exit(&ufsvfsp->vfs_dqrwlock);
186 rw_exit(&ip->i_rwlock);
192 rw_enter(&newip->i_contents, RW_WRITER);
193 newip->i_flag |= IACC|IUPD|ICHG;
195 #if defined(AFS_SUN56_ENV)
196 newip->i_vicemagic = VICEMAGIC;
202 newip->i_mode = IFREG;
203 newip->i_vnode.v_type = VREG;
205 newip->i_vicep1 = param1;
206 if (param2 == 0x1fffffff/*INODESPECIAL*/) {
207 newip->i_vicep2 = ((0x1fffffff << 3) + (param4 & 0x3));
208 newip->i_vicep3 = param3;
210 newip->i_vicep2 = (((param2 >> 16) & 0x1f) << 27) +
211 (((param4 >> 16) & 0x1f) << 22) +
213 newip->i_vicep3 = ((param4 << 16) + (param2 & 0xffff));
215 #ifdef AFS_SUN57_64BIT_ENV
216 rvp->r_vals = newip->i_number;
218 rvp->r_val1 = newip->i_number;
222 * We're being conservative and sync to the disk
225 (*ufs_iupdatp)(newip, 1);
226 AFS_ITIMES_NOLOCK(newip);
227 rw_exit(&newip->i_contents);
228 VN_RELE(ITOV(newip));
232 afs_syscall_iopen(dev, inode, usrmod, rvp, credp)
234 struct AFS_UCRED *credp;
240 struct vnode *vp = (struct vnode *)0;
246 AFS_STATCNT(afs_syscall_iopen);
248 if (!afs_suser(credp))
251 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
252 * This conversion is needed only for the 64 bit OS.
255 #ifdef AFS_SUN57_64BIT_ENV
256 newdev = expldev( (dev32_t) dev);
261 code = igetinode(0, (dev_t)newdev, (ino_t)inode, &ip, credp,&dummy);
265 code = falloc((struct vnode *)NULL, FWRITE|FREAD, &fp, &fd);
267 rw_enter(&ip->i_contents, RW_READER);
269 rw_exit(&ip->i_contents);
274 /* fp->f_count, f_audit_data are set by falloc */
275 fp->f_vnode = ITOV(ip);
277 fp->f_flag = (usrmod+1) & (FMASK);
279 /* fp->f_count, f_msgcount are set by falloc */
281 /* fp->f_offset zeroed by falloc */
282 /* f_cred set by falloc */
284 * falloc returns the fp write locked
286 mutex_exit(&fp->f_tlock);
288 * XXX We should set the fp to null since we don't need it in the icalls
291 #ifdef AFS_SUN57_64BIT_ENV
302 afs_syscall_iincdec(dev, inode, inode_p1, amount, rvp, credp)
304 struct AFS_UCRED *credp;
305 int inode, inode_p1, amount;
310 register afs_int32 code;
313 if (!afs_suser(credp))
316 /** Code to convert a 32 bit dev_t into a 64 bit dev_t
317 * This conversion is needed only for the 64 bit OS.
320 #ifdef AFS_SUN57_64BIT_ENV
321 newdev = expldev( (dev32_t) dev);
326 code = igetinode(0, (dev_t)newdev, (ino_t)inode, &ip, credp,&dummy);
330 if (!IS_VICEMAGIC(ip)) {
332 rw_enter(&ip->i_contents, RW_READER);
334 rw_exit(&ip->i_contents);
337 rw_enter(&ip->i_contents, RW_WRITER);
338 ip->i_nlink += amount;
339 if (ip->i_nlink == 0) {
340 /* remove the "a" name added by igetinode so that the space is reclaimed. */
341 dnlc_remove(ITOV(ip), "a");
345 /* We may want to force the inode to the disk in case of crashes, other references, etc. */
347 (*ufs_iupdatp)(ip, 1);
348 AFS_ITIMES_NOLOCK(ip);
349 rw_exit(&ip->i_contents);