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>
15 #include <afs/afs_args.h>
17 #ifdef AFS_SGI_XFS_IOPS_ENV
18 # include "xfsattrs.h"
20 #include "afssyscalls.h"
23 FILE *inode_debug_log; /* If set, write to this file. */
24 /* Indices used for database arrays. */
30 static void check_iops(int index, char *fun, char *file, int line);
31 #endif /* AFS_DEBUG_IOPS */
35 * in VRMIX, system calls look just like function calls, so we don't
36 * need to do anything!
40 #if defined(AFS_SGI_ENV)
42 #pragma weak xicreate = icreate
43 #pragma weak xiinc = iinc
44 #pragma weak xidec = idec
45 #pragma weak xiopen = iopen
47 #pragma weak xiread = iread
48 #pragma weak xiwrite = iwrite
52 icreate(int dev, int near_inode, int param1, int param2, int param3,
56 (AFS_ICREATE, dev, near_inode, param1, param2, param3, param4));
60 iopen(int dev, int inode, int usrmod)
62 return (syscall(AFS_IOPEN, dev, inode, usrmod));
66 iinc(int dev, int inode, int inode_p1)
68 return (syscall(AFS_IINC, dev, inode, inode_p1));
72 idec(int dev, int inode, int inode_p1)
74 return (syscall(AFS_IDEC, dev, inode, inode_p1));
78 #ifdef AFS_SGI_XFS_IOPS_ENV
80 icreatename64(int dev, char *partname, int p0, int p1, int p2, int p3)
84 afs_inode_params_t param;
86 /* Use an array so we don't widen the syscall interface. */
92 afs_syscall(AFSCALL_ICREATENAME64, dev, partname,
93 1 + strlen(partname), param, &ino);
95 return (uint64_t) - 1;
100 iopen64(int dev, uint64_t inode, int usrmod)
103 (AFS_IOPEN64, dev, (u_int) ((inode >> 32) & 0xffffffff),
104 (u_int) (inode & 0xffffffff), usrmod));
108 iinc64(int dev, uint64_t inode, int inode_p1)
111 (AFSCALL_IINC64, dev, (u_int) ((inode >> 32) & 0xffffffff),
112 (u_int) (inode & 0xffffffff), inode_p1));
116 idec64(int dev, uint64_t inode, int inode_p1)
119 (AFSCALL_IDEC64, dev, (u_int) ((inode >> 32) & 0xffffffff),
120 (u_int) (inode & 0xffffffff), inode_p1));
124 ilistinode64(int dev, uint64_t inode, void *data, int *datalen)
127 (AFSCALL_ILISTINODE64, dev, (u_int) ((inode >> 32) & 0xffffffff),
128 (u_int) (inode & 0xffffffff), data, datalen));
131 #ifdef AFS_DEBUG_IOPS
133 debug_icreatename64(int dev, char *partname, int p0, int p1, int p2, int p3,
134 char *file, int line)
136 check_iops(CREATE_I, "icreatename64", file, line);
137 return icreatename64(dev, partname, p0, p1, p2, p3);
141 debug_iopen64(int dev, uint64_t inode, int usrmod, char *file, int line)
143 check_iops(OPEN_I, "iopen64", file, line);
144 return iopen64(dev, inode, usrmod);
148 debug_iinc64(int dev, uint64_t inode, int inode_p1, char *file, int line)
150 check_iops(INC_I, "iinc64", file, line);
151 return iinc64(dev, inode, inode_p1);
155 debug_idec64(int dev, uint64_t inode, int inode_p1, char *file, int line)
157 check_iops(DEC_I, "idec64", file, line);
158 return idec64(dev, inode, inode_p1);
161 #endif /* AFS_DEBUG_IOPS */
162 #endif /* AFS_SGI_XFS_IOPS_ENV */
164 #ifdef AFS_SGI_VNODE_GLUE
165 /* flag: 1 = has NUMA, 0 = no NUMA, -1 = kernel decides. */
167 afs_init_kernel_config(int flag)
169 return afs_syscall(AFSCALL_INIT_KERNEL_CONFIG, flag);
174 /* iread and iwrite are deprecated interfaces. Use inode_read and inode_write instead. */
176 iread(int dev, int inode, int inode_p1, unsigned int offset, char *cbuf,
179 return (syscall(AFS_IREAD, dev, inode, inode_p1, offset, cbuf, count));
183 iwrite(int dev, int inode, int inode_p1, unsigned int offset, char *cbuf,
186 return (syscall(AFS_IWRITE, dev, inode, inode_p1, offset, cbuf, count));
190 #else /* AFS_SGI_ENV */
192 #ifndef AFS_NAMEI_ENV
200 /* 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) */
202 /* Also since we're limited to 6 parameters/call, in some calls (icreate,
203 iread, iwrite) we combine some in a structure */
206 icreate(int dev, int near_inode, int param1, int param2, int param3,
210 struct iparam iparams;
212 iparams.param1 = param1;
213 iparams.param2 = param2;
214 iparams.param3 = param3;
215 iparams.param4 = param4;
218 syscall(AFS_SYSCALL, AFSCALL_ICREATE, dev, near_inode, &iparams);
224 iopen(int dev, int inode, int usrmod)
228 errcode = syscall(AFS_SYSCALL, AFSCALL_IOPEN, dev, inode, usrmod);
234 iinc(int dev, int inode, int inode_p1)
238 errcode = syscall(AFS_SYSCALL, AFSCALL_IINC, dev, inode, inode_p1);
244 idec(int dev, int inode, int inode_p1)
248 errcode = syscall(AFS_SYSCALL, AFSCALL_IDEC, dev, inode, inode_p1);
255 iread(int dev, int inode, int inode_p1, unsigned int offset, char *cbuf,
259 struct iparam iparams;
261 iparams.param1 = inode_p1;
262 iparams.param2 = offset;
263 iparams.param3 = (long)cbuf;
264 iparams.param4 = count;
265 errcode = syscall(AFS_SYSCALL, AFSCALL_IREAD, dev, inode, &iparams);
270 iwrite(int dev, int inode, int inode_p1, unsigned int offset, char *cbuf,
274 struct iparam iparams;
276 iparams.param1 = inode_p1;
277 iparams.param2 = offset;
278 iparams.param3 = (long)cbuf;
279 iparams.param4 = count;
281 errcode = syscall(AFS_SYSCALL, AFSCALL_IWRITE, dev, inode, &iparams);
286 #endif /* AFS_NAMEI_ENV */
288 #endif /* !AFS_SGI_ENV */
289 #endif /* !AFS_AIX32_ENV */
291 #ifndef AFS_NAMEI_ENV
294 inode_read(afs_int32 dev, Inode inode, afs_int32 inode_p1,
295 unsigned int offset, char *cbuf, unsigned int count)
301 fd = IOPEN(dev, inode, O_RDONLY);
305 code = lseek(fd, offset, SEEK_SET);
306 if (code != offset) {
309 code = read(fd, cbuf, count);
317 inode_write(afs_int32 dev, Inode inode, afs_int32 inode_p1,
318 unsigned int offset, char *cbuf, unsigned int count)
323 fd = IOPEN(dev, inode, O_WRONLY);
327 code = lseek(fd, offset, SEEK_SET);
328 if (code != offset) {
331 code = write(fd, cbuf, count);
340 * returns a static string used to print either 32 or 64 bit inode numbers.
342 #ifdef AFS_64BIT_IOPS_ENV
344 PrintInode(char *s, Inode ino)
347 PrintInode(afs_ino_str_t s, Inode ino)
350 static afs_ino_str_t result;
355 #ifdef AFS_64BIT_IOPS_ENV
356 (void)sprintf((char *)s, "%llu", ino);
358 (void)sprintf((char *)s, "%u", ino);
362 #endif /* AFS_NAMEI_ENV */
365 #ifdef AFS_DEBUG_IOPS
366 #define MAX_FILE_NAME_LENGTH 32
369 char file[MAX_FILE_NAME_LENGTH];
371 int iops_debug_n_avail[MAX_I + 1];
372 int iops_debug_n_used[MAX_I + 1];
373 iops_debug_t *iops_debug[MAX_I + 1];
374 #define IOPS_DEBUG_MALLOC_STEP 64
377 * Returns 1 if first time we've seen this file/line.
378 * Puts file/line in array so we only print the first time we encounter
382 check_iops(int index, char *fun, char *file, int line)
385 int *availp = &iops_debug_n_avail[index];
386 int *usedp = &iops_debug_n_used[index];
387 iops_debug_t *iops = iops_debug[index];
390 if (!inode_debug_log)
395 for (i = 0; i < used; i++) {
396 if (line == iops[i].line) {
397 if (!strncmp(file, iops[i].file, MAX_FILE_NAME_LENGTH)) {
398 /* We've already entered this one. */
405 /* Not found, enter into db. */
406 if (used >= *availp) {
408 avail += IOPS_DEBUG_MALLOC_STEP;
409 if (avail == IOPS_DEBUG_MALLOC_STEP)
411 (iops_debug_t *) malloc(avail * sizeof(iops_debug_t));
413 iops_debug[index] = realloc(*iops, avail * sizeof(iops_debug_t));
414 if (!iops_debug[index]) {
415 printf("check_iops: Can't %salloc %lu bytes for index %d\n",
416 (avail == IOPS_DEBUG_MALLOC_STEP) ? "m" : "re",
417 avail * sizeof(iops_debug_t), index);
421 iops = iops_debug[index];
423 iops[used].line = line;
424 (void)strncpy(iops[used].file, file, MAX_FILE_NAME_LENGTH);
427 fprintf(inode_debug_log, "%s: file %s, line %d\n", fun, file, line);
428 fflush(inode_debug_log);
430 #endif /* AFS_DEBUG_IOPS */