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
)
410 iops_debug
[index
] = malloc(avail
* sizeof(iops_debug_t
));
412 iops_debug
[index
] = realloc(*iops
, avail
* sizeof(iops_debug_t
));
413 if (!iops_debug
[index
]) {
414 printf("check_iops: Can't %salloc %lu bytes for index %d\n",
415 (avail
== IOPS_DEBUG_MALLOC_STEP
) ? "m" : "re",
416 avail
* sizeof(iops_debug_t
), index
);
420 iops
= iops_debug
[index
];
422 iops
[used
].line
= line
;
423 (void)strncpy(iops
[used
].file
, file
, MAX_FILE_NAME_LENGTH
);
426 fprintf(inode_debug_log
, "%s: file %s, line %d\n", fun
, file
, line
);
427 fflush(inode_debug_log
);
429 #endif /* AFS_DEBUG_IOPS */