AC_CHECK_LINUX_FUNC([i_size_read],
[#include <linux/fs.h>],
[i_size_read(NULL);])
- AC_CHECK_LINUX_FUNC([iget],
- [#include <linux/fs.h>],
- [iget(NULL, NULL);])
AC_CHECK_LINUX_FUNC([kernel_setsockopt],
[#include <linux/net.h>],
[kernel_setsockopt(NULL, 0, 0, NULL, 0);])
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])])
# 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
+}
#include "afs/afs_stats.h" /* afs statistics */
#include <linux/smp_lock.h>
#include <linux/namei.h>
-#if defined(LINUX_USE_FH)
+
+#if defined(HAVE_LINUX_EXPORTFS_H)
#include <linux/exportfs.h>
+#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;
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)
{
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)
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;
}
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).
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)
dput(dp);
+ afs_init_sb_export_ops(afs_cacheSBp);
+
return 0;
}
* 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;
}
} 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 "
# ifdef HAVE_LINUX_COMPLETION_H
# include <linux/completion.h>
# endif
-# if defined(LINUX_USE_FH)
+# if defined(HAVE_LINUX_EXPORTFS_H)
# include <linux/exportfs.h>
# endif
* -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
* 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 */
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);
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;
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 */
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.
*/
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