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