Remove the RCSID macro
[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     register 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     register 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     register 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 }