staging: add Lustre file system client support

Lustre is the most deployed distributed file system
in the HPC (High Performance Computing) world. The patch
adds its client side support.

The code is not very clean and needs to live in drivers/staging
for some time for continuing cleanup work. See
drivers/staging/lustre/TODO for details.

The code is based on Lustre master commit faefbfc04

commit faefbfc0460bc00f2ee4c1c1c86aa1e39b9eea49
Author: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Date:   Tue Apr 30 23:05:21 2013 +0400

    LU-3244 utils: tunefs.lustre should preserve virgin label

Plus a few under-review patches on Whamcloud gerrit:
3.8 kernel support:
http://review.whamcloud.com/#change,5973
http://review.whamcloud.com/#change,5974
http://review.whamcloud.com/#change,5768
http://review.whamcloud.com/#change,5781
http://review.whamcloud.com/#change,5763
http://review.whamcloud.com/#change,5613
http://review.whamcloud.com/#change,5655

3.9 kernel support:
http://review.whamcloud.com/#change,5898
http://review.whamcloud.com/#change,5899

Kconfig/Kbuild:
http://review.whamcloud.com/#change,4646
http://review.whamcloud.com/#change,4644

libcfs cleanup:
http://review.whamcloud.com/#change,2831
http://review.whamcloud.com/#change,4775
http://review.whamcloud.com/#change,4776
http://review.whamcloud.com/#change,4777
http://review.whamcloud.com/#change,4778
http://review.whamcloud.com/#change,4779
http://review.whamcloud.com/#change,4780

All starting/trailing whitespaces are removed, to match kernel
coding style. Also ran scripts/cleanfile on all lustre source files.

[maked the Kconfig depend on BROKEN as the recent procfs changes causes
this to fail - gregkh]

Signed-off-by: Peng Tao <tao.peng@emc.com>
Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Peng Tao
2013-05-14 13:54:50 -04:00
committed by Greg Kroah-Hartman
parent 2339b79d09
commit d7e09d0397
427 changed files with 258994 additions and 0 deletions
+2
View File
@@ -140,4 +140,6 @@ source "drivers/staging/netlogic/Kconfig"
source "drivers/staging/dwc2/Kconfig"
source "drivers/staging/lustre/Kconfig"
endif # STAGING
+1
View File
@@ -62,3 +62,4 @@ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
obj-$(CONFIG_ZCACHE) += zcache/
obj-$(CONFIG_GOLDFISH) += goldfish/
obj-$(CONFIG_USB_DWC2) += dwc2/
obj-$(CONFIG_LUSTRE_FS) += lustre/
+3
View File
@@ -0,0 +1,3 @@
source "drivers/staging/lustre/lustre/Kconfig"
source "drivers/staging/lustre/lnet/Kconfig"
+4
View File
@@ -0,0 +1,4 @@
subdir-ccflags-y := -I$(src)/include/
obj-$(CONFIG_LUSTRE_FS) += lustre/
obj-$(CONFIG_LNET) += lnet/
+13
View File
@@ -0,0 +1,13 @@
* Possible remaining coding style fix.
* Remove deadcode.
* Seperate client/server functionality. Functions only used by server can be
removed from client.
* Clean up libcfs layer. Ideally we can remove include/linux/libcfs entirely.
* Clean up CLIO layer. Lustre client readahead/writeback control needs to better
suit kernel providings.
* Add documents in Documentation.
* Other minor misc cleanups...
Please send any patches to Greg Kroah-Hartman <greg@kroah.com>, Andreas Dilger
<andreas.dilger@intel.com> and Peng Tao <tao.peng@emc.com>. CCing
hpdd-discuss <hpdd-discuss@lists.01.org> would be great too.
@@ -0,0 +1,111 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*/
#ifndef _LIBCFS_BITMAP_H_
#define _LIBCFS_BITMAP_H_
typedef struct {
int size;
unsigned long data[0];
} cfs_bitmap_t;
#define CFS_BITMAP_SIZE(nbits) \
(((nbits/BITS_PER_LONG)+1)*sizeof(long)+sizeof(cfs_bitmap_t))
static inline
cfs_bitmap_t *CFS_ALLOCATE_BITMAP(int size)
{
cfs_bitmap_t *ptr;
OBD_ALLOC(ptr, CFS_BITMAP_SIZE(size));
if (ptr == NULL)
RETURN(ptr);
ptr->size = size;
RETURN (ptr);
}
#define CFS_FREE_BITMAP(ptr) OBD_FREE(ptr, CFS_BITMAP_SIZE(ptr->size))
static inline
void cfs_bitmap_set(cfs_bitmap_t *bitmap, int nbit)
{
set_bit(nbit, bitmap->data);
}
static inline
void cfs_bitmap_clear(cfs_bitmap_t *bitmap, int nbit)
{
test_and_clear_bit(nbit, bitmap->data);
}
static inline
int cfs_bitmap_check(cfs_bitmap_t *bitmap, int nbit)
{
return test_bit(nbit, bitmap->data);
}
static inline
int cfs_bitmap_test_and_clear(cfs_bitmap_t *bitmap, int nbit)
{
return test_and_clear_bit(nbit, bitmap->data);
}
/* return 0 is bitmap has none set bits */
static inline
int cfs_bitmap_check_empty(cfs_bitmap_t *bitmap)
{
return find_first_bit(bitmap->data, bitmap->size) == bitmap->size;
}
static inline
void cfs_bitmap_copy(cfs_bitmap_t *new, cfs_bitmap_t *old)
{
int newsize;
LASSERT(new->size >= old->size);
newsize = new->size;
memcpy(new, old, CFS_BITMAP_SIZE(old->size));
new->size = newsize;
}
#define cfs_foreach_bit(bitmap, pos) \
for ((pos) = find_first_bit((bitmap)->data, bitmap->size); \
(pos) < (bitmap)->size; \
(pos) = find_next_bit((bitmap)->data, (bitmap)->size, (pos) + 1))
#endif
@@ -0,0 +1,110 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2011, 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* libcfs/include/libcfs/curproc.h
*
* Lustre curproc API declaration
*
* Author: Nikita Danilov <nikita@clusterfs.com>
*/
#ifndef __LIBCFS_CURPROC_H__
#define __LIBCFS_CURPROC_H__
/*
* Portable API to access common characteristics of "current" UNIX process.
*
* Implemented in portals/include/libcfs/<os>/
*/
int cfs_curproc_groups_nr(void);
int current_is_in_group(gid_t group);
void cfs_curproc_groups_dump(gid_t *array, int size);
/*
* Plus, platform-specific constant
*
* CFS_CURPROC_COMM_MAX,
*
* and opaque scalar type
*
* kernel_cap_t
*/
/* check if task is running in compat mode.*/
int current_is_32bit(void);
#define current_pid() (current->pid)
#define current_comm() (current->comm)
int cfs_get_environ(const char *key, char *value, int *val_len);
typedef __u32 cfs_cap_t;
#define CFS_CAP_CHOWN 0
#define CFS_CAP_DAC_OVERRIDE 1
#define CFS_CAP_DAC_READ_SEARCH 2
#define CFS_CAP_FOWNER 3
#define CFS_CAP_FSETID 4
#define CFS_CAP_LINUX_IMMUTABLE 9
#define CFS_CAP_SYS_ADMIN 21
#define CFS_CAP_SYS_BOOT 23
#define CFS_CAP_SYS_RESOURCE 24
#define CFS_CAP_FS_MASK ((1 << CFS_CAP_CHOWN) | \
(1 << CFS_CAP_DAC_OVERRIDE) | \
(1 << CFS_CAP_DAC_READ_SEARCH) | \
(1 << CFS_CAP_FOWNER) | \
(1 << CFS_CAP_FSETID ) | \
(1 << CFS_CAP_LINUX_IMMUTABLE) | \
(1 << CFS_CAP_SYS_ADMIN) | \
(1 << CFS_CAP_SYS_BOOT) | \
(1 << CFS_CAP_SYS_RESOURCE))
void cfs_cap_raise(cfs_cap_t cap);
void cfs_cap_lower(cfs_cap_t cap);
int cfs_cap_raised(cfs_cap_t cap);
cfs_cap_t cfs_curproc_cap_pack(void);
void cfs_curproc_cap_unpack(cfs_cap_t cap);
int cfs_capable(cfs_cap_t cap);
/* __LIBCFS_CURPROC_H__ */
#endif
/*
* Local variables:
* c-indentation-style: "K&R"
* c-basic-offset: 8
* tab-width: 8
* fill-column: 80
* scroll-step: 1
* End:
*/
@@ -0,0 +1,286 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2011, 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*/
#ifndef __LIBCFS_LIBCFS_H__
#define __LIBCFS_LIBCFS_H__
#if !__GNUC__
#define __attribute__(x)
#endif
#include <linux/libcfs/linux/libcfs.h>
#include "curproc.h"
#ifndef offsetof
# define offsetof(typ,memb) ((long)(long_ptr_t)((char *)&(((typ *)0)->memb)))
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) ((sizeof (a)) / (sizeof ((a)[0])))
#endif
#if !defined(swap)
#define swap(x,y) do { typeof(x) z = x; x = y; y = z; } while (0)
#endif
#if !defined(container_of)
/* given a pointer @ptr to the field @member embedded into type (usually
* struct) @type, return pointer to the embedding instance of @type. */
#define container_of(ptr, type, member) \
((type *)((char *)(ptr)-(char *)(&((type *)0)->member)))
#endif
static inline int __is_po2(unsigned long long val)
{
return !(val & (val - 1));
}
#define IS_PO2(val) __is_po2((unsigned long long)(val))
#define LOWEST_BIT_SET(x) ((x) & ~((x) - 1))
/*
* Lustre Error Checksum: calculates checksum
* of Hex number by XORing each bit.
*/
#define LERRCHKSUM(hexnum) (((hexnum) & 0xf) ^ ((hexnum) >> 4 & 0xf) ^ \
((hexnum) >> 8 & 0xf))
/*
* Some (nomina odiosa sunt) platforms define NULL as naked 0. This confuses
* Lustre RETURN(NULL) macro.
*/
#if defined(NULL)
#undef NULL
#endif
#define NULL ((void *)0)
#define LUSTRE_SRV_LNET_PID LUSTRE_LNET_PID
#include <linux/list.h>
#ifndef cfs_for_each_possible_cpu
# error cfs_for_each_possible_cpu is not supported by kernel!
#endif
/* libcfs tcpip */
int libcfs_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask);
int libcfs_ipif_enumerate(char ***names);
void libcfs_ipif_free_enumeration(char **names, int n);
int libcfs_sock_listen(socket_t **sockp, __u32 ip, int port, int backlog);
int libcfs_sock_accept(socket_t **newsockp, socket_t *sock);
void libcfs_sock_abort_accept(socket_t *sock);
int libcfs_sock_connect(socket_t **sockp, int *fatal,
__u32 local_ip, int local_port,
__u32 peer_ip, int peer_port);
int libcfs_sock_setbuf(socket_t *socket, int txbufsize, int rxbufsize);
int libcfs_sock_getbuf(socket_t *socket, int *txbufsize, int *rxbufsize);
int libcfs_sock_getaddr(socket_t *socket, int remote, __u32 *ip, int *port);
int libcfs_sock_write(socket_t *sock, void *buffer, int nob, int timeout);
int libcfs_sock_read(socket_t *sock, void *buffer, int nob, int timeout);
void libcfs_sock_release(socket_t *sock);
/* libcfs watchdogs */
struct lc_watchdog;
/* Add a watchdog which fires after "time" milliseconds of delay. You have to
* touch it once to enable it. */
struct lc_watchdog *lc_watchdog_add(int time,
void (*cb)(pid_t pid, void *),
void *data);
/* Enables a watchdog and resets its timer. */
void lc_watchdog_touch(struct lc_watchdog *lcw, int timeout);
#define CFS_GET_TIMEOUT(svc) (max_t(int, obd_timeout, \
AT_OFF ? 0 : at_get(&svc->srv_at_estimate)) * \
svc->srv_watchdog_factor)
/* Disable a watchdog; touch it to restart it. */
void lc_watchdog_disable(struct lc_watchdog *lcw);
/* Clean up the watchdog */
void lc_watchdog_delete(struct lc_watchdog *lcw);
/* Dump a debug log */
void lc_watchdog_dumplog(pid_t pid, void *data);
/* need both kernel and user-land acceptor */
#define LNET_ACCEPTOR_MIN_RESERVED_PORT 512
#define LNET_ACCEPTOR_MAX_RESERVED_PORT 1023
/*
* libcfs pseudo device operations
*
* struct psdev_t and
* misc_register() and
* misc_deregister() are declared in
* libcfs/<os>/<os>-prim.h
*
* It's just draft now.
*/
struct cfs_psdev_file {
unsigned long off;
void *private_data;
unsigned long reserved1;
unsigned long reserved2;
};
struct cfs_psdev_ops {
int (*p_open)(unsigned long, void *);
int (*p_close)(unsigned long, void *);
int (*p_read)(struct cfs_psdev_file *, char *, unsigned long);
int (*p_write)(struct cfs_psdev_file *, char *, unsigned long);
int (*p_ioctl)(struct cfs_psdev_file *, unsigned long, void *);
};
/*
* Drop into debugger, if possible. Implementation is provided by platform.
*/
void cfs_enter_debugger(void);
/*
* Defined by platform
*/
int unshare_fs_struct(void);
sigset_t cfs_get_blocked_sigs(void);
sigset_t cfs_block_allsigs(void);
sigset_t cfs_block_sigs(unsigned long sigs);
sigset_t cfs_block_sigsinv(unsigned long sigs);
void cfs_restore_sigs(sigset_t);
int cfs_signal_pending(void);
void cfs_clear_sigpending(void);
int convert_server_error(__u64 ecode);
int convert_client_oflag(int cflag, int *result);
/*
* Stack-tracing filling.
*/
/*
* Platform-dependent data-type to hold stack frames.
*/
struct cfs_stack_trace;
/*
* Fill @trace with current back-trace.
*/
void cfs_stack_trace_fill(struct cfs_stack_trace *trace);
/*
* Return instruction pointer for frame @frame_no. NULL if @frame_no is
* invalid.
*/
void *cfs_stack_trace_frame(struct cfs_stack_trace *trace, int frame_no);
#ifndef O_NOACCESS
#define O_NOACCESS O_NONBLOCK
#endif
/*
* Universal open flags.
*/
#define CFS_O_NOACCESS 0003
#define CFS_O_ACCMODE CFS_O_NOACCESS
#define CFS_O_CREAT 0100
#define CFS_O_EXCL 0200
#define CFS_O_NOCTTY 0400
#define CFS_O_TRUNC 01000
#define CFS_O_APPEND 02000
#define CFS_O_NONBLOCK 04000
#define CFS_O_NDELAY CFS_O_NONBLOCK
#define CFS_O_SYNC 010000
#define CFS_O_ASYNC 020000
#define CFS_O_DIRECT 040000
#define CFS_O_LARGEFILE 0100000
#define CFS_O_DIRECTORY 0200000
#define CFS_O_NOFOLLOW 0400000
#define CFS_O_NOATIME 01000000
/* convert local open flags to universal open flags */
int cfs_oflags2univ(int flags);
/* convert universal open flags to local open flags */
int cfs_univ2oflags(int flags);
/*
* Random number handling
*/
/* returns a random 32-bit integer */
unsigned int cfs_rand(void);
/* seed the generator */
void cfs_srand(unsigned int, unsigned int);
void cfs_get_random_bytes(void *buf, int size);
#include <linux/libcfs/libcfs_debug.h>
#include <linux/libcfs/libcfs_cpu.h>
#include <linux/libcfs/libcfs_private.h>
#include <linux/libcfs/libcfs_ioctl.h>
#include <linux/libcfs/libcfs_prim.h>
#include <linux/libcfs/libcfs_time.h>
#include <linux/libcfs/libcfs_string.h>
#include <linux/libcfs/libcfs_kernelcomm.h>
#include <linux/libcfs/libcfs_workitem.h>
#include <linux/libcfs/libcfs_hash.h>
#include <linux/libcfs/libcfs_heap.h>
#include <linux/libcfs/libcfs_fail.h>
#include <linux/libcfs/params_tree.h>
#include <linux/libcfs/libcfs_crypto.h>
/* container_of depends on "likely" which is defined in libcfs_private.h */
static inline void *__container_of(void *ptr, unsigned long shift)
{
if (unlikely(IS_ERR(ptr) || ptr == NULL))
return ptr;
else
return (char *)ptr - shift;
}
#define container_of0(ptr, type, member) \
((type *)__container_of((void *)(ptr), offsetof(type, member)))
#define SET_BUT_UNUSED(a) do { } while(sizeof(a) - sizeof(a))
#define _LIBCFS_H
#endif /* _LIBCFS_H */
@@ -0,0 +1,214 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 021110-1307, USA
*
* GPL HEADER END
*/
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* libcfs/include/libcfs/libcfs_cpu.h
*
* CPU partition
* . CPU partition is virtual processing unit
*
* . CPU partition can present 1-N cores, or 1-N NUMA nodes,
* in other words, CPU partition is a processors pool.
*
* CPU Partition Table (CPT)
* . a set of CPU partitions
*
* . There are two modes for CPT: CFS_CPU_MODE_NUMA and CFS_CPU_MODE_SMP
*
* . User can specify total number of CPU partitions while creating a
* CPT, ID of CPU partition is always start from 0.
*
* Example: if there are 8 cores on the system, while creating a CPT
* with cpu_npartitions=4:
* core[0, 1] = partition[0], core[2, 3] = partition[1]
* core[4, 5] = partition[2], core[6, 7] = partition[3]
*
* cpu_npartitions=1:
* core[0, 1, ... 7] = partition[0]
*
* . User can also specify CPU partitions by string pattern
*
* Examples: cpu_partitions="0[0,1], 1[2,3]"
* cpu_partitions="N 0[0-3], 1[4-8]"
*
* The first character "N" means following numbers are numa ID
*
* . NUMA allocators, CPU affinity threads are built over CPU partitions,
* instead of HW CPUs or HW nodes.
*
* . By default, Lustre modules should refer to the global cfs_cpt_table,
* instead of accessing HW CPUs directly, so concurrency of Lustre can be
* configured by cpu_npartitions of the global cfs_cpt_table
*
* . If cpu_npartitions=1(all CPUs in one pool), lustre should work the
* same way as 2.2 or earlier versions
*
* Author: liang@whamcloud.com
*/
#ifndef __LIBCFS_CPU_H__
#define __LIBCFS_CPU_H__
#ifndef HAVE_LIBCFS_CPT
typedef unsigned long cpumask_t;
typedef unsigned long nodemask_t;
struct cfs_cpt_table {
/* # of CPU partitions */
int ctb_nparts;
/* cpu mask */
cpumask_t ctb_mask;
/* node mask */
nodemask_t ctb_nodemask;
/* version */
__u64 ctb_version;
};
#endif /* !HAVE_LIBCFS_CPT */
/* any CPU partition */
#define CFS_CPT_ANY (-1)
extern struct cfs_cpt_table *cfs_cpt_table;
/**
* destroy a CPU partition table
*/
void cfs_cpt_table_free(struct cfs_cpt_table *cptab);
/**
* create a cfs_cpt_table with \a ncpt number of partitions
*/
struct cfs_cpt_table *cfs_cpt_table_alloc(unsigned int ncpt);
/**
* print string information of cpt-table
*/
int cfs_cpt_table_print(struct cfs_cpt_table *cptab, char *buf, int len);
/**
* return total number of CPU partitions in \a cptab
*/
int
cfs_cpt_number(struct cfs_cpt_table *cptab);
/**
* return number of HW cores or hypter-threadings in a CPU partition \a cpt
*/
int cfs_cpt_weight(struct cfs_cpt_table *cptab, int cpt);
/**
* is there any online CPU in CPU partition \a cpt
*/
int cfs_cpt_online(struct cfs_cpt_table *cptab, int cpt);
/**
* return cpumask of CPU partition \a cpt
*/
cpumask_t *cfs_cpt_cpumask(struct cfs_cpt_table *cptab, int cpt);
/**
* return nodemask of CPU partition \a cpt
*/
nodemask_t *cfs_cpt_nodemask(struct cfs_cpt_table *cptab, int cpt);
/**
* shadow current HW processor ID to CPU-partition ID of \a cptab
*/
int cfs_cpt_current(struct cfs_cpt_table *cptab, int remap);
/**
* shadow HW processor ID \a CPU to CPU-partition ID by \a cptab
*/
int cfs_cpt_of_cpu(struct cfs_cpt_table *cptab, int cpu);
/**
* bind current thread on a CPU-partition \a cpt of \a cptab
*/
int cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt);
/**
* add \a cpu to CPU partion @cpt of \a cptab, return 1 for success,
* otherwise 0 is returned
*/
int cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu);
/**
* remove \a cpu from CPU partition \a cpt of \a cptab
*/
void cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu);
/**
* add all cpus in \a mask to CPU partition \a cpt
* return 1 if successfully set all CPUs, otherwise return 0
*/
int cfs_cpt_set_cpumask(struct cfs_cpt_table *cptab,
int cpt, cpumask_t *mask);
/**
* remove all cpus in \a mask from CPU partition \a cpt
*/
void cfs_cpt_unset_cpumask(struct cfs_cpt_table *cptab,
int cpt, cpumask_t *mask);
/**
* add all cpus in NUMA node \a node to CPU partition \a cpt
* return 1 if successfully set all CPUs, otherwise return 0
*/
int cfs_cpt_set_node(struct cfs_cpt_table *cptab, int cpt, int node);
/**
* remove all cpus in NUMA node \a node from CPU partition \a cpt
*/
void cfs_cpt_unset_node(struct cfs_cpt_table *cptab, int cpt, int node);
/**
* add all cpus in node mask \a mask to CPU partition \a cpt
* return 1 if successfully set all CPUs, otherwise return 0
*/
int cfs_cpt_set_nodemask(struct cfs_cpt_table *cptab,
int cpt, nodemask_t *mask);
/**
* remove all cpus in node mask \a mask from CPU partition \a cpt
*/
void cfs_cpt_unset_nodemask(struct cfs_cpt_table *cptab,
int cpt, nodemask_t *mask);
/**
* unset all cpus for CPU partition \a cpt
*/
void cfs_cpt_clear(struct cfs_cpt_table *cptab, int cpt);
/**
* convert partition id \a cpt to numa node id, if there are more than one
* nodes in this partition, it might return a different node id each time.
*/
int cfs_cpt_spread_node(struct cfs_cpt_table *cptab, int cpt);
/**
* iterate over all CPU partitions in \a cptab
*/
#define cfs_cpt_for_each(i, cptab) \
for (i = 0; i < cfs_cpt_number(cptab); i++)
#ifndef __read_mostly
# define __read_mostly
#endif
#ifndef ____cacheline_aligned
#define ____cacheline_aligned
#endif
int cfs_cpu_init(void);
void cfs_cpu_fini(void);
#endif /* __LIBCFS_CPU_H__ */
@@ -0,0 +1,201 @@
/* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see http://www.gnu.org/licenses
*
* Please visit http://www.xyratex.com/contact if you need additional
* information or have any questions.
*
* GPL HEADER END
*/
/*
* Copyright 2012 Xyratex Technology Limited
*/
#ifndef _LIBCFS_CRYPTO_H
#define _LIBCFS_CRYPTO_H
struct cfs_crypto_hash_type {
char *cht_name; /**< hash algorithm name, equal to
* format name for crypto api */
unsigned int cht_key; /**< init key by default (vaild for
* 4 bytes context like crc32, adler */
unsigned int cht_size; /**< hash digest size */
};
enum cfs_crypto_hash_alg {
CFS_HASH_ALG_NULL = 0,
CFS_HASH_ALG_ADLER32,
CFS_HASH_ALG_CRC32,
CFS_HASH_ALG_MD5,
CFS_HASH_ALG_SHA1,
CFS_HASH_ALG_SHA256,
CFS_HASH_ALG_SHA384,
CFS_HASH_ALG_SHA512,
CFS_HASH_ALG_CRC32C,
CFS_HASH_ALG_MAX
};
static struct cfs_crypto_hash_type hash_types[] = {
[CFS_HASH_ALG_NULL] = { "null", 0, 0 },
[CFS_HASH_ALG_ADLER32] = { "adler32", 1, 4 },
[CFS_HASH_ALG_CRC32] = { "crc32", ~0, 4 },
[CFS_HASH_ALG_CRC32C] = { "crc32c", ~0, 4 },
[CFS_HASH_ALG_MD5] = { "md5", 0, 16 },
[CFS_HASH_ALG_SHA1] = { "sha1", 0, 20 },
[CFS_HASH_ALG_SHA256] = { "sha256", 0, 32 },
[CFS_HASH_ALG_SHA384] = { "sha384", 0, 48 },
[CFS_HASH_ALG_SHA512] = { "sha512", 0, 64 },
};
/** Return pointer to type of hash for valid hash algorithm identifier */
static inline const struct cfs_crypto_hash_type *
cfs_crypto_hash_type(unsigned char hash_alg)
{
struct cfs_crypto_hash_type *ht;
if (hash_alg < CFS_HASH_ALG_MAX) {
ht = &hash_types[hash_alg];
if (ht->cht_name)
return ht;
}
return NULL;
}
/** Return hash name for valid hash algorithm identifier or "unknown" */
static inline const char *cfs_crypto_hash_name(unsigned char hash_alg)
{
const struct cfs_crypto_hash_type *ht;
ht = cfs_crypto_hash_type(hash_alg);
if (ht)
return ht->cht_name;
else
return "unknown";
}
/** Return digest size for valid algorithm identifier or 0 */
static inline int cfs_crypto_hash_digestsize(unsigned char hash_alg)
{
const struct cfs_crypto_hash_type *ht;
ht = cfs_crypto_hash_type(hash_alg);
if (ht)
return ht->cht_size;
else
return 0;
}
/** Return hash identifier for valid hash algorithm name or 0xFF */
static inline unsigned char cfs_crypto_hash_alg(const char *algname)
{
unsigned char i;
for (i = 0; i < CFS_HASH_ALG_MAX; i++)
if (!strcmp(hash_types[i].cht_name, algname))
break;
return (i == CFS_HASH_ALG_MAX ? 0xFF : i);
}
/** Calculate hash digest for buffer.
* @param alg id of hash algorithm
* @param buf buffer of data
* @param buf_len buffer len
* @param key initial value for algorithm, if it is NULL,
* default initial value should be used.
* @param key_len len of initial value
* @param hash [out] pointer to hash, if it is NULL, hash_len is
* set to valid digest size in bytes, retval -ENOSPC.
* @param hash_len [in,out] size of hash buffer
* @returns status of operation
* @retval -EINVAL if buf, buf_len, hash_len or alg_id is invalid
* @retval -ENODEV if this algorithm is unsupported
* @retval -ENOSPC if pointer to hash is NULL, or hash_len less than
* digest size
* @retval 0 for success
* @retval < 0 other errors from lower layers.
*/
int cfs_crypto_hash_digest(unsigned char alg,
const void *buf, unsigned int buf_len,
unsigned char *key, unsigned int key_len,
unsigned char *hash, unsigned int *hash_len);
/* cfs crypto hash descriptor */
struct cfs_crypto_hash_desc;
/** Allocate and initialize desriptor for hash algorithm.
* @param alg algorithm id
* @param key initial value for algorithm, if it is NULL,
* default initial value should be used.
* @param key_len len of initial value
* @returns pointer to descriptor of hash instance
* @retval ERR_PTR(error) when errors occured.
*/
struct cfs_crypto_hash_desc*
cfs_crypto_hash_init(unsigned char alg,
unsigned char *key, unsigned int key_len);
/** Update digest by part of data.
* @param desc hash descriptor
* @param page data page
* @param offset data offset
* @param len data len
* @returns status of operation
* @retval 0 for success.
*/
int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc,
struct page *page, unsigned int offset,
unsigned int len);
/** Update digest by part of data.
* @param desc hash descriptor
* @param buf pointer to data buffer
* @param buf_len size of data at buffer
* @returns status of operation
* @retval 0 for success.
*/
int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf,
unsigned int buf_len);
/** Finalize hash calculation, copy hash digest to buffer, destroy hash
* descriptor.
* @param desc hash descriptor
* @param hash buffer pointer to store hash digest
* @param hash_len pointer to hash buffer size, if NULL
* destory hash descriptor
* @returns status of operation
* @retval -ENOSPC if hash is NULL, or *hash_len less than
* digest size
* @retval 0 for success
* @retval < 0 other errors from lower layers.
*/
int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc,
unsigned char *hash, unsigned int *hash_len);
/**
* Register crypto hash algorithms
*/
int cfs_crypto_register(void);
/**
* Unregister
*/
void cfs_crypto_unregister(void);
/** Return hash speed in Mbytes per second for valid hash algorithm
* identifier. If test was unsuccessfull -1 would be return.
*/
int cfs_crypto_hash_speed(unsigned char hash_alg);
#endif
@@ -0,0 +1,350 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* libcfs/include/libcfs/libcfs_debug.h
*
* Debug messages and assertions
*
*/
#ifndef __LIBCFS_DEBUG_H__
#define __LIBCFS_DEBUG_H__
/*
* Debugging
*/
extern unsigned int libcfs_subsystem_debug;
extern unsigned int libcfs_stack;
extern unsigned int libcfs_debug;
extern unsigned int libcfs_printk;
extern unsigned int libcfs_console_ratelimit;
extern unsigned int libcfs_watchdog_ratelimit;
extern unsigned int libcfs_console_max_delay;
extern unsigned int libcfs_console_min_delay;
extern unsigned int libcfs_console_backoff;
extern unsigned int libcfs_debug_binary;
extern char libcfs_debug_file_path_arr[PATH_MAX];
int libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys);
int libcfs_debug_str2mask(int *mask, const char *str, int is_subsys);
/* Has there been an LBUG? */
extern unsigned int libcfs_catastrophe;
extern unsigned int libcfs_panic_on_lbug;
/**
* Format for debug message headers
*/
struct ptldebug_header {
__u32 ph_len;
__u32 ph_flags;
__u32 ph_subsys;
__u32 ph_mask;
__u16 ph_cpu_id;
__u16 ph_type;
__u32 ph_sec;
__u64 ph_usec;
__u32 ph_stack;
__u32 ph_pid;
__u32 ph_extern_pid;
__u32 ph_line_num;
} __attribute__((packed));
#define PH_FLAG_FIRST_RECORD 1
/* Debugging subsystems (32 bits, non-overlapping) */
/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */
#define S_UNDEFINED 0x00000001
#define S_MDC 0x00000002
#define S_MDS 0x00000004
#define S_OSC 0x00000008
#define S_OST 0x00000010
#define S_CLASS 0x00000020
#define S_LOG 0x00000040
#define S_LLITE 0x00000080
#define S_RPC 0x00000100
#define S_MGMT 0x00000200
#define S_LNET 0x00000400
#define S_LND 0x00000800 /* ALL LNDs */
#define S_PINGER 0x00001000
#define S_FILTER 0x00002000
/* unused */
#define S_ECHO 0x00008000
#define S_LDLM 0x00010000
#define S_LOV 0x00020000
#define S_LQUOTA 0x00040000
#define S_OSD 0x00080000
/* unused */
/* unused */
/* unused */
#define S_LMV 0x00800000 /* b_new_cmd */
/* unused */
#define S_SEC 0x02000000 /* upcall cache */
#define S_GSS 0x04000000 /* b_new_cmd */
/* unused */
#define S_MGC 0x10000000
#define S_MGS 0x20000000
#define S_FID 0x40000000 /* b_new_cmd */
#define S_FLD 0x80000000 /* b_new_cmd */
/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */
/* Debugging masks (32 bits, non-overlapping) */
/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */
#define D_TRACE 0x00000001 /* ENTRY/EXIT markers */
#define D_INODE 0x00000002
#define D_SUPER 0x00000004
#define D_EXT2 0x00000008 /* anything from ext2_debug */
#define D_MALLOC 0x00000010 /* print malloc, free information */
#define D_CACHE 0x00000020 /* cache-related items */
#define D_INFO 0x00000040 /* general information */
#define D_IOCTL 0x00000080 /* ioctl related information */
#define D_NETERROR 0x00000100 /* network errors */
#define D_NET 0x00000200 /* network communications */
#define D_WARNING 0x00000400 /* CWARN(...) == CDEBUG (D_WARNING, ...) */
#define D_BUFFS 0x00000800
#define D_OTHER 0x00001000
#define D_DENTRY 0x00002000
#define D_NETTRACE 0x00004000
#define D_PAGE 0x00008000 /* bulk page handling */
#define D_DLMTRACE 0x00010000
#define D_ERROR 0x00020000 /* CERROR(...) == CDEBUG (D_ERROR, ...) */
#define D_EMERG 0x00040000 /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
#define D_HA 0x00080000 /* recovery and failover */
#define D_RPCTRACE 0x00100000 /* for distributed debugging */
#define D_VFSTRACE 0x00200000
#define D_READA 0x00400000 /* read-ahead */
#define D_MMAP 0x00800000
#define D_CONFIG 0x01000000
#define D_CONSOLE 0x02000000
#define D_QUOTA 0x04000000
#define D_SEC 0x08000000
#define D_LFSCK 0x10000000 /* For both OI scrub and LFSCK */
/* keep these in sync with lnet/{utils,libcfs}/debug.c */
#define D_HSM D_TRACE
#define D_CANTMASK (D_ERROR | D_EMERG | D_WARNING | D_CONSOLE)
#ifndef DEBUG_SUBSYSTEM
# define DEBUG_SUBSYSTEM S_UNDEFINED
#endif
#define CDEBUG_DEFAULT_MAX_DELAY (cfs_time_seconds(600)) /* jiffies */
#define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */
#define CDEBUG_DEFAULT_BACKOFF 2
typedef struct {
cfs_time_t cdls_next;
unsigned int cdls_delay;
int cdls_count;
} cfs_debug_limit_state_t;
struct libcfs_debug_msg_data {
const char *msg_file;
const char *msg_fn;
int msg_subsys;
int msg_line;
int msg_mask;
cfs_debug_limit_state_t *msg_cdls;
};
#define LIBCFS_DEBUG_MSG_DATA_INIT(data, mask, cdls) \
do { \
(data)->msg_subsys = DEBUG_SUBSYSTEM; \
(data)->msg_file = __FILE__; \
(data)->msg_fn = __FUNCTION__; \
(data)->msg_line = __LINE__; \
(data)->msg_cdls = (cdls); \
(data)->msg_mask = (mask); \
} while (0)
#define LIBCFS_DEBUG_MSG_DATA_DECL(dataname, mask, cdls) \
static struct libcfs_debug_msg_data dataname = { \
.msg_subsys = DEBUG_SUBSYSTEM, \
.msg_file = __FILE__, \
.msg_fn = __FUNCTION__, \
.msg_line = __LINE__, \
.msg_cdls = (cdls) }; \
dataname.msg_mask = (mask);
/**
* Filters out logging messages based on mask and subsystem.
*/
static inline int cfs_cdebug_show(unsigned int mask, unsigned int subsystem)
{
return mask & D_CANTMASK ||
((libcfs_debug & mask) && (libcfs_subsystem_debug & subsystem));
}
#define __CDEBUG(cdls, mask, format, ...) \
do { \
static struct libcfs_debug_msg_data msgdata; \
\
CFS_CHECK_STACK(&msgdata, mask, cdls); \
\
if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \
LIBCFS_DEBUG_MSG_DATA_INIT(&msgdata, mask, cdls); \
libcfs_debug_msg(&msgdata, format, ## __VA_ARGS__); \
} \
} while (0)
#define CDEBUG(mask, format, ...) __CDEBUG(NULL, mask, format, ## __VA_ARGS__)
#define CDEBUG_LIMIT(mask, format, ...) \
do { \
static cfs_debug_limit_state_t cdls; \
\
__CDEBUG(&cdls, mask, format, ## __VA_ARGS__);\
} while (0)
#define CWARN(format, ...) CDEBUG_LIMIT(D_WARNING, format, ## __VA_ARGS__)
#define CERROR(format, ...) CDEBUG_LIMIT(D_ERROR, format, ## __VA_ARGS__)
#define CNETERR(format, a...) CDEBUG_LIMIT(D_NETERROR, format, ## a)
#define CEMERG(format, ...) CDEBUG_LIMIT(D_EMERG, format, ## __VA_ARGS__)
#define LCONSOLE(mask, format, ...) CDEBUG(D_CONSOLE | (mask), format, ## __VA_ARGS__)
#define LCONSOLE_INFO(format, ...) CDEBUG_LIMIT(D_CONSOLE, format, ## __VA_ARGS__)
#define LCONSOLE_WARN(format, ...) CDEBUG_LIMIT(D_CONSOLE | D_WARNING, format, ## __VA_ARGS__)
#define LCONSOLE_ERROR_MSG(errnum, format, ...) CDEBUG_LIMIT(D_CONSOLE | D_ERROR, \
"%x-%x: " format, errnum, LERRCHKSUM(errnum), ## __VA_ARGS__)
#define LCONSOLE_ERROR(format, ...) LCONSOLE_ERROR_MSG(0x00, format, ## __VA_ARGS__)
#define LCONSOLE_EMERG(format, ...) CDEBUG(D_CONSOLE | D_EMERG, format, ## __VA_ARGS__)
void libcfs_log_goto(struct libcfs_debug_msg_data *, const char *, long_ptr_t);
#define GOTO(label, rc) \
do { \
if (cfs_cdebug_show(D_TRACE, DEBUG_SUBSYSTEM)) { \
LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_TRACE, NULL); \
libcfs_log_goto(&msgdata, #label, (long_ptr_t)(rc)); \
} else { \
(void)(rc); \
} \
goto label; \
} while (0)
/*
* if rc == NULL, we need to code as RETURN((void *)NULL), otherwise
* there will be a warning in osx.
*/
#if defined(__GNUC__)
long libcfs_log_return(struct libcfs_debug_msg_data *, long rc);
#if BITS_PER_LONG > 32
#define RETURN(rc) \
do { \
EXIT_NESTING; \
if (cfs_cdebug_show(D_TRACE, DEBUG_SUBSYSTEM)) { \
LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_TRACE, NULL); \
return (typeof(rc))libcfs_log_return(&msgdata, \
(long)(rc)); \
} \
\
return (rc); \
} while (0)
#else /* BITS_PER_LONG == 32 */
/* We need an on-stack variable, because we cannot case a 32-bit pointer
* directly to (long long) without generating a complier warning/error, yet
* casting directly to (long) will truncate 64-bit return values. The log
* values will print as 32-bit values, but they always have been. LU-1436
*/
#define RETURN(rc) \
do { \
EXIT_NESTING; \
if (cfs_cdebug_show(D_TRACE, DEBUG_SUBSYSTEM)) { \
typeof(rc) __rc = (rc); \
LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_TRACE, NULL); \
libcfs_log_return(&msgdata, (long_ptr_t)__rc); \
return __rc; \
} \
\
return (rc); \
} while (0)
#endif /* BITS_PER_LONG > 32 */
#elif defined(_MSC_VER)
#define RETURN(rc) \
do { \
CDEBUG(D_TRACE, "Process leaving.\n"); \
EXIT_NESTING; \
return (rc); \
} while (0)
#else
# error "Unkown compiler"
#endif /* __GNUC__ */
#define ENTRY \
ENTRY_NESTING; \
do { \
CDEBUG(D_TRACE, "Process entered\n"); \
} while (0)
#define EXIT \
do { \
CDEBUG(D_TRACE, "Process leaving\n"); \
EXIT_NESTING; \
} while(0)
#define RETURN_EXIT \
do { \
EXIT; \
return; \
} while (0)
extern int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
const char *format1, ...)
__attribute__ ((format (printf, 2, 3)));
extern int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
const char *format1,
va_list args, const char *format2, ...)
__attribute__ ((format (printf, 4, 5)));
/* other external symbols that tracefile provides: */
extern int cfs_trace_copyin_string(char *knl_buffer, int knl_buffer_nob,
const char *usr_buffer, int usr_buffer_nob);
extern int cfs_trace_copyout_string(char *usr_buffer, int usr_buffer_nob,
const char *knl_buffer, char *append);
#define LIBCFS_DEBUG_FILE_PATH_DEFAULT "/tmp/lustre-log"
#endif /* __LIBCFS_DEBUG_H__ */
@@ -0,0 +1,170 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see http://www.gnu.org/licenses
*
* Please contact Oracle Corporation, Inc., 500 Oracle Parkway, Redwood Shores,
* CA 94065 USA or visit www.oracle.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2011, 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Oracle Corporation, Inc.
*/
#ifndef _LIBCFS_FAIL_H
#define _LIBCFS_FAIL_H
extern unsigned long cfs_fail_loc;
extern unsigned int cfs_fail_val;
extern wait_queue_head_t cfs_race_waitq;
extern int cfs_race_state;
int __cfs_fail_check_set(__u32 id, __u32 value, int set);
int __cfs_fail_timeout_set(__u32 id, __u32 value, int ms, int set);
enum {
CFS_FAIL_LOC_NOSET = 0,
CFS_FAIL_LOC_ORSET = 1,
CFS_FAIL_LOC_RESET = 2,
CFS_FAIL_LOC_VALUE = 3
};
/* Failure injection control */
#define CFS_FAIL_MASK_SYS 0x0000FF00
#define CFS_FAIL_MASK_LOC (0x000000FF | CFS_FAIL_MASK_SYS)
#define CFS_FAILED_BIT 30
/* CFS_FAILED is 0x40000000 */
#define CFS_FAILED (1 << CFS_FAILED_BIT)
#define CFS_FAIL_ONCE_BIT 31
/* CFS_FAIL_ONCE is 0x80000000 */
#define CFS_FAIL_ONCE (1 << CFS_FAIL_ONCE_BIT)
/* The following flags aren't made to be combined */
#define CFS_FAIL_SKIP 0x20000000 /* skip N times then fail */
#define CFS_FAIL_SOME 0x10000000 /* only fail N times */
#define CFS_FAIL_RAND 0x08000000 /* fail 1/N of the times */
#define CFS_FAIL_USR1 0x04000000 /* user flag */
#define CFS_FAIL_PRECHECK(id) (cfs_fail_loc && \
(cfs_fail_loc & CFS_FAIL_MASK_LOC) == \
((id) & CFS_FAIL_MASK_LOC))
static inline int cfs_fail_check_set(__u32 id, __u32 value,
int set, int quiet)
{
int ret = 0;
if (unlikely(CFS_FAIL_PRECHECK(id) &&
(ret = __cfs_fail_check_set(id, value, set)))) {
if (quiet) {
CDEBUG(D_INFO, "*** cfs_fail_loc=%x, val=%u***\n",
id, value);
} else {
LCONSOLE_INFO("*** cfs_fail_loc=%x, val=%u***\n",
id, value);
}
}
return ret;
}
/* If id hit cfs_fail_loc, return 1, otherwise return 0 */
#define CFS_FAIL_CHECK(id) \
cfs_fail_check_set(id, 0, CFS_FAIL_LOC_NOSET, 0)
#define CFS_FAIL_CHECK_QUIET(id) \
cfs_fail_check_set(id, 0, CFS_FAIL_LOC_NOSET, 1)
/* If id hit cfs_fail_loc and cfs_fail_val == (-1 or value) return 1,
* otherwise return 0 */
#define CFS_FAIL_CHECK_VALUE(id, value) \
cfs_fail_check_set(id, value, CFS_FAIL_LOC_VALUE, 0)
#define CFS_FAIL_CHECK_VALUE_QUIET(id, value) \
cfs_fail_check_set(id, value, CFS_FAIL_LOC_VALUE, 1)
/* If id hit cfs_fail_loc, cfs_fail_loc |= value and return 1,
* otherwise return 0 */
#define CFS_FAIL_CHECK_ORSET(id, value) \
cfs_fail_check_set(id, value, CFS_FAIL_LOC_ORSET, 0)
#define CFS_FAIL_CHECK_ORSET_QUIET(id, value) \
cfs_fail_check_set(id, value, CFS_FAIL_LOC_ORSET, 1)
/* If id hit cfs_fail_loc, cfs_fail_loc = value and return 1,
* otherwise return 0 */
#define CFS_FAIL_CHECK_RESET(id, value) \
cfs_fail_check_set(id, value, CFS_FAIL_LOC_RESET, 0)
#define CFS_FAIL_CHECK_RESET_QUIET(id, value) \
cfs_fail_check_set(id, value, CFS_FAIL_LOC_RESET, 1)
static inline int cfs_fail_timeout_set(__u32 id, __u32 value, int ms, int set)
{
if (unlikely(CFS_FAIL_PRECHECK(id)))
return __cfs_fail_timeout_set(id, value, ms, set);
else
return 0;
}
/* If id hit cfs_fail_loc, sleep for seconds or milliseconds */
#define CFS_FAIL_TIMEOUT(id, secs) \
cfs_fail_timeout_set(id, 0, secs * 1000, CFS_FAIL_LOC_NOSET)
#define CFS_FAIL_TIMEOUT_MS(id, ms) \
cfs_fail_timeout_set(id, 0, ms, CFS_FAIL_LOC_NOSET)
/* If id hit cfs_fail_loc, cfs_fail_loc |= value and
* sleep seconds or milliseconds */
#define CFS_FAIL_TIMEOUT_ORSET(id, value, secs) \
cfs_fail_timeout_set(id, value, secs * 1000, CFS_FAIL_LOC_ORSET)
#define CFS_FAIL_TIMEOUT_MS_ORSET(id, value, ms) \
cfs_fail_timeout_set(id, value, ms, CFS_FAIL_LOC_ORSET)
/* The idea here is to synchronise two threads to force a race. The
* first thread that calls this with a matching fail_loc is put to
* sleep. The next thread that calls with the same fail_loc wakes up
* the first and continues. */
static inline void cfs_race(__u32 id)
{
if (CFS_FAIL_PRECHECK(id)) {
if (unlikely(__cfs_fail_check_set(id, 0, CFS_FAIL_LOC_NOSET))) {
int rc;
cfs_race_state = 0;
CERROR("cfs_race id %x sleeping\n", id);
cfs_wait_event_interruptible(cfs_race_waitq,
cfs_race_state != 0, rc);
CERROR("cfs_fail_race id %x awake, rc=%d\n", id, rc);
} else {
CERROR("cfs_fail_race id %x waking\n", id);
cfs_race_state = 1;
wake_up(&cfs_race_waitq);
}
}
}
#define CFS_RACE(id) cfs_race(id)
#endif /* _LIBCFS_FAIL_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,200 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License version 2 for more details. A copy is
* included in the COPYING file that accompanied this code.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* GPL HEADER END
*/
/*
* Copyright (c) 2011 Intel Corporation
*/
/*
* libcfs/include/libcfs/heap.h
*
* Author: Eric Barton <eeb@whamcloud.com>
* Liang Zhen <liang@whamcloud.com>
*/
#ifndef __LIBCFS_HEAP_H__
#define __LIBCFS_HEAP_H__
/** \defgroup heap Binary heap
*
* The binary heap is a scalable data structure created using a binary tree. It
* is capable of maintaining large sets of elements sorted usually by one or
* more element properties, but really based on anything that can be used as a
* binary predicate in order to determine the relevant ordering of any two nodes
* that belong to the set. There is no search operation, rather the intention is
* for the element of the lowest priority which will always be at the root of
* the tree (as this is an implementation of a min-heap) to be removed by users
* for consumption.
*
* Users of the heap should embed a \e cfs_binheap_node_t object instance on
* every object of the set that they wish the binary heap instance to handle,
* and (at a minimum) provide a cfs_binheap_ops_t::hop_compare() implementation
* which is used by the heap as the binary predicate during its internal sorting
* operations.
*
* The current implementation enforces no locking scheme, and so assumes the
* user caters for locking between calls to insert, delete and lookup
* operations. Since the only consumer for the data structure at this point
* are NRS policies, and these operate on a per-CPT basis, binary heap instances
* are tied to a specific CPT.
* @{
*/
/**
* Binary heap node.
*
* Objects of this type are embedded into objects of the ordered set that is to
* be maintained by a \e cfs_binheap_t instance.
*/
typedef struct {
/** Index into the binary tree */
unsigned int chn_index;
} cfs_binheap_node_t;
#define CBH_SHIFT 9
#define CBH_SIZE (1 << CBH_SHIFT) /* # ptrs per level */
#define CBH_MASK (CBH_SIZE - 1)
#define CBH_NOB (CBH_SIZE * sizeof(cfs_binheap_node_t *))
#define CBH_POISON 0xdeadbeef
/**
* Binary heap flags.
*/
enum {
CBH_FLAG_ATOMIC_GROW = 1,
};
struct cfs_binheap;
/**
* Binary heap operations.
*/
typedef struct {
/**
* Called right before inserting a node into the binary heap.
*
* Implementing this operation is optional.
*
* \param[in] h The heap
* \param[in] e The node
*
* \retval 0 success
* \retval != 0 error
*/
int (*hop_enter)(struct cfs_binheap *h,
cfs_binheap_node_t *e);
/**
* Called right after removing a node from the binary heap.
*
* Implementing this operation is optional.
*
* \param[in] h The heap
* \param[in] e The node
*/
void (*hop_exit)(struct cfs_binheap *h,
cfs_binheap_node_t *e);
/**
* A binary predicate which is called during internal heap sorting
* operations, and used in order to determine the relevant ordering of
* two heap nodes.
*
* Implementing this operation is mandatory.
*
* \param[in] a The first heap node
* \param[in] b The second heap node
*
* \retval 0 Node a > node b
* \retval 1 Node a < node b
*
* \see cfs_binheap_bubble()
* \see cfs_biheap_sink()
*/
int (*hop_compare)(cfs_binheap_node_t *a,
cfs_binheap_node_t *b);
} cfs_binheap_ops_t;
/**
* Binary heap object.
*
* Sorts elements of type \e cfs_binheap_node_t
*/
typedef struct cfs_binheap {
/** Triple indirect */
cfs_binheap_node_t ****cbh_elements3;
/** double indirect */
cfs_binheap_node_t ***cbh_elements2;
/** single indirect */
cfs_binheap_node_t **cbh_elements1;
/** # elements referenced */
unsigned int cbh_nelements;
/** high water mark */
unsigned int cbh_hwm;
/** user flags */
unsigned int cbh_flags;
/** operations table */
cfs_binheap_ops_t *cbh_ops;
/** private data */
void *cbh_private;
/** associated CPT table */
struct cfs_cpt_table *cbh_cptab;
/** associated CPT id of this cfs_binheap_t::cbh_cptab */
int cbh_cptid;
} cfs_binheap_t;
void cfs_binheap_destroy(cfs_binheap_t *h);
cfs_binheap_t *cfs_binheap_create(cfs_binheap_ops_t *ops, unsigned int flags,
unsigned count, void *arg,
struct cfs_cpt_table *cptab, int cptid);
cfs_binheap_node_t *cfs_binheap_find(cfs_binheap_t *h, unsigned int idx);
int cfs_binheap_insert(cfs_binheap_t *h, cfs_binheap_node_t *e);
void cfs_binheap_remove(cfs_binheap_t *h, cfs_binheap_node_t *e);
static inline int
cfs_binheap_size(cfs_binheap_t *h)
{
return h->cbh_nelements;
}
static inline int
cfs_binheap_is_empty(cfs_binheap_t *h)
{
return h->cbh_nelements == 0;
}
static inline cfs_binheap_node_t *
cfs_binheap_root(cfs_binheap_t *h)
{
return cfs_binheap_find(h, 0);
}
static inline cfs_binheap_node_t *
cfs_binheap_remove_root(cfs_binheap_t *h)
{
cfs_binheap_node_t *e = cfs_binheap_find(h, 0);
if (e != NULL)
cfs_binheap_remove(h, e);
return e;
}
/** @} heap */
#endif /* __LIBCFS_HEAP_H__ */
@@ -0,0 +1,222 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* libcfs/include/libcfs/libcfs_ioctl.h
*
* Low-level ioctl data structures. Kernel ioctl functions declared here,
* and user space functions are in libcfsutil_ioctl.h.
*
*/
#ifndef __LIBCFS_IOCTL_H__
#define __LIBCFS_IOCTL_H__
#define LIBCFS_IOCTL_VERSION 0x0001000a
struct libcfs_ioctl_data {
__u32 ioc_len;
__u32 ioc_version;
__u64 ioc_nid;
__u64 ioc_u64[1];
__u32 ioc_flags;
__u32 ioc_count;
__u32 ioc_net;
__u32 ioc_u32[7];
__u32 ioc_inllen1;
char *ioc_inlbuf1;
__u32 ioc_inllen2;
char *ioc_inlbuf2;
__u32 ioc_plen1; /* buffers in userspace */
char *ioc_pbuf1;
__u32 ioc_plen2; /* buffers in userspace */
char *ioc_pbuf2;
char ioc_bulk[0];
};
struct libcfs_ioctl_hdr {
__u32 ioc_len;
__u32 ioc_version;
};
struct libcfs_debug_ioctl_data
{
struct libcfs_ioctl_hdr hdr;
unsigned int subs;
unsigned int debug;
};
#define LIBCFS_IOC_INIT(data) \
do { \
memset(&data, 0, sizeof(data)); \
data.ioc_version = LIBCFS_IOCTL_VERSION; \
data.ioc_len = sizeof(data); \
} while (0)
struct libcfs_ioctl_handler {
struct list_head item;
int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_data *data);
};
#define DECLARE_IOCTL_HANDLER(ident, func) \
struct libcfs_ioctl_handler ident = { \
/* .item = */ LIST_HEAD_INIT(ident.item), \
/* .handle_ioctl = */ func \
}
/* FIXME check conflict with lustre_lib.h */
#define LIBCFS_IOC_DEBUG_MASK _IOWR('f', 250, long)
/* ioctls for manipulating snapshots 30- */
#define IOC_LIBCFS_TYPE 'e'
#define IOC_LIBCFS_MIN_NR 30
/* libcfs ioctls */
#define IOC_LIBCFS_PANIC _IOWR('e', 30, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_LWT_CONTROL _IOWR('e', 33, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_LWT_SNAPSHOT _IOWR('e', 34, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_LWT_LOOKUP_STRING _IOWR('e', 35, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_MEMHOG _IOWR('e', 36, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_PING_TEST _IOWR('e', 37, IOCTL_LIBCFS_TYPE)
/* lnet ioctls */
#define IOC_LIBCFS_GET_NI _IOWR('e', 50, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_FAIL_NID _IOWR('e', 51, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_ADD_ROUTE _IOWR('e', 52, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_DEL_ROUTE _IOWR('e', 53, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_GET_ROUTE _IOWR('e', 54, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_NOTIFY_ROUTER _IOWR('e', 55, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_UNCONFIGURE _IOWR('e', 56, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_PORTALS_COMPATIBILITY _IOWR('e', 57, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_LNET_DIST _IOWR('e', 58, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_CONFIGURE _IOWR('e', 59, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_TESTPROTOCOMPAT _IOWR('e', 60, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_PING _IOWR('e', 61, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_DEBUG_PEER _IOWR('e', 62, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_LNETST _IOWR('e', 63, IOCTL_LIBCFS_TYPE)
/* lnd ioctls */
#define IOC_LIBCFS_REGISTER_MYNID _IOWR('e', 70, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_CLOSE_CONNECTION _IOWR('e', 71, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_PUSH_CONNECTION _IOWR('e', 72, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_GET_CONN _IOWR('e', 73, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_DEL_PEER _IOWR('e', 74, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_ADD_PEER _IOWR('e', 75, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_GET_PEER _IOWR('e', 76, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_GET_TXDESC _IOWR('e', 77, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_ADD_INTERFACE _IOWR('e', 78, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_DEL_INTERFACE _IOWR('e', 79, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_GET_INTERFACE _IOWR('e', 80, IOCTL_LIBCFS_TYPE)
#define IOC_LIBCFS_MAX_NR 80
static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data)
{
int len = sizeof(*data);
len += cfs_size_round(data->ioc_inllen1);
len += cfs_size_round(data->ioc_inllen2);
return len;
}
static inline int libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data)
{
if (data->ioc_len > (1<<30)) {
CERROR ("LIBCFS ioctl: ioc_len larger than 1<<30\n");
return 1;
}
if (data->ioc_inllen1 > (1<<30)) {
CERROR ("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n");
return 1;
}
if (data->ioc_inllen2 > (1<<30)) {
CERROR ("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n");
return 1;
}
if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
CERROR ("LIBCFS ioctl: inlbuf1 pointer but 0 length\n");
return 1;
}
if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
CERROR ("LIBCFS ioctl: inlbuf2 pointer but 0 length\n");
return 1;
}
if (data->ioc_pbuf1 && !data->ioc_plen1) {
CERROR ("LIBCFS ioctl: pbuf1 pointer but 0 length\n");
return 1;
}
if (data->ioc_pbuf2 && !data->ioc_plen2) {
CERROR ("LIBCFS ioctl: pbuf2 pointer but 0 length\n");
return 1;
}
if (data->ioc_plen1 && !data->ioc_pbuf1) {
CERROR ("LIBCFS ioctl: plen1 nonzero but no pbuf1 pointer\n");
return 1;
}
if (data->ioc_plen2 && !data->ioc_pbuf2) {
CERROR ("LIBCFS ioctl: plen2 nonzero but no pbuf2 pointer\n");
return 1;
}
if ((__u32)libcfs_ioctl_packlen(data) != data->ioc_len ) {
CERROR ("LIBCFS ioctl: packlen != ioc_len\n");
return 1;
}
if (data->ioc_inllen1 &&
data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') {
CERROR ("LIBCFS ioctl: inlbuf1 not 0 terminated\n");
return 1;
}
if (data->ioc_inllen2 &&
data->ioc_bulk[cfs_size_round(data->ioc_inllen1) +
data->ioc_inllen2 - 1] != '\0') {
CERROR ("LIBCFS ioctl: inlbuf2 not 0 terminated\n");
return 1;
}
return 0;
}
extern int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand);
extern int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand);
extern int libcfs_ioctl_getdata(char *buf, char *end, void *arg);
extern int libcfs_ioctl_popdata(void *arg, void *buf, int size);
#endif /* __LIBCFS_IOCTL_H__ */
@@ -0,0 +1,117 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* Author: Nathan Rutman <nathan.rutman@sun.com>
*
* libcfs/include/libcfs/libcfs_kernelcomm.h
*
* Kernel <-> userspace communication routines.
* The definitions below are used in the kernel and userspace.
*
*/
#ifndef __LIBCFS_KERNELCOMM_H__
#define __LIBCFS_KERNELCOMM_H__
#ifndef __LIBCFS_LIBCFS_H__
#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
#endif
/* KUC message header.
* All current and future KUC messages should use this header.
* To avoid having to include Lustre headers from libcfs, define this here.
*/
struct kuc_hdr {
__u16 kuc_magic;
__u8 kuc_transport; /* Each new Lustre feature should use a different
transport */
__u8 kuc_flags;
__u16 kuc_msgtype; /* Message type or opcode, transport-specific */
__u16 kuc_msglen; /* Including header */
} __attribute__((aligned(sizeof(__u64))));
#define KUC_MAGIC 0x191C /*Lustre9etLinC */
#define KUC_FL_BLOCK 0x01 /* Wait for send */
/* kuc_msgtype values are defined in each transport */
enum kuc_transport_type {
KUC_TRANSPORT_GENERIC = 1,
KUC_TRANSPORT_HSM = 2,
KUC_TRANSPORT_CHANGELOG = 3,
};
enum kuc_generic_message_type {
KUC_MSG_SHUTDOWN = 1,
};
/* prototype for callback function on kuc groups */
typedef int (*libcfs_kkuc_cb_t)(__u32 data, void *cb_arg);
/* KUC Broadcast Groups. This determines which userspace process hears which
* messages. Mutliple transports may be used within a group, or multiple
* groups may use the same transport. Broadcast
* groups need not be used if e.g. a UID is specified instead;
* use group 0 to signify unicast.
*/
#define KUC_GRP_HSM 0x02
#define KUC_GRP_MAX KUC_GRP_HSM
/* Kernel methods */
extern int libcfs_kkuc_msg_put(struct file *fp, void *payload);
extern int libcfs_kkuc_group_put(int group, void *payload);
extern int libcfs_kkuc_group_add(struct file *fp, int uid, int group,
__u32 data);
extern int libcfs_kkuc_group_rem(int uid, int group);
extern int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func,
void *cb_arg);
#define LK_FLG_STOP 0x01
/* kernelcomm control structure, passed from userspace to kernel */
typedef struct lustre_kernelcomm {
__u32 lk_wfd;
__u32 lk_rfd;
__u32 lk_uid;
__u32 lk_group;
__u32 lk_data;
__u32 lk_flags;
} __attribute__((packed)) lustre_kernelcomm;
/* Userspace methods */
extern int libcfs_ukuc_start(lustre_kernelcomm *l, int groups);
extern int libcfs_ukuc_stop(lustre_kernelcomm *l);
extern int libcfs_ukuc_msg_get(lustre_kernelcomm *l, char *buf, int maxsize,
int transport);
#endif /* __LIBCFS_KERNELCOMM_H__ */
@@ -0,0 +1,101 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* libcfs/include/libcfs/libcfs_prim.h
*
* General primitives.
*
*/
#ifndef __LIBCFS_PRIM_H__
#define __LIBCFS_PRIM_H__
#ifndef EXPORT_SYMBOL
# define EXPORT_SYMBOL(s)
#endif
/*
* Schedule
*/
void cfs_pause(cfs_duration_t ticks);
/*
* Timer
*/
typedef void (cfs_timer_func_t)(ulong_ptr_t);
void schedule_timeout_and_set_state(cfs_task_state_t, int64_t);
void init_waitqueue_entry_current(wait_queue_t *link);
int64_t waitq_timedwait(wait_queue_t *, cfs_task_state_t, int64_t);
void waitq_wait(wait_queue_t *, cfs_task_state_t);
void add_wait_queue_exclusive_head(wait_queue_head_t *, wait_queue_t *);
void cfs_init_timer(timer_list_t *t);
void cfs_timer_init(timer_list_t *t, cfs_timer_func_t *func, void *arg);
void cfs_timer_done(timer_list_t *t);
void cfs_timer_arm(timer_list_t *t, cfs_time_t deadline);
void cfs_timer_disarm(timer_list_t *t);
int cfs_timer_is_armed(timer_list_t *t);
cfs_time_t cfs_timer_deadline(timer_list_t *t);
/*
* Memory
*/
#ifndef memory_pressure_get
#define memory_pressure_get() (0)
#endif
#ifndef memory_pressure_set
#define memory_pressure_set() do {} while (0)
#endif
#ifndef memory_pressure_clr
#define memory_pressure_clr() do {} while (0)
#endif
static inline int cfs_memory_pressure_get_and_set(void)
{
int old = memory_pressure_get();
if (!old)
memory_pressure_set();
return old;
}
static inline void cfs_memory_pressure_restore(int old)
{
if (old)
memory_pressure_set();
else
memory_pressure_clr();
return;
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,137 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* libcfs/include/libcfs/libcfs_string.h
*
* Generic string manipulation functions.
*
* Author: Nathan Rutman <nathan.rutman@sun.com>
*/
#ifndef __LIBCFS_STRING_H__
#define __LIBCFS_STRING_H__
/* libcfs_string.c */
/* string comparison ignoring case */
int cfs_strncasecmp(const char *s1, const char *s2, size_t n);
/* Convert a text string to a bitmask */
int cfs_str2mask(const char *str, const char *(*bit2str)(int bit),
int *oldmask, int minmask, int allmask);
/* Allocate space for and copy an existing string.
* Must free with kfree().
*/
char *cfs_strdup(const char *str, u_int32_t flags);
/* safe vsnprintf */
int cfs_vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
/* safe snprintf */
int cfs_snprintf(char *buf, size_t size, const char *fmt, ...);
/* trim leading and trailing space characters */
char *cfs_firststr(char *str, size_t size);
/**
* Structure to represent NULL-less strings.
*/
struct cfs_lstr {
char *ls_str;
int ls_len;
};
/*
* Structure to represent \<range_expr\> token of the syntax.
*/
struct cfs_range_expr {
/*
* Link to cfs_expr_list::el_exprs.
*/
struct list_head re_link;
__u32 re_lo;
__u32 re_hi;
__u32 re_stride;
};
struct cfs_expr_list {
struct list_head el_link;
struct list_head el_exprs;
};
static inline int
cfs_iswhite(char c)
{
switch (c) {
case ' ':
case '\t':
case '\n':
case '\r':
return 1;
default:
break;
}
return 0;
}
char *cfs_trimwhite(char *str);
int cfs_gettok(struct cfs_lstr *next, char delim, struct cfs_lstr *res);
int cfs_str2num_check(char *str, int nob, unsigned *num,
unsigned min, unsigned max);
int cfs_range_expr_parse(struct cfs_lstr *src, unsigned min, unsigned max,
int single_tok, struct cfs_range_expr **expr);
int cfs_expr_list_match(__u32 value, struct cfs_expr_list *expr_list);
int cfs_expr_list_values(struct cfs_expr_list *expr_list,
int max, __u32 **values);
static inline void
cfs_expr_list_values_free(__u32 *values, int num)
{
/* This array is allocated by LIBCFS_ALLOC(), so it shouldn't be freed
* by OBD_FREE() if it's called by module other than libcfs & LNet,
* otherwise we will see fake memory leak */
LIBCFS_FREE(values, num * sizeof(values[0]));
}
void cfs_expr_list_free(struct cfs_expr_list *expr_list);
void cfs_expr_list_print(struct cfs_expr_list *expr_list);
int cfs_expr_list_parse(char *str, int len, unsigned min, unsigned max,
struct cfs_expr_list **elpp);
void cfs_expr_list_free_list(struct list_head *list);
int cfs_ip_addr_parse(char *str, int len, struct list_head *list);
int cfs_ip_addr_match(__u32 addr, struct list_head *list);
void cfs_ip_addr_free(struct list_head *list);
#define strtoul(str, endp, base) simple_strtoul(str, endp, base)
#endif
@@ -0,0 +1,132 @@
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* libcfs/include/libcfs/libcfs_time.h
*
* Time functions.
*
*/
#ifndef __LIBCFS_TIME_H__
#define __LIBCFS_TIME_H__
/*
* generic time manipulation functions.
*/
static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d)
{
return (cfs_time_t)(t + d);
}
static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2)
{
return (cfs_time_t)(t1 - t2);
}
static inline int cfs_time_after(cfs_time_t t1, cfs_time_t t2)
{
return cfs_time_before(t2, t1);
}
static inline int cfs_time_aftereq(cfs_time_t t1, cfs_time_t t2)
{
return cfs_time_beforeq(t2, t1);
}
static inline cfs_time_t cfs_time_shift(int seconds)
{
return cfs_time_add(cfs_time_current(), cfs_time_seconds(seconds));
}
static inline long cfs_timeval_sub(struct timeval *large, struct timeval *small,
struct timeval *result)
{
long r = (long) (
(large->tv_sec - small->tv_sec) * ONE_MILLION +
(large->tv_usec - small->tv_usec));
if (result != NULL) {
result->tv_usec = r % ONE_MILLION;
result->tv_sec = r / ONE_MILLION;
}
return r;
}
static inline void cfs_slow_warning(cfs_time_t now, int seconds, char *msg)
{
if (cfs_time_after(cfs_time_current(),
cfs_time_add(now, cfs_time_seconds(15))))
CERROR("slow %s "CFS_TIME_T" sec\n", msg,
cfs_duration_sec(cfs_time_sub(cfs_time_current(),now)));
}
#define CFS_RATELIMIT(seconds) \
({ \
/* \
* XXX nikita: non-portable initializer \
*/ \
static time_t __next_message = 0; \
int result; \
\
if (cfs_time_after(cfs_time_current(), __next_message)) \
result = 1; \
else { \
__next_message = cfs_time_shift(seconds); \
result = 0; \
} \
result; \
})
/*
* helper function similar to do_gettimeofday() of Linux kernel
*/
static inline void cfs_fs_timeval(struct timeval *tv)
{
cfs_fs_time_t time;
cfs_fs_time_current(&time);
cfs_fs_time_usec(&time, tv);
}
/*
* return valid time-out based on user supplied one. Currently we only check
* that time-out is not shorted than allowed.
*/
static inline cfs_duration_t cfs_timeout_cap(cfs_duration_t timeout)
{
if (timeout < CFS_TICK)
timeout = CFS_TICK;
return timeout;
}
#endif

Some files were not shown because too many files have changed in this diff Show More