2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
17 #include <sys/errno.h>
18 #include <afs/afs_args.h>
20 #include <sys/ioctl.h>
21 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
29 #ifdef AFS_SGI_XFS_IOPS_ENV
33 #include "afssyscalls.h"
36 FILE *inode_debug_log; /* If set, write to this file. */
37 /* Indices used for database arrays. */
43 static void check_iops(int index, char *fun, char *file, int line);
44 #endif /* AFS_DEBUG_IOPS */
48 * in VRMIX, system calls look just like function calls, so we don't
49 * need to do anything!
53 #if defined(AFS_SGI_ENV)
55 #include <sys/types.h>
56 #endif /* AFS_SGI61_ENV */
58 #pragma weak xicreate = icreate
59 #pragma weak xiinc = iinc
60 #pragma weak xidec = idec
61 #pragma weak xiopen = iopen
62 #pragma weak xlsetpag = lsetpag
63 #pragma weak xlpioctl = lpioctl
65 #pragma weak xiread = iread
66 #pragma weak xiwrite = iwrite
70 icreate(int dev, int near_inode, int param1, int param2, int param3,
74 (AFS_ICREATE, dev, near_inode, param1, param2, param3, param4));
78 iopen(int dev, int inode, int usrmod)
80 return (syscall(AFS_IOPEN, dev, inode, usrmod));
84 iinc(int dev, int inode, int inode_p1)
86 return (syscall(AFS_IINC, dev, inode, inode_p1));
90 idec(int dev, int inode, int inode_p1)
92 return (syscall(AFS_IDEC, dev, inode, inode_p1));
96 #ifdef AFS_SGI_XFS_IOPS_ENV
98 icreatename64(int dev, char *partname, int p0, int p1, int p2, int p3)
102 afs_inode_params_t param;
104 /* Use an array so we don't widen the syscall interface. */
110 afs_syscall(AFSCALL_ICREATENAME64, dev, partname,
111 1 + strlen(partname), param, &ino);
113 return (uint64_t) - 1;
118 iopen64(int dev, uint64_t inode, int usrmod)
121 (AFS_IOPEN64, dev, (u_int) ((inode >> 32) & 0xffffffff),
122 (u_int) (inode & 0xffffffff), usrmod));
126 iinc64(int dev, uint64_t inode, int inode_p1)
129 (AFSCALL_IINC64, dev, (u_int) ((inode >> 32) & 0xffffffff),
130 (u_int) (inode & 0xffffffff), inode_p1));
134 idec64(int dev, uint64_t inode, int inode_p1)
137 (AFSCALL_IDEC64, dev, (u_int) ((inode >> 32) & 0xffffffff),
138 (u_int) (inode & 0xffffffff), inode_p1));
142 ilistinode64(int dev, uint64_t inode, void *data, int *datalen)
145 (AFSCALL_ILISTINODE64, dev, (u_int) ((inode >> 32) & 0xffffffff),
146 (u_int) (inode & 0xffffffff), data, datalen));
149 #ifdef AFS_DEBUG_IOPS
151 debug_icreatename64(int dev, char *partname, int p0, int p1, int p2, int p3,
152 char *file, int line)
154 check_iops(CREATE_I, "icreatename64", file, line);
155 return icreatename64(dev, partname, p0, p1, p2, p3);
159 debug_iopen64(int dev, uint64_t inode, int usrmod, char *file, int line)
161 check_iops(OPEN_I, "iopen64", file, line);
162 return iopen64(dev, inode, usrmod);
166 debug_iinc64(int dev, uint64_t inode, int inode_p1, char *file, int line)
168 check_iops(INC_I, "iinc64", file, line);
169 return iinc64(dev, inode, inode_p1);
173 debug_idec64(int dev, uint64_t inode, int inode_p1, char *file, int line)
175 check_iops(DEC_I, "idec64", file, line);
176 return idec64(dev, inode, inode_p1);
179 #endif /* AFS_DEBUG_IOPS */
180 #endif /* AFS_SGI_XFS_IOPS_ENV */
182 #ifdef AFS_SGI_VNODE_GLUE
183 /* flag: 1 = has NUMA, 0 = no NUMA, -1 = kernel decides. */
185 afs_init_kernel_config(int flag)
187 return afs_syscall(AFSCALL_INIT_KERNEL_CONFIG, flag);
192 /* iread and iwrite are deprecated interfaces. Use inode_read and inode_write instead. */
194 iread(int dev, int inode, int inode_p1, unsigned int offset, char *cbuf,
197 return (syscall(AFS_IREAD, dev, inode, inode_p1, offset, cbuf, count));
201 iwrite(int dev, int inode, int inode_p1, unsigned int offset, char *cbuf,
204 return (syscall(AFS_IWRITE, dev, inode, inode_p1, offset, cbuf, count));
211 return (syscall(AFS_SETPAG));
215 lpioctl(char *path, int cmd, char *cmarg, int follow)
217 return (syscall(AFS_PIOCTL, path, cmd, cmarg, follow));
219 #else /* AFS_SGI_ENV */
221 #ifndef AFS_NAMEI_ENV
229 /* This module contains the stubs for all AFS-related kernel calls that use a single common entry (i.e. AFS_SYSCALL system call). Note we ignore SIGSYS signals that are sent when a "nosys" is reached so that kernels that don't support this new entry, will revert back to the original old afs entry; note that in some cases (where EINVAL is normally returned) we'll call the appropriate system call twice (sigh) */
231 /* Also since we're limited to 6 parameters/call, in some calls (icreate,
232 iread, iwrite) we combine some in a structure */
235 icreate(int dev, int near_inode, int param1, int param2, int param3,
239 struct iparam iparams;
241 iparams.param1 = param1;
242 iparams.param2 = param2;
243 iparams.param3 = param3;
244 iparams.param4 = param4;
247 syscall(AFS_SYSCALL, AFSCALL_ICREATE, dev, near_inode, &iparams);
253 iopen(int dev, int inode, int usrmod)
257 errcode = syscall(AFS_SYSCALL, AFSCALL_IOPEN, dev, inode, usrmod);
263 iinc(int dev, int inode, int inode_p1)
267 errcode = syscall(AFS_SYSCALL, AFSCALL_IINC, dev, inode, inode_p1);
273 idec(int dev, int inode, int inode_p1)
277 errcode = syscall(AFS_SYSCALL, AFSCALL_IDEC, dev, inode, inode_p1);
284 iread(int dev, int inode, int inode_p1, unsigned int offset, char *cbuf,
288 struct iparam iparams;
290 iparams.param1 = inode_p1;
291 iparams.param2 = offset;
292 iparams.param3 = (long)cbuf;
293 iparams.param4 = count;
294 errcode = syscall(AFS_SYSCALL, AFSCALL_IREAD, dev, inode, &iparams);
299 iwrite(int dev, int inode, int inode_p1, unsigned int offset, char *cbuf,
303 struct iparam iparams;
305 iparams.param1 = inode_p1;
306 iparams.param2 = offset;
307 iparams.param3 = (long)cbuf;
308 iparams.param4 = count;
310 errcode = syscall(AFS_SYSCALL, AFSCALL_IWRITE, dev, inode, &iparams);
315 #endif /* AFS_NAMEI_ENV */
317 #if defined(AFS_DARWIN80_ENV)
318 int ioctl_afs_syscall(long syscall, long param1, long param2, long param3,
319 long param4, long param5, long param6, int *rval) {
320 struct afssysargs syscall_data;
322 int fd = open(SYSCALL_DEV_FNAME, O_RDWR);
326 syscall_data.syscall = syscall;
327 syscall_data.param1 = param1;
328 syscall_data.param2 = param2;
329 syscall_data.param3 = param3;
330 syscall_data.param4 = param4;
331 syscall_data.param5 = param5;
332 syscall_data.param6 = param6;
334 code = ioctl(fd, VIOC_SYSCALL, &syscall_data);
339 *rval=syscall_data.retval;
343 #if defined(AFS_LINUX20_ENV)
344 int proc_afs_syscall(long syscall, long param1, long param2, long param3,
345 long param4, int *rval) {
346 struct afsprocdata syscall_data;
347 int fd = open(PROC_SYSCALL_FNAME, O_RDWR);
349 fd = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
353 syscall_data.syscall = syscall;
354 syscall_data.param1 = param1;
355 syscall_data.param2 = param2;
356 syscall_data.param3 = param3;
357 syscall_data.param4 = param4;
359 *rval = ioctl(fd, VIOC_SYSCALL, &syscall_data);
372 #if defined(AFS_LINUX20_ENV)
373 rval = proc_afs_syscall(AFSCALL_SETPAG,0,0,0,0,&errcode);
376 errcode = syscall(AFS_SYSCALL, AFSCALL_SETPAG);
377 #elif defined(AFS_DARWIN80_ENV)
378 if (ioctl_afs_syscall(AFSCALL_SETPAG,0,0,0,0,0,0,&errcode))
381 errcode = syscall(AFS_SYSCALL, AFSCALL_SETPAG);
388 lpioctl(char *path, int cmd, char *cmarg, int follow)
392 #if defined(AFS_LINUX20_ENV)
393 rval = proc_afs_syscall(AFSCALL_PIOCTL, (long)path, cmd, (long)cmarg, follow, &errcode);
396 errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow);
397 #elif defined(AFS_DARWIN80_ENV)
398 if (ioctl_afs_syscall(AFSCALL_PIOCTL,(long)path,cmd,(long)cmarg,follow,0,0,&errcode))
401 errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow);
407 #endif /* !AFS_SGI_ENV */
408 #endif /* !AFS_AIX32_ENV */
410 #ifndef AFS_NAMEI_ENV
413 inode_read(afs_int32 dev, Inode inode, afs_int32 inode_p1,
414 unsigned int offset, char *cbuf, unsigned int count)
420 fd = IOPEN(dev, inode, O_RDONLY);
424 code = lseek(fd, offset, SEEK_SET);
425 if (code != offset) {
428 code = read(fd, cbuf, count);
436 inode_write(afs_int32 dev, Inode inode, afs_int32 inode_p1,
437 unsigned int offset, char *cbuf, unsigned int count)
442 fd = IOPEN(dev, inode, O_WRONLY);
446 code = lseek(fd, offset, SEEK_SET);
447 if (code != offset) {
450 code = write(fd, cbuf, count);
459 * returns a static string used to print either 32 or 64 bit inode numbers.
461 #ifdef AFS_64BIT_IOPS_ENV
463 PrintInode(char *s, Inode ino)
466 PrintInode(afs_ino_str_t s, Inode ino)
469 static afs_ino_str_t result;
474 #ifdef AFS_64BIT_IOPS_ENV
475 (void)sprintf((char *)s, "%llu", ino);
477 (void)sprintf((char *)s, "%u", ino);
481 #endif /* AFS_NAMEI_ENV */
484 #ifdef AFS_DEBUG_IOPS
485 #define MAX_FILE_NAME_LENGTH 32
488 char file[MAX_FILE_NAME_LENGTH];
490 int iops_debug_n_avail[MAX_I + 1];
491 int iops_debug_n_used[MAX_I + 1];
492 iops_debug_t *iops_debug[MAX_I + 1];
493 #define IOPS_DEBUG_MALLOC_STEP 64
496 * Returns 1 if first time we've seen this file/line.
497 * Puts file/line in array so we only print the first time we encounter
501 check_iops(int index, char *fun, char *file, int line)
504 int *availp = &iops_debug_n_avail[index];
505 int *usedp = &iops_debug_n_used[index];
506 iops_debug_t *iops = iops_debug[index];
509 if (!inode_debug_log)
514 for (i = 0; i < used; i++) {
515 if (line == iops[i].line) {
516 if (!strncmp(file, iops[i].file, MAX_FILE_NAME_LENGTH)) {
517 /* We've already entered this one. */
524 /* Not found, enter into db. */
525 if (used >= *availp) {
527 avail += IOPS_DEBUG_MALLOC_STEP;
528 if (avail == IOPS_DEBUG_MALLOC_STEP)
530 (iops_debug_t *) malloc(avail * sizeof(iops_debug_t));
533 (iops_debug_t *) realloc(*iops, avail * sizeof(iops_debug_t));
534 if (!iops_debug[index]) {
535 printf("check_iops: Can't %salloc %lu bytes for index %d\n",
536 (avail == IOPS_DEBUG_MALLOC_STEP) ? "m" : "re",
537 avail * sizeof(iops_debug_t), index);
541 iops = iops_debug[index];
543 iops[used].line = line;
544 (void)strncpy(iops[used].file, file, MAX_FILE_NAME_LENGTH);
547 fprintf(inode_debug_log, "%s: file %s, line %d\n", fun, file, line);
548 fflush(inode_debug_log);
550 #endif /* AFS_DEBUG_IOPS */