Commit f46b21d5 authored by Phoebe Buckheister's avatar Phoebe Buckheister 🦎 Committed by Christian Mohrbacher

client: support linux 4.11

(cherry picked from commit 6a16571857a20def9668cd5c34ca6d41753d7943)
parent 25f5b551
......@@ -71,6 +71,7 @@ kernel_version:
- x86_64/linux-4.8
- x86_64/linux-4.9-rc7
- x86_64/linux-4.10
- x86_64/linux-4.11
- x86_64/linux-3.10.0-514.el7
- x86/linux-2.6.30.3
- x86_64/linux-4.8-debian
......
......@@ -66,6 +66,14 @@ check_function() {
_check_function_input "$name" "$signature" "$@" | _marker_if_compiles "$marker"
}
check_header() {
local header=$1
local marker=$2
shift 2
_generate_includes "$header" | _marker_if_compiles "$marker"
}
cd $srctree
check_struct_field \
......@@ -78,6 +86,31 @@ check_function \
KERNEL_HAS_GENERIC_READLINK \
linux/fs.h
check_header \
linux/sched/signal.h \
KERNEL_HAS_SCHED_SIG_H
# older kernels (RHEL5) don't have linux/cred.h
check_header \
linux/cred.h \
KERNEL_HAS_CRED_H
# cryptohash does not include linux/types.h, so the type comparison fails
check_function \
half_md4_transform "__u32 (__u32[4], __u32 const in[8])" \
KERNEL_HAS_HALF_MD4_TRANSFORM \
linux/types.h linux/cryptohash.h
check_function \
vfs_getattr "int (const struct path *, struct kstat *, u32, unsigned int)" \
KERNEL_HAS_STATX \
linux/fs.h
check_function \
kref_read "unsigned int (const struct kref*)" \
KERNEL_HAS_KREF_READ \
linux/kref.h
# we have to communicate with the calling makefile somehow. since we can't really use the return
# code of this script, we'll echo a special string at the end of our output for the caller to
# detect and remove again.
......
......@@ -16,9 +16,16 @@
#include <stdarg.h>
#include <linux/types.h>
#include <linux/stddef.h>
#ifdef KERNEL_HAS_CRED_H
#include <linux/cred.h>
#endif
//#include <linux/compiler.h>
#include <asm/div64.h>
#ifdef KERNEL_HAS_SCHED_SIG_H
#include <linux/sched/signal.h>
#endif
#include <common/FhgfsTypes.h>
#include <os/OsDeps.h>
......
......@@ -110,6 +110,71 @@ uint32_t HashTk_HsiehHash32(const char* data, int len)
return hash;
}
/* half_md4_transform and macros taken from lib/halfmd4.c */
#ifndef KERNEL_HAS_HALF_MD4_TRANSFORM
/* F, G and H are basic MD4 functions: selection, majority, parity */
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
/*
* The generic round function. The application is so specific that
* we don't bother protecting all the arguments with parens, as is generally
* good macro practice, in favor of extra legibility.
* Rotation is separate from addition to prevent recomputation
*/
#define ROUND(f, a, b, c, d, x, s) \
(a += f(b, c, d) + x, a = rol32(a, s))
#define K1 0
#define K2 013240474631UL
#define K3 015666365641UL
/*
* Basic cut-down MD4 transform. Returns only 32 bits of result.
*/
static __u32 half_md4_transform(__u32 buf[4], __u32 const in[8])
{
__u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
/* Round 1 */
ROUND(F, a, b, c, d, in[0] + K1, 3);
ROUND(F, d, a, b, c, in[1] + K1, 7);
ROUND(F, c, d, a, b, in[2] + K1, 11);
ROUND(F, b, c, d, a, in[3] + K1, 19);
ROUND(F, a, b, c, d, in[4] + K1, 3);
ROUND(F, d, a, b, c, in[5] + K1, 7);
ROUND(F, c, d, a, b, in[6] + K1, 11);
ROUND(F, b, c, d, a, in[7] + K1, 19);
/* Round 2 */
ROUND(G, a, b, c, d, in[1] + K2, 3);
ROUND(G, d, a, b, c, in[3] + K2, 5);
ROUND(G, c, d, a, b, in[5] + K2, 9);
ROUND(G, b, c, d, a, in[7] + K2, 13);
ROUND(G, a, b, c, d, in[0] + K2, 3);
ROUND(G, d, a, b, c, in[2] + K2, 5);
ROUND(G, c, d, a, b, in[4] + K2, 9);
ROUND(G, b, c, d, a, in[6] + K2, 13);
/* Round 3 */
ROUND(H, a, b, c, d, in[3] + K3, 3);
ROUND(H, d, a, b, c, in[7] + K3, 9);
ROUND(H, c, d, a, b, in[2] + K3, 11);
ROUND(H, b, c, d, a, in[6] + K3, 15);
ROUND(H, a, b, c, d, in[1] + K3, 3);
ROUND(H, d, a, b, c, in[5] + K3, 9);
ROUND(H, c, d, a, b, in[0] + K3, 11);
ROUND(H, b, c, d, a, in[4] + K3, 15);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
return buf[1]; /* "most hashed" word */
}
#endif
/**
* Do the halfMD4 hash computation.
* Note: OutBuf must be an array of size HashTk_HALFMD4_OUT_BUF_SIZE
......
......@@ -32,13 +32,14 @@ static struct kmem_cache* FhgfsInodeCache = NULL;
static void FhgfsOps_newAttrToInode(struct iattr* iAttr, struct inode* outInode);
static __always_inline int maybeRefreshInode(struct inode* inode, bool whenCacheInvalid,
bool withFileSize)
bool withFileSize, bool force)
{
App* app = FhgfsOps_getApp(inode->i_sb);
Config* cfg = app->cfg;
if(unlikely(!FhgfsOps_getIsRootInited(inode->i_sb) && inode->i_ino == BEEGFS_INODE_ROOT_INO)
|| (!FhgfsInode_isCacheValid(BEEGFS_INODE(inode), inode->i_mode, cfg) && whenCacheInvalid) )
|| (!FhgfsInode_isCacheValid(BEEGFS_INODE(inode), inode->i_mode, cfg) && whenCacheInvalid)
|| unlikely(force))
{
FhgfsIsizeHints iSizeHints;
int refreshRes;
......@@ -101,7 +102,7 @@ struct dentry* FhgfsOps_lookupIntent(struct inode* parentDir, struct dentry* den
(because the kernel doesn't do lookup/revalidate for the root inode) */
{
int refreshRes = maybeRefreshInode(parentDir, true, false);
int refreshRes = maybeRefreshInode(parentDir, true, false, false);
// root permissions might have changed now => recheck permissions
if (!refreshRes)
......@@ -233,8 +234,21 @@ struct dentry* FhgfsOps_lookupIntent(struct inode* parentDir, struct dentry* den
}
#ifdef KERNEL_HAS_STATX
int FhgfsOps_getattr(const struct path* path, struct kstat* kstat, u32 request_mask,
unsigned int query_flags)
{
struct vfsmount* mnt = path->mnt;
struct dentry* dentry = path->dentry;
bool mustQuery = (query_flags & AT_STATX_SYNC_TYPE) == AT_STATX_FORCE_SYNC;
#else
int FhgfsOps_getattr(struct vfsmount* mnt, struct dentry* dentry, struct kstat* kstat)
{
const bool mustQuery = false;
#endif
App* app = FhgfsOps_getApp(dentry->d_sb);
Config* cfg = App_getConfig(app);
const char* logContext = "FhgfsOps_getattr";
......@@ -262,7 +276,7 @@ int FhgfsOps_getattr(struct vfsmount* mnt, struct dentry* dentry, struct kstat*
can never be up-to-date, so that would also be quite useless. */
retVal = maybeRefreshInode(inode,
isRoot || FhgfsInode_getIsFileOpen(fhgfsInode) || refreshOnGetAttr, true);
isRoot || FhgfsInode_getIsFileOpen(fhgfsInode) || refreshOnGetAttr, true, mustQuery);
if(!retVal)
{
......@@ -299,7 +313,7 @@ ssize_t FhgfsOps_listxattr(struct dentry* dentry, char* value, size_t size)
FhgfsInode* fhgfsInode = BEEGFS_INODE(dentry->d_inode);
int refreshRes = maybeRefreshInode(dentry->d_inode, true, false);
int refreshRes = maybeRefreshInode(dentry->d_inode, true, false, false);
if (refreshRes)
return refreshRes;
......@@ -344,7 +358,7 @@ ssize_t FhgfsOps_getxattr(struct inode* inode, const char* name, void* value, si
FhgfsOpsErr remotingRes;
ssize_t resSize;
int refreshRes = maybeRefreshInode(inode, true, false);
int refreshRes = maybeRefreshInode(inode, true, false, false);
if (refreshRes)
return refreshRes;
......@@ -386,7 +400,7 @@ int FhgfsOps_removexattrInode(struct inode* inode, const char* name)
FhgfsInode* fhgfsInode = BEEGFS_INODE(inode);
int refreshRes = maybeRefreshInode(inode, true, false);
int refreshRes = maybeRefreshInode(inode, true, false, false);
if (refreshRes)
return refreshRes;
......@@ -420,7 +434,7 @@ int FhgfsOps_setxattr(struct inode* inode, const char* name, const void* value,
FhgfsInode* fhgfsInode = BEEGFS_INODE(inode);
FhgfsOpsErr remotingRes;
int refreshRes = maybeRefreshInode(inode, true, false);
int refreshRes = maybeRefreshInode(inode, true, false, false);
if (refreshRes)
return refreshRes;
......@@ -451,7 +465,7 @@ struct posix_acl* FhgfsOps_get_acl(struct inode* inode, int type)
FhgfsInode* fhgfsInode = BEEGFS_INODE(inode);
const EntryInfo* entryInfo = FhgfsInode_getEntryInfo(fhgfsInode);
int refreshRes = maybeRefreshInode(inode, true, false);
int refreshRes = maybeRefreshInode(inode, true, false, false);
if (refreshRes)
return ERR_PTR(refreshRes);
......@@ -520,7 +534,7 @@ int FhgfsOps_set_acl(struct inode* inode, struct posix_acl* acl, int type)
FhgfsInode* fhgfsInode = BEEGFS_INODE(inode);
const EntryInfo* entryInfo = FhgfsInode_getEntryInfo(fhgfsInode);
int refreshRes = maybeRefreshInode(inode, true, false);
int refreshRes = maybeRefreshInode(inode, true, false, false);
if (refreshRes)
return refreshRes;
......
......@@ -31,7 +31,12 @@ typedef struct FhgfsInodeComparisonInfo FhgfsInodeComparisonInfo;
unsigned flags);
#endif // KERNEL_HAS_ATOMIC_OPEN
#ifdef KERNEL_HAS_STATX
extern int FhgfsOps_getattr(const struct path* path, struct kstat* kstat, u32 request_mask,
unsigned int query_flags);
#else
extern int FhgfsOps_getattr(struct vfsmount* mnt, struct dentry* dentry, struct kstat* kstat);
#endif
extern int FhgfsOps_setattr(struct dentry* dentry, struct iattr* iattr);
extern ssize_t FhgfsOps_listxattr(struct dentry* dentry, char* value, size_t size);
......
......@@ -162,17 +162,21 @@ Node* NodeStoreEx_referenceNode(NodeStoreEx* this, NumNodeID id)
RWLock_readLock(&this->rwLock); // L O C K
node = NodeTree_find(&this->nodeTree, id);
if(likely(node) )
if (likely(node))
{ // found it
Node_get(node);
// check for unusually high reference count
#ifdef BEEGFS_DEBUG
#ifdef BEEGFS_DEBUG
# ifdef KERNEL_HAS_KREF_READ
if (kref_read(&node->references) > NODESTORE_WARN_REFNUM)
# else
if(atomic_read(&node->references.refcount) > NODESTORE_WARN_REFNUM)
#endif
Logger_logFormatted(log, Log_CRITICAL, __func__,
"WARNING: Lots of references to node (=> leak?): %s %s; ref count: %d",
Node_getNodeTypeStr(node), Node_getID(node), node->references);
#endif // BEEGFS_DEBUG
#endif // BEEGFS_DEBUG
}
RWLock_readUnlock(&this->rwLock); // U N L O C K
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment