Commit 8ea4a5d8 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-4.17-ofs' of git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux

Pull orangefs updates from Mike Marshall:
 "Fixes and cleanups:

   - Documentation cleanups

   - removal of unused code

   - make some structs static

   - implement Orangefs vm_operations fault callout

   - eliminate two single-use functions and put their cleaned up code in
     line.

   - replace a vmalloc/memset instance with vzalloc

   - fix a race condition bug in wait code"

* tag 'for-linus-4.17-ofs' of git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux:
  Orangefs: documentation updates
  orangefs: document package install and xfstests procedure
  orangefs: remove unused code
  orangefs: make several *_operations structs static
  orangefs: implement vm_ops->fault
  orangefs: open code short single-use functions
  orangefs: replace vmalloc and memset with vzalloc
  orangefs: bug fix for a race condition when getting a slot
parents 190f2ace 8e9ba5c4
......@@ -21,10 +21,16 @@ Orangefs features include:
* Stateless
MAILING LIST
============
MAILING LIST ARCHIVES
=====================
http://beowulf-underground.org/mailman/listinfo/pvfs2-users
http://lists.orangefs.org/pipermail/devel_lists.orangefs.org/
MAILING LIST SUBMISSIONS
========================
devel@lists.orangefs.org
DOCUMENTATION
......@@ -42,12 +48,59 @@ Orangefs versions prior to 2.9.3 would not be compatible with the
upstream version of the kernel client.
BUILDING THE USERSPACE FILESYSTEM ON A SINGLE SERVER
====================================================
RUNNING ORANGEFS ON A SINGLE SERVER
===================================
OrangeFS is usually run in large installations with multiple servers and
clients, but a complete filesystem can be run on a single machine for
development and testing.
On Fedora, install orangefs and orangefs-server.
dnf -y install orangefs orangefs-server
There is an example server configuration file in
/etc/orangefs/orangefs.conf. Change localhost to your hostname if
necessary.
To generate a filesystem to run xfstests against, see below.
There is an example client configuration file in /etc/pvfs2tab. It is a
single line. Uncomment it and change the hostname if necessary. This
controls clients which use libpvfs2. This does not control the
pvfs2-client-core.
Create the filesystem.
pvfs2-server -f /etc/orangefs/orangefs.conf
Start the server.
systemctl start orangefs-server
Test the server.
pvfs2-ping -m /pvfsmnt
Start the client. The module must be compiled in or loaded before this
point.
systemctl start orangefs-client
Mount the filesystem.
mount -t pvfs2 tcp://localhost:3334/orangefs /pvfsmnt
You can omit --prefix if you don't care that things are sprinkled around in
/usr/local. As of version 2.9.6, Orangefs uses Berkeley DB by default, we
will probably be changing the default to lmdb soon.
BUILDING ORANGEFS ON A SINGLE SERVER
====================================
Where OrangeFS cannot be installed from distribution packages, it may be
built from source.
You can omit --prefix if you don't care that things are sprinkled around
in /usr/local. As of version 2.9.6, OrangeFS uses Berkeley DB by
default, we will probably be changing the default to LMDB soon.
./configure --prefix=/opt/ofs --with-db-backend=lmdb
......@@ -55,35 +108,69 @@ make
make install
Create an orangefs config file:
Create an orangefs config file.
/opt/ofs/bin/pvfs2-genconfig /etc/pvfs2.conf
for "Enter hostnames", use the hostname, don't let it default to
localhost.
Create an /etc/pvfs2tab file.
echo tcp://localhost:3334/orangefs /pvfsmnt pvfs2 defaults,noauto 0 0 > \
/etc/pvfs2tab
Create the mount point you specified in the tab file if needed.
create a pvfs2tab file in /etc:
cat /etc/pvfs2tab
tcp://myhostname:3334/orangefs /mymountpoint pvfs2 defaults,noauto 0 0
mkdir /pvfsmnt
create the mount point you specified in the tab file if needed:
mkdir /mymountpoint
Bootstrap the server.
bootstrap the server:
/opt/ofs/sbin/pvfs2-server /etc/pvfs2.conf -f
/opt/ofs/sbin/pvfs2-server -f /etc/pvfs2.conf
Start the server.
start the server:
/opt/osf/sbin/pvfs2-server /etc/pvfs2.conf
Now the server is running. At this point you might like to
prove things are working with:
Now the server should be running. Pvfs2-ls is a simple
test to verify that the server is running.
/opt/ofs/bin/pvfs2-ls /pvfsmnt
/opt/osf/bin/pvfs2-ls /mymountpoint
If stuff seems to be working, load the kernel module and
turn on the client core.
If stuff seems to be working, turn on the client core:
/opt/osf/sbin/pvfs2-client -p /opt/osf/sbin/pvfs2-client-core
/opt/ofs/sbin/pvfs2-client -p /opt/osf/sbin/pvfs2-client-core
Mount your filesystem.
mount -t pvfs2 tcp://myhostname:3334/orangefs /mymountpoint
mount -t pvfs2 tcp://localhost:3334/orangefs /pvfsmnt
RUNNING XFSTESTS
================
It is useful to use a scratch filesystem with xfstests. This can be
done with only one server.
Make a second copy of the FileSystem section in the server configuration
file, which is /etc/orangefs/orangefs.conf. Change the Name to scratch.
Change the ID to something other than the ID of the first FileSystem
section (2 is usually a good choice).
Then there are two FileSystem sections: orangefs and scratch.
This change should be made before creating the filesystem.
pvfs2-server -f /etc/orangefs/orangefs.conf
To run xfstests, create /etc/xfsqa.config.
TEST_DIR=/orangefs
TEST_DEV=tcp://localhost:3334/orangefs
SCRATCH_MNT=/scratch
SCRATCH_DEV=tcp://localhost:3334/scratch
Then xfstests can be run
./check -pvfs2
OPTIONS
......
......@@ -463,11 +463,10 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
if (op->downcall.type != ORANGEFS_VFS_OP_READDIR)
goto wakeup;
op->downcall.trailer_buf = vmalloc(op->downcall.trailer_size);
op->downcall.trailer_buf = vzalloc(op->downcall.trailer_size);
if (!op->downcall.trailer_buf)
goto Enomem;
memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size);
if (!copy_from_iter_full(op->downcall.trailer_buf,
op->downcall.trailer_size, iter)) {
gossip_err("%s: failed to copy trailer.\n", __func__);
......@@ -779,9 +778,35 @@ static long orangefs_devreq_compat_ioctl(struct file *filp, unsigned int cmd,
#endif /* CONFIG_COMPAT is in .config */
static __poll_t orangefs_devreq_poll(struct file *file,
struct poll_table_struct *poll_table)
{
__poll_t poll_revent_mask = 0;
poll_wait(file, &orangefs_request_list_waitq, poll_table);
if (!list_empty(&orangefs_request_list))
poll_revent_mask |= EPOLLIN;
return poll_revent_mask;
}
/* the assigned character device major number */
static int orangefs_dev_major;
static const struct file_operations orangefs_devreq_file_operations = {
.owner = THIS_MODULE,
.read = orangefs_devreq_read,
.write_iter = orangefs_devreq_write_iter,
.open = orangefs_devreq_open,
.release = orangefs_devreq_release,
.unlocked_ioctl = orangefs_devreq_ioctl,
#ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */
.compat_ioctl = orangefs_devreq_compat_ioctl,
#endif
.poll = orangefs_devreq_poll
};
/*
* Initialize orangefs device specific state:
* Must be called at module load time only
......@@ -814,29 +839,3 @@ void orangefs_dev_cleanup(void)
"*** /dev/%s character device unregistered ***\n",
ORANGEFS_REQDEVICE_NAME);
}
static __poll_t orangefs_devreq_poll(struct file *file,
struct poll_table_struct *poll_table)
{
__poll_t poll_revent_mask = 0;
poll_wait(file, &orangefs_request_list_waitq, poll_table);
if (!list_empty(&orangefs_request_list))
poll_revent_mask |= EPOLLIN;
return poll_revent_mask;
}
const struct file_operations orangefs_devreq_file_operations = {
.owner = THIS_MODULE,
.read = orangefs_devreq_read,
.write_iter = orangefs_devreq_write_iter,
.open = orangefs_devreq_open,
.release = orangefs_devreq_release,
.unlocked_ioctl = orangefs_devreq_ioctl,
#ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */
.compat_ioctl = orangefs_devreq_compat_ioctl,
#endif
.poll = orangefs_devreq_poll
};
......@@ -41,70 +41,6 @@ static int flush_racache(struct inode *inode)
return ret;
}
/*
* Copy to client-core's address space from the buffers specified
* by the iovec upto total_size bytes.
* NOTE: the iovector can either contain addresses which
* can futher be kernel-space or user-space addresses.
* or it can pointers to struct page's
*/
static int precopy_buffers(int buffer_index,
struct iov_iter *iter,
size_t total_size)
{
int ret = 0;
/*
* copy data from application/kernel by pulling it out
* of the iovec.
*/
if (total_size) {
ret = orangefs_bufmap_copy_from_iovec(iter,
buffer_index,
total_size);
if (ret < 0)
gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n",
__func__,
(long)ret);
}
if (ret < 0)
gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n",
__func__,
(long)ret);
return ret;
}
/*
* Copy from client-core's address space to the buffers specified
* by the iovec upto total_size bytes.
* NOTE: the iovector can either contain addresses which
* can futher be kernel-space or user-space addresses.
* or it can pointers to struct page's
*/
static int postcopy_buffers(int buffer_index,
struct iov_iter *iter,
size_t total_size)
{
int ret = 0;
/*
* copy data to application/kernel by pushing it out to
* the iovec. NOTE; target buffers can be addresses or
* struct page pointers.
*/
if (total_size) {
ret = orangefs_bufmap_copy_to_iovec(iter,
buffer_index,
total_size);
if (ret < 0)
gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n",
__func__,
(long)ret);
}
return ret;
}
/*
* Post and wait for the I/O upcall to finish
*/
......@@ -157,14 +93,15 @@ static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inod
total_size);
/*
* Stage 1: copy the buffers into client-core's address space
* precopy_buffers only pertains to writes.
*/
if (type == ORANGEFS_IO_WRITE) {
ret = precopy_buffers(buffer_index,
iter,
total_size);
if (ret < 0)
if (type == ORANGEFS_IO_WRITE && total_size) {
ret = orangefs_bufmap_copy_from_iovec(iter, buffer_index,
total_size);
if (ret < 0) {
gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n",
__func__, (long)ret);
goto out;
}
}
gossip_debug(GOSSIP_FILE_DEBUG,
......@@ -260,14 +197,20 @@ static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inod
/*
* Stage 3: Post copy buffers from client-core's address space
* postcopy_buffers only pertains to reads.
*/
if (type == ORANGEFS_IO_READ) {
ret = postcopy_buffers(buffer_index,
iter,
new_op->downcall.resp.io.amt_complete);
if (ret < 0)
if (type == ORANGEFS_IO_READ && new_op->downcall.resp.io.amt_complete) {
/*
* NOTE: the iovector can either contain addresses which
* can futher be kernel-space or user-space addresses.
* or it can pointers to struct page's
*/
ret = orangefs_bufmap_copy_to_iovec(iter, buffer_index,
new_op->downcall.resp.io.amt_complete);
if (ret < 0) {
gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n",
__func__, (long)ret);
goto out;
}
}
gossip_debug(GOSSIP_FILE_DEBUG,
"%s(%pU): Amount %s, returned by the sys-io call:%d\n",
......@@ -585,6 +528,28 @@ static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long ar
return ret;
}
static int orangefs_fault(struct vm_fault *vmf)
{
struct file *file = vmf->vma->vm_file;
int rc;
rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1,
STATX_SIZE);
if (rc == -ESTALE)
rc = -EIO;
if (rc) {
gossip_err("%s: orangefs_inode_getattr failed, "
"rc:%d:.\n", __func__, rc);
return rc;
}
return filemap_fault(vmf);
}
const struct vm_operations_struct orangefs_file_vm_ops = {
.fault = orangefs_fault,
.map_pages = filemap_map_pages,
.page_mkwrite = filemap_page_mkwrite,
};
/*
* Memory map a region of a file.
*/
......@@ -596,12 +561,16 @@ static int orangefs_file_mmap(struct file *file, struct vm_area_struct *vma)
(char *)file->f_path.dentry->d_name.name :
(char *)"Unknown"));
if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
return -EINVAL;
/* set the sequential readahead hint */
vma->vm_flags |= VM_SEQ_READ;
vma->vm_flags &= ~VM_RAND_READ;
/* Use readonly mmap since we cannot support writable maps. */
return generic_file_readonly_mmap(file, vma);
file_accessed(file);
vma->vm_ops = &orangefs_file_vm_ops;
return 0;
}
#define mapping_nrpages(idata) ((idata)->nrpages)
......
......@@ -138,7 +138,7 @@ static ssize_t orangefs_direct_IO(struct kiocb *iocb,
}
/** ORANGEFS2 implementation of address space operations */
const struct address_space_operations orangefs_address_operations = {
static const struct address_space_operations orangefs_address_operations = {
.readpage = orangefs_readpage,
.readpages = orangefs_readpages,
.invalidatepage = orangefs_invalidatepage,
......@@ -307,7 +307,7 @@ int orangefs_update_time(struct inode *inode, struct timespec *time, int flags)
}
/* ORANGEDS2 implementation of VFS inode operations for files */
const struct inode_operations orangefs_file_inode_operations = {
static const struct inode_operations orangefs_file_inode_operations = {
.get_acl = orangefs_get_acl,
.set_acl = orangefs_set_acl,
.setattr = orangefs_setattr,
......
......@@ -71,9 +71,9 @@ static void put(struct slot_map *m, int slot)
spin_lock(&m->q.lock);
__clear_bit(slot, m->map);
v = ++m->c;
if (unlikely(v == 1)) /* no free slots -> one free slot */
if (v > 0)
wake_up_locked(&m->q);
else if (unlikely(v == -1)) /* finished dying */
if (unlikely(v == -1)) /* finished dying */
wake_up_all_locked(&m->q);
spin_unlock(&m->q.lock);
}
......
......@@ -43,12 +43,6 @@
#define GOSSIP_MAX_NR 16
#define GOSSIP_MAX_DEBUG (((__u64)1 << GOSSIP_MAX_NR) - 1)
/*function prototypes*/
__u64 ORANGEFS_kmod_eventlog_to_mask(const char *event_logging);
__u64 ORANGEFS_debug_eventlog_to_mask(const char *event_logging);
char *ORANGEFS_debug_mask_to_eventlog(__u64 mask);
char *ORANGEFS_kmod_mask_to_eventlog(__u64 mask);
/* a private internal type */
struct __keyword_mask_s {
const char *keyword;
......
......@@ -65,11 +65,7 @@
#define ORANGEFS_REQDEVICE_NAME "pvfs2-req"
#define ORANGEFS_DEVREQ_MAGIC 0x20030529
#define ORANGEFS_LINK_MAX 0x000000FF
#define ORANGEFS_PURGE_RETRY_COUNT 0x00000005
#define ORANGEFS_MAX_NUM_OPTIONS 0x00000004
#define ORANGEFS_MAX_MOUNT_OPT_LEN 0x00000080
#define ORANGEFS_MAX_FSKEY_LEN 64
#define MAX_DEV_REQ_UPSIZE (2 * sizeof(__s32) + \
sizeof(__u64) + sizeof(struct orangefs_upcall_s))
......@@ -112,15 +108,6 @@ extern const struct xattr_handler *orangefs_xattr_handlers[];
extern struct posix_acl *orangefs_get_acl(struct inode *inode, int type);
extern int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
/*
* Redefine xtvec structure so that we could move helper functions out of
* the define
*/
struct xtvec {
__kernel_off_t xtv_off; /* must be off_t */
__kernel_size_t xtv_len; /* must be size_t */
};
/*
* orangefs data structures
*/
......@@ -224,39 +211,6 @@ struct orangefs_sb_info_s {
struct list_head list;
};
/*
* structure that holds the state of any async I/O operation issued
* through the VFS. Needed especially to handle cancellation requests
* or even completion notification so that the VFS client-side daemon
* can free up its vfs_request slots.
*/
struct orangefs_kiocb_s {
/* the pointer to the task that initiated the AIO */
struct task_struct *tsk;
/* pointer to the kiocb that kicked this operation */
struct kiocb *kiocb;
/* buffer index that was used for the I/O */
struct orangefs_bufmap *bufmap;
int buffer_index;
/* orangefs kernel operation type */
struct orangefs_kernel_op_s *op;
/* set to indicate the type of the operation */
int rw;
/* file offset */
loff_t offset;
/* and the count in bytes */
size_t bytes_to_be_copied;
ssize_t bytes_copied;
int needs_cleanup;
};
struct orangefs_stats {
unsigned long cache_hits;
unsigned long cache_misses;
......@@ -305,21 +259,6 @@ static inline struct orangefs_khandle *get_khandle_from_ino(struct inode *inode)
return &(ORANGEFS_I(inode)->refn.khandle);
}
static inline ino_t get_ino_from_khandle(struct inode *inode)
{
struct orangefs_khandle *khandle;
ino_t ino;
khandle = get_khandle_from_ino(inode);
ino = orangefs_khandle_to_ino(khandle);
return ino;
}
static inline ino_t get_parent_ino_from_dentry(struct dentry *dentry)
{
return get_ino_from_khandle(dentry->d_parent->d_inode);
}
static inline int is_root_handle(struct inode *inode)
{
gossip_debug(GOSSIP_DCACHE_DEBUG,
......@@ -391,7 +330,6 @@ void fsid_key_table_finalize(void);
/*
* defined in inode.c
*/
__u32 convert_to_orangefs_mask(unsigned long lite_mask);
struct inode *orangefs_new_inode(struct super_block *sb,
struct inode *dir,
int mode,
......@@ -410,17 +348,6 @@ int orangefs_update_time(struct inode *, struct timespec *, int);
/*
* defined in xattr.c
*/
int orangefs_setxattr(struct dentry *dentry,
const char *name,
const void *value,
size_t size,
int flags);
ssize_t orangefs_getxattr(struct dentry *dentry,
const char *name,
void *buffer,
size_t size);
ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size);
/*
......@@ -467,8 +394,6 @@ int orangefs_inode_check_changed(struct inode *inode);
int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr);
int orangefs_unmount_sb(struct super_block *sb);
bool orangefs_cancel_op_in_progress(struct orangefs_kernel_op_s *op);
int orangefs_normalize_to_errno(__s32 error_code);
......@@ -487,16 +412,11 @@ extern struct list_head *orangefs_htable_ops_in_progress;
extern spinlock_t orangefs_htable_ops_in_progress_lock;
extern int hash_table_size;
extern const struct address_space_operations orangefs_address_operations;
extern const struct inode_operations orangefs_file_inode_operations;
extern const struct file_operations orangefs_file_operations;
extern const struct inode_operations orangefs_symlink_inode_operations;
extern const struct inode_operations orangefs_dir_inode_operations;
extern const struct file_operations orangefs_dir_operations;
extern const struct dentry_operations orangefs_dentry_operations;
extern const struct file_operations orangefs_devreq_file_operations;
extern wait_queue_head_t orangefs_bufmap_init_waitq;
/*
* misc convenience macros
......
......@@ -5,11 +5,6 @@
#include <linux/slab.h>
#include <linux/ioctl.h>
/* pvfs2-config.h ***********************************************************/
#define ORANGEFS_VERSION_MAJOR 2
#define ORANGEFS_VERSION_MINOR 9
#define ORANGEFS_VERSION_SUB 0
/* khandle stuff ***********************************************************/
/*
......@@ -70,16 +65,6 @@ static inline void ORANGEFS_khandle_from(struct orangefs_khandle *kh,
}
/* pvfs2-types.h ************************************************************/
typedef __u32 ORANGEFS_uid;
typedef __u32 ORANGEFS_gid;
typedef __s32 ORANGEFS_fs_id;
typedef __u32 ORANGEFS_permissions;
typedef __u64 ORANGEFS_time;
typedef __s64 ORANGEFS_size;
typedef __u64 ORANGEFS_flags;
typedef __u64 ORANGEFS_ds_position;
typedef __s32 ORANGEFS_error;
typedef __s64 ORANGEFS_offset;
#define ORANGEFS_SUPER_MAGIC 0x20030528
......@@ -145,7 +130,6 @@ typedef __s64 ORANGEFS_offset;
#define ORANGEFS_APPEND_FL FS_APPEND_FL
#define ORANGEFS_NOATIME_FL FS_NOATIME_FL
#define ORANGEFS_MIRROR_FL 0x01000000ULL
#define ORANGEFS_O_EXECUTE (1 << 0)
#define ORANGEFS_FS_ID_NULL ((__s32)0)
#define ORANGEFS_ATTR_SYS_UID (1 << 0)
#define ORANGEFS_ATTR_SYS_GID (1 << 1)
......@@ -229,35 +213,6 @@ enum orangefs_ds_type {
ORANGEFS_TYPE_INTERNAL = (1 << 5) /* for the server's private use */
};
/*
* ORANGEFS_certificate simply stores a buffer with the buffer size.
* The buffer can be converted to an OpenSSL X509 struct for use.
*/
struct ORANGEFS_certificate {
__u32 buf_size;
unsigned char *buf;
};
/*
* A credential identifies a user and is signed by the client/user
* private key.
*/
struct ORANGEFS_credential {
__u32 userid; /* user id */
__u32 num_groups; /* length of group_array */
__u32 *group_array; /* groups for which the user is a member */
char *issuer; /* alias of the issuing server */
__u64 timeout; /* seconds after epoch to time out */
__u32 sig_size; /* length of the signature in bytes */
unsigned char *signature; /* digital signature */
struct ORANGEFS_certificate certificate; /* user certificate buffer */
};
#define extra_size_ORANGEFS_credential (ORANGEFS_REQ_LIMIT_GROUPS * \
sizeof(__u32) + \
ORANGEFS_REQ_LIMIT_ISSUER + \
ORANGEFS_REQ_LIMIT_SIGNATURE + \
extra_size_ORANGEFS_certificate)
/* This structure is used by the VFS-client interaction alone */
struct ORANGEFS_keyval_pair {
char key[ORANGEFS_MAX_XATTR_NAMELEN];
......
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