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