1 /* Copyright 1998 Transarc Corporation - All Rights Reserved.
5 * Linux module support routines.
8 #include "../afs/param.h"
9 #include "../afs/sysincludes.h"
10 #include "../afs/afsincludes.h"
11 #include "../h/unistd.h" /* For syscall numbers. */
14 #include <linux/module.h>
18 asmlinkage int (*sys_settimeofdayp)(struct timeval *tv, struct timezone *tz);
19 asmlinkage int (*sys_socketcallp)(int call, long *args);
20 asmlinkage int (*sys_killp)(int pid, int signal);
21 asmlinkage int (*sys_setgroupsp)(int gidsetsize, gid_t *grouplist);
23 extern void *sys_call_table[];
24 extern struct file_system_type afs_file_system;
26 static long get_page_offset(void);
28 struct semaphore afs_global_lock = MUTEX;
29 int afs_global_owner = 0;
30 unsigned long afs_linux_page_offset = 0; /* contains the PAGE_OFFSET value */
32 /* Since sys_ni_syscall is not exported, I need to cache it in order to restore
35 static void *afs_ni_syscall = NULL;
39 extern int afs_syscall();
40 extern int afs_xsetgroups();
42 /* obtain PAGE_OFFSET value */
43 afs_linux_page_offset = get_page_offset();
45 if (afs_linux_page_offset == 0) {
46 /* couldn't obtain page offset so can't continue */
47 printf("afs: Unable to obtain PAGE_OFFSET. Exiting..");
51 /* Initialize pointers to kernel syscalls. */
52 sys_settimeofdayp = sys_call_table[__NR_settimeofday];
53 sys_socketcallp = sys_call_table[__NR_socketcall];
54 sys_killp = sys_call_table[__NR_kill];
56 /* setup AFS entry point. */
57 if (sys_call_table[__NR_afs_syscall] == afs_syscall) {
58 printf("AFS syscall entry point already in use!\n");
63 afs_ni_syscall = sys_call_table[__NR_afs_syscall];
64 sys_call_table[__NR_afs_syscall] = afs_syscall;
67 register_filesystem(&afs_file_system);
69 /* Intercept setgroups calls */
70 sys_setgroupsp = sys_call_table[__NR_setgroups];
71 sys_call_table[__NR_setgroups] = afs_xsetgroups;
76 void cleanup_module(void)
78 struct task_struct *t;
80 sys_call_table[__NR_setgroups] = sys_setgroupsp;
81 sys_call_table[__NR_afs_syscall] = afs_ni_syscall;
83 unregister_filesystem(&afs_file_system);
85 osi_linux_free_inode_pages(); /* Invalidate all pages using AFS inodes. */
86 osi_linux_free_afs_memory();
91 static long get_page_offset(void)
93 struct task_struct *p;
95 /* search backward thru the circular list */
96 for(p = current; p; p = p->prev_task)
98 return p->addr_limit.seg;