|
Attached is a patch that replaces the afs syscall interface with a magic proc file, as required for linux 2.6 compatibility.
- Jon Curley
Index: acinclude.m4
===================================================================
RCS file: /cvs/openafs/acinclude.m4,v retrieving revision 1.107 diff -u -w -r1.107 acinclude.m4 --- acinclude.m4 27 Apr 2004 19:43:04 -0000 1.107 +++ acinclude.m4 7 May 2004 19:29:08 -0000 @@ -192,8 +192,8 @@ LINUX_SCHED_STRUCT_TASK_STRUCT_HAS_SIGMASK_LOCK LINUX_WHICH_MODULES if test "x$ac_cv_linux_config_modversions" = "xno"; then - AC_MSG_WARN([Cannot determine sys_call_table status. assuming it's exported]) - ac_cv_linux_exports_sys_call_table=yes + AC_MSG_WARN([Cannot determine sys_call_table status. assuming it isn't exported]) + ac_cv_linux_exports_sys_call_table=no if test -f "$LINUX_KERNEL_PATH/include/asm/ia32_unistd.h"; then ac_cv_linux_exports_ia32_sys_call_table=yes fi Index: src/afs/LINUX/osi_misc.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_misc.c,v retrieving revision 1.32 diff -u -w -r1.32 osi_misc.c --- src/afs/LINUX/osi_misc.c 4 May 2004 21:38:15 -0000 1.32 +++ src/afs/LINUX/osi_misc.c 7 May 2004 19:29:18 -0000 @@ -312,6 +312,12 @@ { extern int (*sys_settimeofdayp) (struct timeval * tv, struct timezone * tz); + + // If pointer invalid, time setting doesn't work. + if(!sys_settimeofdayp) { + printf("Warning: SetTime failed because syscall table is not exported.\n"); + return; + } #ifdef AFS_LINUX_64BIT_KERNEL struct timeval tv; AFS_STATCNT(osi_SetTime); Index: src/afs/LINUX/osi_module.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_module.c,v retrieving revision 1.44 diff -u -w -r1.44 osi_module.c --- src/afs/LINUX/osi_module.c 12 Apr 2004 16:04:32 -0000 1.44 +++ src/afs/LINUX/osi_module.c 7 May 2004 19:29:20 -0000 @@ -27,6 +27,7 @@ #endif
#include <linux/module.h> +#include <linux/proc_fs.h> #include <linux/slab.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #include <linux/init.h> @@ -51,7 +52,6 @@ asmlinkage int (*sys_settimeofdayp) (struct timeval * tv, struct timezone * tz); asmlinkage long (*sys_setgroupsp) (int gidsetsize, gid_t * grouplist); - #ifdef EXPORTED_SYS_CALL_TABLE #ifdef AFS_SPARC64_LINUX20_ENV extern unsigned int sys_call_table[]; /* changed to uint because SPARC64 has syscaltable of 32bit items */ @@ -130,6 +130,52 @@ } #endif /* AFS_SPARC64_LINUX20_ENV */
+static int afs_ioctl(struct inode *, struct file *, unsigned int, + unsigned long); + +static struct file_operations afs_syscall_fops = { + .ioctl = afs_ioctl, +}; + +static struct proc_dir_entry *openafs_procfs; + +static int +afsproc_init() +{ + struct proc_dir_entry *entry1; + + openafs_procfs = proc_mkdir(PROC_FSDIRNAME, proc_root_fs); + entry1 = create_proc_entry(PROC_SYSCALL_NAME, 0, openafs_procfs); + + entry1->proc_fops = &afs_syscall_fops; + + entry1->owner = THIS_MODULE; + + return 0; +} + +static void +afsproc_exit() +{ + remove_proc_entry(PROC_SYSCALL_NAME, openafs_procfs); + remove_proc_entry(PROC_FSDIRNAME, proc_root_fs); +} + +static int +afs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + + struct afsprocdata sysargs; + + + if (copy_from_user(&sysargs, (void *)arg, sizeof(struct afsprocdata))) + return -1; + + return afs_syscall(sysargs.syscall, sysargs.param1, + sysargs.param2, sysargs.param3, sysargs.param4); +} + #ifdef AFS_IA64_LINUX20_ENV
asmlinkage long @@ -306,11 +352,15 @@ break; } #else +#ifdef EXPORTED_SYS_OPEN if (ptr[0] == (unsigned long)&sys_exit && ptr[__NR_open - __NR_exit] == (unsigned long)&sys_open) { sys_call_table = ptr - __NR_exit; break; } +#else + break; +#endif #endif #endif #endif @@ -327,8 +377,8 @@ #endif if (!sys_call_table) { printf("Failed to find address of sys_call_table\n"); - return -EIO; - } + sys_settimeofdayp = 0; + } else { printf("Found sys_call_table at %x\n", sys_call_table);
# ifdef AFS_SPARC64_LINUX20_ENV
error cant support this yet. @@ -357,9 +407,9 @@ #ifdef EXPORTED_KALLSYMS_ADDRESS ret = kallsyms_address_to_symbol((unsigned long)&interruptible_sleep_on, - &mod_name, &mod_start, &mod_end, &sec_name, - &sec_start, &sec_end, &sym_name, - &sym_start, &sym_end); + &mod_name, &mod_start, &mod_end, + &sec_name, &sec_start, &sec_end, + &sym_name, &sym_start, &sym_end); ptr = (unsigned long *)sec_start; datalen = (sec_end - sec_start) / sizeof(unsigned long); #else /* EXPORTED_KALLSYMS_ADDRESS */ @@ -382,15 +432,16 @@ #ifdef EXPORTED_KALLSYMS_ADDRESS ret = kallsyms_address_to_symbol((unsigned long)ia32_sys_call_table, - &mod_name, &mod_start, &mod_end, &sec_name, - &sec_start, &sec_end, &sym_name, - &sym_start, &sym_end); + &mod_name, &mod_start, &mod_end, + &sec_name, &sec_start, &sec_end, + &sym_name, &sym_start, &sym_end); if (ret && strcmp(sym_name, "ia32_sys_call_table")) ia32_sys_call_table = 0; #endif /* EXPORTED_KALLSYMS_ADDRESS */ #endif /* EXPORTED_KALLSYMS_SYMBOL */ if (!ia32_sys_call_table) { - printf("Warning: Failed to find address of ia32_sys_call_table\n"); + printf + ("Warning: Failed to find address of ia32_sys_call_table\n"); } else { printf("Found ia32_sys_call_table at %x\n", ia32_sys_call_table); } @@ -443,11 +494,12 @@ POINTER2SYSCALL afs_syscall; } #endif /* AFS_S390_LINUX22_ENV */ - + } osi_Init(); register_filesystem(&afs_fs_type);
/* Intercept setgroups calls */ + if (sys_call_table) { #if defined(AFS_IA64_LINUX20_ENV) sys_setgroupsp = (void *)&sys_setgroups;
@@ -468,8 +520,10 @@ sys_setgroups32p = SYSCALL2POINTER sys_call_table[__NR_setgroups32]; sys_call_table[__NR_setgroups32] = POINTER2SYSCALL afs_xsetgroups32; #ifdef AFS_SPARC64_LINUX20_ENV - sys32_setgroups32p = SYSCALL2POINTER sys_call_table32[__NR_setgroups32]; - sys_call_table32[__NR_setgroups32] = POINTER2SYSCALL afs32_xsetgroups32; + sys32_setgroups32p = + SYSCALL2POINTER sys_call_table32[__NR_setgroups32]; + sys_call_table32[__NR_setgroups32] = + POINTER2SYSCALL afs32_xsetgroups32; #endif /* AFS_SPARC64_LINUX20_ENV */ #endif /* __NR_setgroups32 */ #ifdef AFS_AMD64_LINUX20_ENV @@ -493,8 +547,10 @@ sys_setgroupsp = set_afs_xsetgroups_syscall(afs_xsetgroups); sys32_setgroupsp = set_afs_xsetgroups_syscall32(afs32_xsetgroups); #endif + }
osi_sysctl_init(); + afsproc_init();
return 0; } @@ -510,7 +566,7 @@ struct task_struct *t;
osi_sysctl_clean(); - + if (sys_call_table) { #if defined(AFS_IA64_LINUX20_ENV) sys_call_table[__NR_setgroups - 1024] = POINTER2SYSCALL((struct fptr *)sys_setgroupsp)->ip; @@ -525,7 +581,8 @@
# if defined(__NR_setgroups32)
sys_call_table[__NR_setgroups32] = POINTER2SYSCALL sys_setgroups32p;
# ifdef AFS_SPARC64_LINUX20_ENV
- sys_call_table32[__NR_setgroups32] = POINTER2SYSCALL sys32_setgroups32p; + sys_call_table32[__NR_setgroups32] = + POINTER2SYSCALL sys32_setgroups32p;
# endif # endif
#endif /* AFS_IA64_LINUX20_ENV */ @@ -541,6 +598,7 @@ #endif } #endif + } #ifdef AFS_PPC64_LINUX20_ENV set_afs_syscall(afs_ni_syscall); set_afs_xsetgroups_syscall(sys_setgroupsp); @@ -551,6 +609,7 @@ osi_linux_free_inode_pages(); /* Invalidate all pages using AFS inodes. */ osi_linux_free_afs_memory();
+ afsproc_exit(); return; }
Index: src/afsd/afsd.c
===================================================================
RCS file: /cvs/openafs/src/afsd/afsd.c,v retrieving revision 1.40 diff -u -w -r1.40 afsd.c --- src/afsd/afsd.c 4 Dec 2003 16:10:46 -0000 1.40 +++ src/afsd/afsd.c 7 May 2004 19:29:26 -0000 @@ -2260,12 +2260,15 @@ }
#if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV) + call_syscall(param1, param2, param3, param4, param5, param6, param7) long param1, param2, param3, param4, param5, param6, param7; { int error; #ifdef AFS_LINUX20_ENV long eparm[4]; + struct afsprocdata syscall_data; + int fd = open(PROC_SYSCALL_FNAME,O_RDWR);
eparm[0] = param4; eparm[1] = param5; @@ -2273,11 +2276,22 @@ eparm[3] = param7;
param4 = (long)eparm; -#endif
+ syscall_data.syscall = AFSCALL_CALL; + syscall_data.param1 = param1; + syscall_data.param2 = param2; + syscall_data.param3 = param3; + syscall_data.param4 = param4; + if(fd > 0) { + error = ioctl(fd, VIOC_SYSCALL, &syscall_data); + close(fd); + } + else +#endif error = syscall(AFS_SYSCALL, AFSCALL_CALL, param1, param2, param3, param4, param5, param6, param7); + if (afsd_verbose) printf("SScall(%d, %d, %d)=%d ", AFS_SYSCALL, AFSCALL_CALL, param1, error); Index: src/config/afs_args.h
===================================================================
RCS file: /cvs/openafs/src/config/afs_args.h,v retrieving revision 1.10 diff -u -w -r1.10 afs_args.h --- src/config/afs_args.h 8 Aug 2003 19:55:11 -0000 1.10 +++ src/config/afs_args.h 7 May 2004 19:29:28 -0000 @@ -172,4 +172,25 @@ #define AFS_CLIENT_RETRIEVAL_VERSION 1 /* latest version */ #define AFS_CLIENT_RETRIEVAL_FIRST_EDITION 1 /* first version */
+/* Defines and structures for the AFS proc replacement layer for the original syscall (AFS_SYSCALL) strategy */ + +#ifdef AFS_LINUX20_ENV + +#define PROC_FSDIRNAME "openafs" +#define PROC_SYSCALL_NAME "afs_ioctl" +#define PROC_SYSCALL_FNAME "/proc/fs/openafs/afs_ioctl" +#define VIOC_SYSCALL_TYPE 'C' +#define VIOC_SYSCALL _IOW(VIOC_SYSCALL_TYPE,1,void *) + +struct afsprocdata { + int param4; + int param3; + int param2; + int param1; + int syscall; +}; + +#endif + + #endif /* _AFS_ARGS_H_ */ Index: src/sys/afssyscalls.c
===================================================================
RCS file: /cvs/openafs/src/sys/afssyscalls.c,v retrieving revision 1.7 diff -u -w -r1.7 afssyscalls.c --- src/sys/afssyscalls.c 15 Jul 2003 23:16:54 -0000 1.7 +++ src/sys/afssyscalls.c 7 May 2004 19:29:33 -0000 @@ -17,6 +17,7 @@ #include <sys/errno.h> #include <afs/afs_args.h> #include <sys/file.h> +#include <sys/ioctl.h> #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV) #include <unistd.h> #else @@ -313,21 +314,60 @@
#endif /* AFS_NAMEI_ENV */
+#ifdef AFS_LINUX20_ENV +int proc_afs_syscall(int syscall, int param1, int param2, int param3, + int param4, int *rval) { + struct afsprocdata syscall_data; + int fd = open(PROC_SYSCALL_FNAME, O_RDWR); + + if(fd < 0) + return -1; + + syscall_data.syscall = syscall; + syscall_data.param1 = param1; + syscall_data.param2 = param2; + syscall_data.param3 = param3; + syscall_data.param4 = param4; + + *rval = ioctl(fd, VIOC_SYSCALL, &syscall_data); + + close(fd); + + return 0; +} +#endif + int lsetpag(void) { - int errcode; + int errcode, rval;
+#ifdef AFS_LINUX20_ENV + rval = proc_afs_syscall(AFSCALL_SETPAG,0,0,0,0,&errcode); + + if(rval) + errcode = syscall(AFS_SYSCALL, AFSCALL_SETPAG); +#else errcode = syscall(AFS_SYSCALL, AFSCALL_SETPAG); +#endif + return (errcode); }
int lpioctl(char *path, int cmd, char *cmarg, int follow) { - int errcode; + int errcode, rval; + +#ifdef AFS_LINUX20_ENV + rval = proc_afs_syscall(AFSCALL_PIOCTL, (unsigned int)path, cmd, (unsigned int)cmarg, follow, &errcode);
+ if(rval) errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow); +#else + errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow); +#endif + return (errcode); }
|
|
A few minor patches related to details of the ioctl interface:
- The arguments to afs_syscall are long, not int - The ioctl vnode op should return a negative error code, not -1. - We should return -EINVAL if the ioctl command is not the one we know, so that it is possible to extend this interface later.
-- Jeff
Index: src/afs/LINUX/osi_module.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_module.c,v retrieving revision 1.47 diff -u -r1.47 osi_module.c --- src/afs/LINUX/osi_module.c 10 May 2004 04:39:21 -0000 1.47 +++ src/afs/LINUX/osi_module.c 11 May 2004 20:08:28 -0000 @@ -170,9 +170,10 @@
struct afsprocdata sysargs;
+ if (cmd != VIOC_SYSCALL) return -EINVAL;
if (copy_from_user(&sysargs, (void *)arg, sizeof(struct afsprocdata))) - return -1; + return -EFAULT;
return afs_syscall(sysargs.syscall, sysargs.param1, sysargs.param2, sysargs.param3, sysargs.param4); Index: src/config/afs_args.h
===================================================================
RCS file: /cvs/openafs/src/config/afs_args.h,v retrieving revision 1.11 diff -u -r1.11 afs_args.h --- src/config/afs_args.h 8 May 2004 04:12:28 -0000 1.11 +++ src/config/afs_args.h 11 May 2004 20:08:28 -0000 @@ -183,11 +183,11 @@ #define VIOC_SYSCALL _IOW(VIOC_SYSCALL_TYPE,1,void *)
struct afsprocdata { - int param4; - int param3; - int param2; - int param1; - int syscall; + long param4; + long param3; + long param2; + long param1; + long syscall; };
#endif Index: src/sys/afssyscalls.c
===================================================================
RCS file: /cvs/openafs/src/sys/afssyscalls.c,v retrieving revision 1.8 diff -u -r1.8 afssyscalls.c --- src/sys/afssyscalls.c 8 May 2004 04:12:29 -0000 1.8 +++ src/sys/afssyscalls.c 11 May 2004 20:08:30 -0000 @@ -315,8 +315,8 @@ #endif /* AFS_NAMEI_ENV */
#ifdef AFS_LINUX20_ENV -int proc_afs_syscall(int syscall, int param1, int param2, int param3, - int param4, int *rval) { +int proc_afs_syscall(long syscall, long param1, long param2, long param3, + long param4, int *rval) { struct afsprocdata syscall_data; int fd = open(PROC_SYSCALL_FNAME, O_RDWR);
@@ -360,7 +360,7 @@ int errcode, rval;
#ifdef AFS_LINUX20_ENV - rval = proc_afs_syscall(AFSCALL_PIOCTL, (unsigned int)path, cmd, (unsigned int)cmarg, follow, &errcode); + rval = proc_afs_syscall(AFSCALL_PIOCTL, (long)path, cmd, (long)cmarg, follow, &errcode);
if(rval) errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow);
|