From: Marc Dionne Date: Sat, 26 Jun 2010 00:06:08 +0000 (-0400) Subject: Linux: Use filehandles for all 2.6 kernels X-Git-Tag: openafs-devel-1_5_75~59 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=b59af55f80b2339a93ba985d496b2e9052f29b60 Linux: Use filehandles for all 2.6 kernels This generalizes the use of the exportfs API and file handles to open disk cache files for all 2.6 kernels. Code outside of src/afs/LINUX (ex: afsd) can assume that file handles are used for all 2.6 kernels and can use AFS_LINUX26_ENV to check. Within src/afs/LINUX/osi_file.c, NEW_EXPORT_OPS can be used to determine if the old exportfs API (pre 2.6.24) or the new one applies. All traces of the LINUX_USE_FH define are removed. FIXES 127530 Change-Id: I6803101c56981f9f674cef581f7299656723fdf3 Reviewed-on: http://gerrit.openafs.org/2260 Tested-by: Marc Dionne Reviewed-by: Simon Wilkinson Reviewed-by: Derrick Brashear --- diff --git a/acinclude.m4 b/acinclude.m4 index a0bad9e..9cf9d22 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -842,9 +842,6 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) AC_CHECK_LINUX_FUNC([i_size_read], [#include ], [i_size_read(NULL);]) - AC_CHECK_LINUX_FUNC([iget], - [#include ], - [iget(NULL, NULL);]) AC_CHECK_LINUX_FUNC([kernel_setsockopt], [#include ], [kernel_setsockopt(NULL, 0, 0, NULL, 0);]) @@ -872,9 +869,6 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) dnl Consequences - things which get set as a result of the dnl above tests - AS_IF([test "x$ac_cv_linux_func_iget" = "xno"], - [AC_DEFINE([LINUX_USE_FH], 1, - [define to use linux file handles for cache files])]) AS_IF([test "x$ac_cv_linux_func_d_alloc_anon" = "xno"], [AC_DEFINE([AFS_NONFSTRANS], 1, [define to disable the nfs translator])]) diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h index 7088625..2d7382f 100644 --- a/src/afs/LINUX/osi_compat.h +++ b/src/afs/LINUX/osi_compat.h @@ -293,3 +293,52 @@ afs_try_to_freeze(void) { # endif #endif + +#if !defined(NEW_EXPORT_OPS) +extern struct export_operations export_op_default; +#endif + +static inline struct dentry * +afs_get_dentry_from_fh(struct super_block *afs_cacheSBp, afs_dcache_id_t *ainode, + int cache_fh_len, int cache_fh_type, + int (*afs_fh_acceptable)(void *, struct dentry *)) { +#if defined(NEW_EXPORT_OPS) + return afs_cacheSBp->s_export_op->fh_to_dentry(afs_cacheSBp, &ainode->ufs.fh, + cache_fh_len, cache_fh_type); +#else + if (afs_cacheSBp->s_export_op && afs_cacheSBp->s_export_op->decode_fh) + return afs_cacheSBp->s_export_op->decode_fh(afs_cacheSBp, ainode->ufs.raw, + cache_fh_len, cache_fh_type, afs_fh_acceptable, NULL); + else + return export_op_default.decode_fh(afs_cacheSBp, ainode->ufs.raw, + cache_fh_len, cache_fh_type, afs_fh_acceptable, NULL); +#endif +} + +static inline int +afs_get_fh_from_dentry(struct dentry *dp, afs_ufs_dcache_id_t *ainode, int *max_lenp) { + if (dp->d_sb->s_export_op->encode_fh) + return dp->d_sb->s_export_op->encode_fh(dp, &ainode->raw[0], max_lenp, 0); +#if defined(NEW_EXPORT_OPS) + /* If fs doesn't provide an encode_fh method, assume the default INO32 type */ + *max_lenp = sizeof(struct fid)/4; + ainode->fh.i32.ino = dp->d_inode->i_ino; + ainode->fh.i32.gen = dp->d_inode->i_generation; + return FILEID_INO32_GEN; +#else + /* or call the default encoding function for the old API */ + return export_op_default.encode_fh(dp, &ainode->raw[0], max_lenp, 0); +#endif +} + +static inline void +afs_init_sb_export_ops(struct super_block *sb) { +#if !defined(NEW_EXPORT_OPS) + /* + * decode_fh will call this function. If not defined for this FS, make + * sure it points to the default + */ + if (!sb->s_export_op->find_exported_dentry) + sb->s_export_op->find_exported_dentry = find_exported_dentry; +#endif +} diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c index c0c589b..53784ca 100644 --- a/src/afs/LINUX/osi_file.c +++ b/src/afs/LINUX/osi_file.c @@ -17,11 +17,14 @@ #include "afs/afs_stats.h" /* afs statistics */ #include #include -#if defined(LINUX_USE_FH) + +#if defined(HAVE_LINUX_EXPORTFS_H) #include +#endif +#include "osi_compat.h" + int cache_fh_type = -1; int cache_fh_len = -1; -#endif afs_lock_t afs_xosi; /* lock is for tvattr */ extern struct osi_dev cacheDev; @@ -31,6 +34,13 @@ extern struct super_block *afs_cacheSBp; extern struct cred *cache_creds; #endif +/* Old export ops: decode_fh will call back here. Accept any dentry it suggests */ +int +afs_fh_acceptable(void *context, struct dentry *dp) +{ + return 1; +} + struct file * afs_linux_raw_open(afs_dcache_id_t *ainode) { @@ -38,19 +48,11 @@ afs_linux_raw_open(afs_dcache_id_t *ainode) struct dentry *dp = NULL; struct file* filp; -#if !defined(LINUX_USE_FH) - tip = iget(afs_cacheSBp, ainode->ufs); - if (!tip) - osi_Panic("Can't get inode %d\n", (int) ainode->ufs); - - dp = d_alloc_anon(tip); -#else - dp = afs_cacheSBp->s_export_op->fh_to_dentry(afs_cacheSBp, &ainode->ufs.fh, - cache_fh_len, cache_fh_type); + dp = afs_get_dentry_from_fh(afs_cacheSBp, ainode, cache_fh_len, cache_fh_type, + afs_fh_acceptable); if (!dp) osi_Panic("Can't get dentry\n"); tip = dp->d_inode; -#endif tip->i_flags |= S_NOATIME; /* Disable updating access times. */ #if defined(STRUCT_TASK_STRUCT_HAS_CRED) @@ -62,11 +64,7 @@ afs_linux_raw_open(afs_dcache_id_t *ainode) filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR); #endif if (IS_ERR(filp)) -#if defined(LINUX_USE_FH) osi_Panic("Can't open file: %d\n", (int) PTR_ERR(filp)); -#else - osi_Panic("Can't open inode %d\n", (int) ainode->ufs); -#endif return filp; } @@ -102,7 +100,6 @@ osi_UFSOpen(afs_dcache_id_t *ainode) return (void *)afile; } -#if defined(LINUX_USE_FH) /* * Given a dentry, return the file handle as encoded by the filesystem. * We can't assume anything about the length (words, not bytes). @@ -117,34 +114,19 @@ void osi_get_fh(struct dentry *dp, afs_ufs_dcache_id_t *ainode) { max_len = cache_fh_len; else max_len = MAX_FH_LEN; - if (dp->d_sb->s_export_op->encode_fh) { - type = dp->d_sb->s_export_op->encode_fh(dp, &ainode->raw[0], &max_len, 0); - if (type == 255) { - osi_Panic("File handle encoding failed\n"); - } - if (cache_fh_type < 0) - cache_fh_type = type; - if (cache_fh_len < 0) { - cache_fh_len = max_len; - } - if (type != cache_fh_type || max_len != cache_fh_len) { - osi_Panic("Inconsistent file handles within cache\n"); - } - } else { - /* If fs doesn't provide an encode_fh method, assume the default INO32 type */ - if (cache_fh_type < 0) - cache_fh_type = FILEID_INO32_GEN; - if (cache_fh_len < 0) - cache_fh_len = sizeof(struct fid)/4; - ainode->fh.i32.ino = dp->d_inode->i_ino; - ainode->fh.i32.gen = dp->d_inode->i_generation; + type = afs_get_fh_from_dentry(dp, ainode, &max_len); + if (type == 255) { + osi_Panic("File handle encoding failed\n"); + } + if (cache_fh_type < 0) + cache_fh_type = type; + if (cache_fh_len < 0) { + cache_fh_len = max_len; + } + if (type != cache_fh_type || max_len != cache_fh_len) { + osi_Panic("Inconsistent file handles within cache\n"); } } -#else -void osi_get_fh(struct dentry *dp, afs_ufs_dcache_id_t *ainode) { - *ainode = dp->d_inode->i_ino; -} -#endif int afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat) @@ -357,6 +339,8 @@ osi_InitCacheInfo(char *aname) dput(dp); + afs_init_sb_export_ops(afs_cacheSBp); + return 0; } diff --git a/src/afs/afs.h b/src/afs/afs.h index f660464..0168ceb 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -1067,11 +1067,13 @@ typedef char *afs_ufs_dcache_id_t; * the size correctly. */ typedef ino64_t afs_ufs_dcache_id_t; -#elif defined(LINUX_USE_FH) +#elif defined(AFS_LINUX26_ENV) #define MAX_FH_LEN 10 typedef union { - struct fid fh; - __u32 raw[MAX_FH_LEN]; +#if defined(NEW_EXPORT_OPS) + struct fid fh; +#endif + __u32 raw[MAX_FH_LEN]; } afs_ufs_dcache_id_t; extern int cache_fh_type; extern int cache_fh_len; diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 9d2bf48..77dec65 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -2910,7 +2910,7 @@ afs_InitCacheFile(char *afile, ino_t ainode) } } else { /* Add any other 'complex' inode types here ... */ -#if !defined(LINUX_USE_FH) && !defined(AFS_CACHE_VNODE_PATH) +#if !defined(AFS_LINUX26_ENV) && !defined(AFS_CACHE_VNODE_PATH) tdc->f.inode.ufs = ainode; #else osi_Panic("Can't init cache with inode numbers when complex inodes are " diff --git a/src/afs/sysincludes.h b/src/afs/sysincludes.h index 71bfbcf..560ce83 100644 --- a/src/afs/sysincludes.h +++ b/src/afs/sysincludes.h @@ -183,7 +183,7 @@ struct xfs_inode_info { # ifdef HAVE_LINUX_COMPLETION_H # include # endif -# if defined(LINUX_USE_FH) +# if defined(HAVE_LINUX_EXPORTFS_H) # include # endif diff --git a/src/afsd/afsd.c b/src/afsd/afsd.c index 2377c2a..aecec1b 100644 --- a/src/afsd/afsd.c +++ b/src/afsd/afsd.c @@ -325,7 +325,7 @@ int *dir_for_V = NULL; /* Array: dir of each cache file. * -2: file exists in top-level * >=0: file exists in Dxxx */ -#if !defined(AFS_CACHE_VNODE_PATH) && !defined(LINUX_USE_FH) +#if !defined(AFS_CACHE_VNODE_PATH) && !defined(AFS_LINUX26_ENV) AFSD_INO_T *inode_for_V; /* Array of inodes for desired * cache files */ #endif @@ -1017,7 +1017,7 @@ doSweepAFSCache(int *vFilesFound, * file's inode, directory, and bump the number of files found * total and in this directory. */ -#if !defined(AFS_CACHE_VNODE_PATH) && !defined(LINUX_USE_FH) +#if !defined(AFS_CACHE_VNODE_PATH) && !defined(AFS_LINUX26_ENV) inode_for_V[vFileNum] = currp->d_ino; #endif dir_for_V[vFileNum] = dirNum; /* remember this directory */ @@ -1159,7 +1159,7 @@ doSweepAFSCache(int *vFilesFound, vFileNum); else { struct stat statb; -#if !defined(AFS_CACHE_VNODE_PATH) && !defined(LINUX_USE_FH) +#if !defined(AFS_CACHE_VNODE_PATH) && !defined(AFS_LINUX26_ENV) assert(inode_for_V[vFileNum] == (AFSD_INO_T) 0); #endif sprintf(vFilePtr, "D%d/V%d", thisDir, vFileNum); @@ -1172,7 +1172,7 @@ doSweepAFSCache(int *vFilesFound, if (CreateCacheFile(fullpn_VFile, &statb)) printf("%s: Can't create '%s'\n", rn, fullpn_VFile); else { -#if !defined(AFS_CACHE_VNODE_PATH) && !defined(LINUX_USE_FH) +#if !defined(AFS_CACHE_VNODE_PATH) && !defined(AFS_LINUX26_ENV) inode_for_V[vFileNum] = statb.st_ino; #endif dir_for_V[vFileNum] = thisDir; @@ -1275,7 +1275,7 @@ CheckCacheBaseDir(char *dir) if (res != 0) { return "unable to statfs cache base directory"; } -#if !defined(LINUX_USE_FH) +#if !defined(AFS_LINUX26_ENV) if (statfsbuf.f_type == 0x52654973) { /* REISERFS_SUPER_MAGIC */ return "cannot use reiserfs as cache partition"; } else if (statfsbuf.f_type == 0x58465342) { /* XFS_SUPER_MAGIC */ @@ -2103,7 +2103,7 @@ afsd_run(void) cacheStatEntries); } -#if !defined(AFS_CACHE_VNODE_PATH) && !defined(LINUX_USE_FH) +#if !defined(AFS_CACHE_VNODE_PATH) && !defined(AFS_LINUX26_ENV) /* * Create and zero the inode table for the desired cache files. */ @@ -2433,7 +2433,7 @@ afsd_run(void) afsd_call_syscall(AFSOP_CACHEINODE, (afs_uint32) (inode_for_V[currVFile] >> 32), (afs_uint32) (inode_for_V[currVFile] & 0xffffffff)); -#elif !(defined(LINUX_USE_FH) || defined(AFS_CACHE_VNODE_PATH)) +#elif !(defined(AFS_LINUX26_ENV) || defined(AFS_CACHE_VNODE_PATH)) afsd_call_syscall(AFSOP_CACHEINODE, inode_for_V[currVFile]); #else printf