Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / afs / FBSD / 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 * FreeBSD 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/queue.h>
25 #include <sys/lock.h>
26 #include <ufs/ufs/dinode.h>
27 #include <ufs/ufs/extattr.h>
28 #include <ufs/ufs/ufsmount.h>
29
30 int
31 getinode(fs, dev, inode, ipp, perror)
32 struct mount *fs;
33 struct inode **ipp;
34 #ifdef AFS_FBSD53_ENV
35 struct cdev *dev;
36 #else
37 dev_t dev;
38 #endif
39 ino_t inode;
40 int *perror;
41 {
42 struct vnode *vp;
43 int code;
44
45 *ipp = 0;
46 *perror = 0;
47 if (!fs) {
48 struct ufsmount *ump;
49 struct mount *mp;
50
51 mtx_lock(&mountlist_mtx);
52 if ((mp = TAILQ_FIRST(&mountlist)) != NULL)
53 do {
54 /*
55 * XXX Also do the test for MFS
56 */
57 #undef m_data
58 #undef m_next
59 if (!strcmp(mp->mnt_stat.f_fstypename, MOUNT_UFS)) {
60 ump = VFSTOUFS(mp);
61 if (ump->um_fs == NULL)
62 break;
63 if (ump->um_dev == dev) {
64 fs = ump->um_mountp;
65 }
66 }
67 mp = TAILQ_NEXT(mp, mnt_list);
68 } while (mp != TAILQ_FIRST(&mountlist));
69 mtx_unlock(&mountlist_mtx);
70 if (!fs)
71 return (ENXIO);
72 }
73 code = VFS_VGET(fs, inode, 0, &vp);
74 if (code != 0) {
75 *perror = BAD_IGET;
76 return code;
77 } else {
78 *ipp = VTOI(vp);
79 return (0);
80 }
81 }
82
83 int
84 igetinode(vfsp, dev, inode, ipp, perror)
85 struct inode **ipp;
86 struct mount *vfsp;
87 #ifdef AFS_FBSD53_ENV
88 struct cdev *dev;
89 #else
90 dev_t dev;
91 #endif
92 ino_t inode;
93 int *perror;
94 {
95 struct inode *ip;
96 int code = 0;
97
98 *perror = 0;
99
100 AFS_STATCNT(igetinode);
101
102 if ((code = getinode(vfsp, dev, inode, &ip, perror)) != 0) {
103 return (code);
104 }
105
106 if (ip->i_mode == 0) {
107 /* Not an allocated inode */
108 vput(ITOV(ip));
109 return (ENOENT);
110 }
111
112 if (ip->i_nlink == 0 || (ip->i_mode & IFMT) != IFREG) {
113 vput(ITOV(ip));
114 return (ENOENT);
115 }
116
117 *ipp = ip;
118 return (0);
119 }
120
121 #if 0
122 /*
123 * icreate system call -- create an inode
124 */
125 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval)
126 long *retval;
127 long dev, near_inode, param1, param2, param3, param4;
128 {
129 int dummy, err = 0;
130 struct inode *ip, *newip;
131 int code;
132 struct vnode *vp;
133
134 AFS_STATCNT(afs_syscall_icreate);
135
136 if (!afs_suser(NULL))
137 return (EPERM);
138
139 code = getinode(0, (dev_t) dev, 2, &ip, &dummy);
140 if (code) {
141 return (ENOENT);
142 }
143 code = ialloc(ip, (ino_t) near_inode, 0, &newip);
144 iput(ip);
145 if (code) {
146 return (code);
147 }
148 IN_LOCK(newip);
149 newip->i_flag |= IACC | IUPD | ICHG;
150
151 newip->i_nlink = 1;
152
153 newip->i_mode = IFREG;
154
155 IN_UNLOCK(newip);
156 vp = ITOV(newip);
157 VN_LOCK(vp);
158 vp->v_type = VREG;
159 VN_UNLOCK(vp);
160
161 /*
162 * if ( !vp->v_object)
163 * {
164 * extern struct vfs_ubcops ufs_ubcops;
165 * extern struct vm_ubc_object* ubc_object_allocate();
166 * struct vm_ubc_object* vop;
167 * vop = ubc_object_allocate(&vp, &ufs_ubcops,
168 * vp->v_mount->m_funnel);
169 * VN_LOCK(vp);
170 * vp->v_object = vop;
171 * VN_UNLOCK(vp);
172 * }
173 */
174
175 IN_LOCK(newip);
176 /* newip->i_flags |= IC_XUID|IC_XGID; */
177 /* newip->i_flags &= ~IC_PROPLIST; */
178 newip->i_vicep1 = param1;
179 if (param2 == 0x1fffffff /*INODESPECIAL*/) {
180 newip->i_vicep2 = ((0x1fffffff << 3) + (param4 & 0x3));
181 newip->i_vicep3a = (u_short) (param3 >> 16);
182 newip->i_vicep3b = (u_short) param3;
183 } else {
184 newip->i_vicep2 =
185 (((param2 >> 16) & 0x1f) << 27) +
186 (((param4 >> 16) & 0x1f) << 22) + (param3 & 0x3fffff);
187 newip->i_vicep3a = (u_short) param4;
188 newip->i_vicep3b = (u_short) param2;
189 }
190 newip->i_vicemagic = VICEMAGIC;
191
192 *retval = newip->i_number;
193 IN_UNLOCK(newip);
194 iput(newip);
195 return (code);
196 }
197
198
199 int
200 afs_syscall_iopen(dev, inode, usrmod, retval)
201 long *retval;
202 int dev, inode, usrmod;
203 {
204 struct file *fp;
205 struct inode *ip;
206 struct vnode *vp = NULL;
207 int dummy;
208 int fd;
209 extern struct fileops vnops;
210 int code;
211
212 AFS_STATCNT(afs_syscall_iopen);
213
214 if (!afs_suser(NULL))
215 return (EPERM);
216
217 code = igetinode(0, (dev_t) dev, (ino_t) inode, &ip, &dummy);
218 if (code) {
219 return (code);
220 }
221 if ((code = falloc(curproc, &fp, &fd)) != 0) {
222 iput(ip);
223 return (code);
224 }
225 IN_UNLOCK(ip);
226
227 /* FreeBSD doesn't do much mp stuff yet :( */
228 /* FP_LOCK(fp); */
229 fp->f_flag = (usrmod) & FMASK;
230 fp->f_type = DTYPE_VNODE;
231 fp->f_ops = &vnops;
232 fp->f_data = (caddr_t) ITOV(ip);
233
234 /* FP_UNLOCK(fp); */
235 return (0);
236 }
237
238
239 /*
240 * Support for iinc() and idec() system calls--increment or decrement
241 * count on inode.
242 * Restricted to super user.
243 * Only VICEMAGIC type inodes.
244 */
245 int
246 afs_syscall_iincdec(dev, inode, inode_p1, amount)
247 int dev, inode, inode_p1, amount;
248 {
249 int dummy;
250 struct inode *ip;
251 int code;
252
253 if (!afs_suser(NULL))
254 return (EPERM);
255
256 code = igetinode(0, (dev_t) dev, (ino_t) inode, &ip, &dummy);
257 if (code) {
258 return (code);
259 }
260 if (!IS_VICEMAGIC(ip)) {
261 return (EPERM);
262 } else if (ip->i_vicep1 != inode_p1) {
263 return (ENXIO);
264 }
265 ip->i_nlink += amount;
266 if (ip->i_nlink == 0) {
267 CLEAR_VICEMAGIC(ip);
268 }
269 ip->i_flag |= ICHG;
270 iput(ip);
271 return (0);
272 }
273 #else
274 int
275 afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval)
276 long *retval;
277 long dev, near_inode, param1, param2, param3, param4;
278 {
279 return EOPNOTSUPP;
280 }
281
282 int
283 afs_syscall_iopen(dev, inode, usrmod, retval)
284 long *retval;
285 int dev, inode, usrmod;
286 {
287 return EOPNOTSUPP;
288 }
289
290 int
291 afs_syscall_iincdec(dev, inode, inode_p1, amount)
292 int dev, inode, inode_p1, amount;
293 {
294 return EOPNOTSUPP;
295 }
296 #endif