4c93e088a1b424fc61a2546b46cae394ba8e1bfc
[openafs.git] / src / afs / HPUX / osi_inode.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /*
11  * HPUX inode operations
12  *
13  * Implements:
14  *
15  */
16 #include <afsconfig.h>
17 #include "afs/param.h"
18
19 RCSID
20     ("$Header$");
21
22 #include "afs/sysincludes.h"    /* Standard vendor system headers */
23 #include "afsincludes.h"        /* Afs-based standard headers */
24 #include "afs/osi_inode.h"
25 #include "afs/afs_stats.h"      /* statistics stuff */
26 #include <sys/mount.h>
27
28
29 static struct inode *
30 getinode(struct vfs *vfsp, dev_t dev, ino_t inode, int *perror)
31 {
32     struct mount *mp = (vfsp ? VFSTOM(vfsp) : 0);
33     struct inode *pip;
34     *perror = 0;
35
36     if (!mp && !(mp = getmp(dev))) {
37         u.u_error = ENXIO;
38         return (NULL);
39     }
40     pip = iget(dev, mp, inode);
41     if (!pip)
42         *perror = BAD_IGET;
43     return (pip);
44 }
45
46 struct inode *
47 igetinode(struct vfs *vfsp, dev_t dev, ino_t inode, int *perror)
48 {
49     struct inode *pip, *ip;
50     extern struct osi_dev cacheDev;
51     register int code = 0;
52
53     *perror = 0;
54     AFS_STATCNT(igetinode);
55     ip = getinode(vfsp, dev, inode, perror);
56     if (ip == NULL) {
57         *perror = BAD_IGET;
58         u.u_error = ENOENT;     /* Well... */
59         return;
60     }
61     if (ip->i_mode == 0) {
62         /* Not an allocated inode */
63         iforget(ip);
64         u.u_error = ENOENT;
65         return;
66     }
67     if (ip->i_nlink == 0 || (ip->i_mode & IFMT) != IFREG) {
68         iput(ip);
69         u.u_error = ENOENT;
70         return;
71     }
72     return ip;
73 }
74
75 iforget(ip)
76      struct inode *ip;
77 {
78     idrop(ip);
79 }
80
81 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4)
82      long dev, near_inode, param1, param2, param3, param4;
83 {
84     int dummy, err = 0;
85     struct inode *ip, *newip;
86
87     AFS_STATCNT(afs_syscall_icreate);
88
89     if (!afs_suser(NULL)) {
90         u.u_error = EPERM;
91         goto out;
92     }
93
94     ip = getinode(0, (dev_t) dev, 2, &dummy);
95     if (ip == NULL) {
96         u.u_error = ENOENT;     /* Well... */
97         goto out;
98     }
99
100     newip = (struct inode *)ialloc(ip, near_inode, 0);
101     iput(ip);
102     if (newip == NULL)
103         goto out;
104
105     newip->i_flag |= IACC | IUPD | ICHG;
106     newip->i_nlink = 1;
107     newip->i_mode = IFREG;
108     newip->i_vnode.v_type = VREG;
109     newip->i_vicemagic = VICEMAGIC;
110     newip->i_vicep1 = param1;
111     newip->i_vicep2 = param2;
112     I_VICE3(newip) = param3;
113     newip->i_vicep4 = param4;
114     u.u_r.r_val1 = newip->i_number;
115
116     iput(newip);
117
118   out:
119     return err;
120 }
121
122 afs_syscall_iopen(dev, inode, usrmod)
123      int dev, inode, usrmod;
124 {
125     struct file *fp;
126     struct inode *ip;
127     struct vnode *vp = NULL;
128     int dummy;
129     extern struct fileops vnodefops;
130     register int code;
131     int fd;
132
133     AFS_STATCNT(afs_syscall_iopen);
134
135     if (!afs_suser(NULL)) {
136         u.u_error = EPERM;
137         goto out;
138     }
139
140     ip = igetinode(0, (dev_t) dev, (ino_t) inode, &dummy);
141     if (u.u_error)
142         goto out;
143     fp = falloc();
144     if (!fp) {
145         iput(ip);
146         goto out;
147     }
148 #ifdef AFS_HPUX1111_ENV
149     fd = u.u_r.r_val1;
150 #endif
151     iunlock(ip);
152
153     fp->f_ops = &vnodefops;
154     vp = ITOV(ip);
155     fp->f_data = (char *)vp;
156     fp->f_type = DTYPE_VNODE;
157     fp->f_flag = (usrmod + 1) & (FMASK);
158
159     /* Obtained from hp kernel sys/vfs_scalls.c: copen().
160      * Otherwise we panic because the v_writecount
161      * goes less than 0 during close.
162      */
163     if ((vp->v_type == VREG) && (fp->f_flag & FWRITE)) {
164         VN_INC_WRITECOUNT(vp);
165     }
166
167     /* fp->f_count, f_msgcount are set by falloc */
168     /* fp->f_offset zeroed by falloc */
169     /* f_cred set by falloc */
170
171     /*
172      * Obtained from hp kernel sys/vfs_scalls.c: copen() does
173      * a PUTF() (defined earlier in the file) before returning,
174      * so we parrot what it does.  If this is not done, then
175      * threaded processes will get EBADF errors when they try
176      * to use the resulting file descriptor (e.g. with lseek()).
177      *
178      * Note: u.u_r.r_val1 is set by ufalloc(), which is
179      * called by falloc(), which is called above.
180      */
181     if (is_multithreaded(u.u_procp)) {
182 #ifndef AFS_HPUX1111_ENV
183         fd = (int)u.u_r.r_val1;
184 #endif
185         putf(fd);
186     }
187
188   out:
189     return;
190 }
191
192 afs_syscall_iincdec(dev, inode, inode_p1, amount)
193      int dev, inode, inode_p1, amount;
194 {
195     int dummy;
196     struct inode *ip;
197     register afs_int32 code;
198
199     if (!afs_suser(NULL)) {
200         u.u_error = EPERM;
201         goto out;
202     }
203
204     ip = igetinode(0, (dev_t) dev, (ino_t) inode, &dummy);
205     if (u.u_error) {
206         goto out;
207     }
208
209     if (!IS_VICEMAGIC(ip))
210         u.u_error = EPERM;
211     else if (ip->i_vicep1 != inode_p1)
212         u.u_error = ENXIO;
213     else {
214         ip->i_nlink += amount;
215         if (ip->i_nlink == 0) {
216             CLEAR_VICEMAGIC(ip);
217         }
218         ip->i_flag |= ICHG;
219     }
220
221     iput(ip);
222
223   out:
224     return;
225 }