Exemple #1
0
static int pvfs2_check_acl(struct inode *inode, int mask)
{
    struct posix_acl *acl = NULL;

    gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_check_acl: called on inode %llu\n",
            llu(get_handle_from_ino(inode)));

    acl = pvfs2_get_acl(inode, ACL_TYPE_ACCESS);

    if (IS_ERR(acl)) {
        int error = PTR_ERR(acl);
        gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_check_acl: pvfs2_get_acl returned error %d\n",
                error);
        return error;
    }
    if (acl) 
    {
        int error = posix_acl_permission(inode, acl, mask);
        posix_acl_release(acl);
        gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_check_acl: posix_acl_permission "
                " (inode %llu, acl %p, mask %x) returned %d\n",
                 llu(get_handle_from_ino(inode)), acl, mask, error);
        return error;
    }
    gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_check_acl returning EAGAIN\n");
    return -EAGAIN;
}
Exemple #2
0
int client_state_machine_terminate(
        struct PINT_smcb *smcb, job_status_s *js_p)
{
    int ret;
    PINT_client_sm *sm_p;

    sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);

    gossip_debug(GOSSIP_CLIENT_DEBUG,
                 "client_state_machine_terminate smcb %p\n",smcb);

    if (!((PINT_smcb_op(smcb) == PVFS_SYS_IO) &&
            (PINT_smcb_cancelled(smcb)) &&
            (cancelled_io_jobs_are_pending(smcb))) &&
        !PINT_smcb_immediate_completion(smcb))
    {
        gossip_debug(GOSSIP_CLIENT_DEBUG,
                 "client_state_machine_terminate smcb %p completing\n",smcb);

        PINT_EVENT_END(PINT_client_sys_event_id, pint_client_pid, NULL, sm_p->event_id, 0);
        PVFS_hint_free(sm_p->hints);
        sm_p->hints = NULL;

        gossip_debug(GOSSIP_CLIENT_DEBUG, 
                "add smcb %p to completion list\n", smcb);
        ret = add_sm_to_completion_list(smcb);
        assert(ret == 0);
    }
    else
    {
        gossip_debug(GOSSIP_CLIENT_DEBUG,
                 "client_state_machine_terminate smcb %p waiting for cancelled jobs\n",smcb);
    }
    return SM_ACTION_TERMINATE;
}
Exemple #3
0
static int iterate_root_squash_wildcards(struct filesystem_configuration_s *fsconfig,
    PVFS_BMI_addr_t client_addr)
{
    int i;

    /* check exceptions first */
    for (i = 0; i < fsconfig->root_squash_exceptions_count; i++)
    {
        gossip_debug(GOSSIP_SERVER_DEBUG, "BMI_query_addr_range %lld, %s, netmask: %i\n",
            lld(client_addr), fsconfig->root_squash_exceptions_hosts[i],
            fsconfig->root_squash_exceptions_netmasks[i]);
        if (BMI_query_addr_range(client_addr, fsconfig->root_squash_exceptions_hosts[i], 
                fsconfig->root_squash_exceptions_netmasks[i]) == 1)
        {
            /* in the exception list, do not squash */
            return 0;
        }
    }

    for (i = 0; i < fsconfig->root_squash_count; i++)
    {
        gossip_debug(GOSSIP_SERVER_DEBUG, "BMI_query_addr_range %lld, %s, netmask: %i\n",
            lld(client_addr), fsconfig->root_squash_hosts[i],
            fsconfig->root_squash_netmasks[i]);
        if (BMI_query_addr_range(client_addr, fsconfig->root_squash_hosts[i], 
                fsconfig->root_squash_netmasks[i]) == 1)
        {
            return 1;
        }
    }
    return 0;
}
Exemple #4
0
static int
pvfs2_xattr_set_acl(struct inode *inode, int type, const void *value,
        size_t size)
{
    struct posix_acl *acl;
    int error;
#ifdef HAVE_CURRENT_FSUID
    int fsuid = current_fsuid();
#else
    int fsuid = current->fsuid;
#endif

    gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_xattr_set_acl called with size %ld\n",
            (long)size);
    /* if we have not been mounted with acl option, ignore this */
    if (get_acl_flag(inode) == 0)
    {
        gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_xattr_set_acl: ACL options "
                "disabled on this FS!\n");
        return -EOPNOTSUPP;
    }
    /* Are we capable of setting acls on a file for which we should not be? */
    if ((fsuid != inode->i_uid) && !capable(CAP_FOWNER))
    {
        gossip_err("pvfs2_xattr_set_acl: operation not permitted "
                "(current->fsuid %d), (inode->owner %d)\n", 
                fsuid, inode->i_uid);
        return -EPERM;
    }
    if (value) 
    {
        acl = posix_acl_from_xattr(value, size);
        if (IS_ERR(acl))
        {
            error = PTR_ERR(acl);
            gossip_err("pvfs2_xattr_set_acl: posix_acl_from_xattr returned "
                    "error %d\n", error);
            goto err;
        }
        else if (acl) 
        {
            error = posix_acl_valid(acl);
            if (error)
            {
                gossip_err("pvfs2_xattr_set_acl: posix_acl_valid returned "
                        "error %d\n", error);
                goto out;
            }
        }
    }
    else {
        acl = NULL;
    }
    error = pvfs2_set_acl(inode, type, acl);
    gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_set_acl returned error %d\n", error);
out:
    posix_acl_release(acl);
err:
    return error;
}
Exemple #5
0
static PINT_sm_action replace_datafile_handle(
					      struct PINT_smcb *smcb, job_status_s *js_p)
{
	struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
	int i;
	PVFS_single_dfile target_handle = s_op->req->u.setattr.attr.u.meta.metafile;

	gossip_debug(GOSSIP_SERVER_DEBUG,"migration happen: ar_predict_fun->global_forecast_load: 1 \n");
	

	/* print data file handle array*/
	for (i = 0; i < s_op->ds_attr.u.metafile.dfile_count; i++){
/* 	 	gossip_debug(GOSSIP_LB_DEBUG,  */
/*  			     "#%d handle=%llu,old handle: %llu, new handle: %llu\n",  */
/*  			     i,   */
/*  			     s_op->req->u.setattr.attr.u.meta.dfile_array[i],  */
/*  			     target_handle.old,  */
/*  			     target_handle.new); */ 
	  if (s_op->req->u.setattr.attr.u.meta.dfile_array[i] ==  target_handle.old){
	    s_op->req->u.setattr.attr.u.meta.dfile_array[i] =  target_handle.new;
	    
	    gossip_debug(GOSSIP_LB_DEBUG,  
			 "#Replace %llu with %llu \n\n",   
			 target_handle.old,   
			 s_op->req->u.setattr.attr.u.meta.dfile_array[i]);  
	    
	    break;
	  }
	}
Exemple #6
0
int pvfs2_mmap_ra_cache_initialize(void)
{
    int ret = -1;

    if (!MMAP_RA_CACHE_INITIALIZED())
    {
        s_key_to_data_table = qhash_init(
            hash_key_compare, hash_key,
            DEFAULT_MMAP_RA_CACHE_HTABLE_SIZE);
        if (!s_key_to_data_table)
        {
            goto return_error;
        }

        gossip_debug(GOSSIP_MMAP_RCACHE_DEBUG,
                     "mmap_ra_cache_initialized\n");
        ret = 0;
    }
    else
    {
        gossip_debug(GOSSIP_MMAP_RCACHE_DEBUG, "mmap readahead cache already "
                     "initalized.  returning success\n");
        ret = 0;
    }

  return_error:
    return ret;
}
Exemple #7
0
static int flush_racache(struct inode *inode)
{
	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
	struct orangefs_kernel_op_s *new_op;
	int ret;

	gossip_debug(GOSSIP_UTILS_DEBUG,
	    "%s: %pU: Handle is %pU | fs_id %d\n", __func__,
	    get_khandle_from_ino(inode), &orangefs_inode->refn.khandle,
	    orangefs_inode->refn.fs_id);

	new_op = op_alloc(ORANGEFS_VFS_OP_RA_FLUSH);
	if (!new_op)
		return -ENOMEM;
	new_op->upcall.req.ra_cache_flush.refn = orangefs_inode->refn;

	ret = service_operation(new_op, "orangefs_flush_racache",
	    get_interruptible_flag(inode));

	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: got return value of %d\n",
	    __func__, ret);

	op_release(new_op);
	return ret;
}
Exemple #8
0
/** Change attributes of an object referenced by dentry.
 */
int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr)
{
    int ret = -EINVAL;
    struct inode *inode = dentry->d_inode;

    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_setattr: called on %s\n", dentry->d_name.name);

    ret = inode_change_ok(inode, iattr);
    if (ret == 0)
    {
        ret = inode_setattr(inode, iattr);
        gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_setattr: inode_setattr returned %d\n", ret);

        if (ret == 0)
        {
            ret = pvfs2_inode_setattr(inode, iattr);
#if !defined(PVFS2_LINUX_KERNEL_2_4) && defined(HAVE_GENERIC_GETXATTR) && defined(CONFIG_FS_POSIX_ACL)
            if (!ret && (iattr->ia_valid & ATTR_MODE))
            {
                /* change mod on a file that has ACLs */
                ret = pvfs2_acl_chmod(inode);
            }
#endif
        }
    }
    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_setattr: returning %d\n", ret);
    return ret;
}
Exemple #9
0
static int orangefs_readpages(struct file *file,
			   struct address_space *mapping,
			   struct list_head *pages,
			   unsigned nr_pages)
{
	int page_idx;
	int ret;

	gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_readpages called\n");

	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
		struct page *page;

		page = list_entry(pages->prev, struct page, lru);
		list_del(&page->lru);
		if (!add_to_page_cache(page,
				       mapping,
				       page->index,
				       readahead_gfp_mask(mapping))) {
			ret = read_one_page(page);
			gossip_debug(GOSSIP_INODE_DEBUG,
				"failure adding page to cache, read_one_page returned: %d\n",
				ret);
	      } else {
			put_page(page);
	      }
	}
	BUG_ON(!list_empty(pages));
	return 0;
}
Exemple #10
0
int pvfs2_getattr_lite(
    struct vfsmount *mnt,
    struct dentry *dentry,
    struct kstat_lite *kstat_lite)
{
    int ret = -ENOENT;
    struct inode *inode = dentry->d_inode;
    uint32_t mask;

    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_getattr_lite: called on %s\n", dentry->d_name.name);

    /*
     * ->getattr_lite needs to refresh only certain fields 
     * of the inode and that is indicated by the lite_mask
     * field of kstat_lite structure. 
     */
    mask = convert_to_pvfs2_mask(kstat_lite->lite_mask);
    ret = pvfs2_inode_getattr(inode, mask);
    if (ret == 0)
    {
        generic_fillattr_lite(inode, kstat_lite);
    }
    else
    {
        /* assume an I/O error and flag inode as bad */
        gossip_debug(GOSSIP_INODE_DEBUG, "%s:%s:%d calling make bad inode\n", __FILE__,  __func__, __LINE__);
        pvfs2_make_bad_inode(inode);
    }
    return ret;
}
Exemple #11
0
/*
 * Change attributes of an object referenced by dentry.
 */
int orangefs_setattr(struct dentry *dentry, struct iattr *iattr)
{
	int ret = -EINVAL;
	struct inode *inode = dentry->d_inode;

	gossip_debug(GOSSIP_INODE_DEBUG,
		     "orangefs_setattr: called on %pd\n",
		     dentry);

	ret = setattr_prepare(dentry, iattr);
	if (ret)
		goto out;

	if (iattr->ia_valid & ATTR_SIZE) {
		ret = orangefs_setattr_size(inode, iattr);
		if (ret)
			goto out;
	}

	setattr_copy(inode, iattr);
	mark_inode_dirty(inode);

	ret = orangefs_inode_setattr(inode, iattr);
	gossip_debug(GOSSIP_INODE_DEBUG,
		     "orangefs_setattr: inode_setattr returned %d\n",
		     ret);

	if (!ret && (iattr->ia_valid & ATTR_MODE))
		/* change mod on a file that has ACLs */
		ret = posix_acl_chmod(inode, inode->i_mode);

out:
	gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: returning %d\n", ret);
	return ret;
}
Exemple #12
0
/*
 * Called to notify the module that there are no more references to
 * this file (i.e. no processes have it open).
 *
 * \note Not called when each file is closed.
 */
static int orangefs_file_release(struct inode *inode, struct file *file)
{
	gossip_debug(GOSSIP_FILE_DEBUG,
		     "orangefs_file_release: called on %pD\n",
		     file);

	orangefs_flush_inode(inode);

	/*
	 * remove all associated inode pages from the page cache and
	 * readahead cache (if any); this forces an expensive refresh of
	 * data for the next caller of mmap (or 'get_block' accesses)
	 */
	if (file_inode(file) &&
	    file_inode(file)->i_mapping &&
	    mapping_nrpages(&file_inode(file)->i_data)) {
		if (orangefs_features & ORANGEFS_FEATURE_READAHEAD) {
			gossip_debug(GOSSIP_INODE_DEBUG,
			    "calling flush_racache on %pU\n",
			    get_khandle_from_ino(inode));
			flush_racache(inode);
			gossip_debug(GOSSIP_INODE_DEBUG,
			    "flush_racache finished\n");
		}
		truncate_inode_pages(file_inode(file)->i_mapping,
				     0);
	}
	return 0;
}
Exemple #13
0
/* pvfs_bufmap_finalize()
 *
 * shuts down the mapped buffer interface and releases any resources
 * associated with it
 *
 * no return value
 */
void pvfs_bufmap_finalize(void)
{
    int i = 0;

    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_finalize: called\n");

    down_write(&bufmap_init_sem);
    if (bufmap_init == 0)
    {
        gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_finalize: not yet "
                    "initialized; returning\n");
        up_write(&bufmap_init_sem);
        return;
    }

    for(i = 0; i < bufmap_page_count; i++)
    {
        pvfs2_clear_page_reserved(bufmap_page_array[i]);
        page_cache_release(bufmap_page_array[i]);
    }
    kfree(bufmap_page_array);

    bufmap_init = 0;

    finalize_bufmap_descriptors();
    up_write(&bufmap_init_sem);
    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_finalize: exiting normally\n");
}
Exemple #14
0
static int pvfs2_create(
    struct inode *dir,
    struct dentry *dentry,
    int mode,
    struct nameidata *nd)
#endif
{
    int ret = -EINVAL;
    struct inode *inode = NULL;

    gossip_debug(GOSSIP_NAME_DEBUG, "pvfs2_create: called\n");

    inode = pvfs2_create_entry(
        dir, dentry, NULL, mode, PVFS2_VFS_OP_CREATE, &ret);

    if (inode)
    {
        pvfs2_inode_t *dir_pinode = PVFS2_I(dir);

        SetMtimeFlag(dir_pinode);
        pvfs2_update_inode_time(dir);
        mark_inode_dirty_sync(dir);
        
        ret = 0;
    }

    gossip_debug(GOSSIP_NAME_DEBUG, "pvfs2_create: returning %d\n", ret);
    return ret;
}
Exemple #15
0
/*
 * Change the file pointer position for an instance of an open file.
 *
 * \note If .llseek is overriden, we must acquire lock as described in
 *       Documentation/filesystems/Locking.
 *
 * Future upgrade could support SEEK_DATA and SEEK_HOLE but would
 * require much changes to the FS
 */
static loff_t orangefs_file_llseek(struct file *file, loff_t offset, int origin)
{
	int ret = -EINVAL;
	struct inode *inode = file_inode(file);

	if (origin == SEEK_END) {
		/*
		 * revalidate the inode's file size.
		 * NOTE: We are only interested in file size here,
		 * so we set mask accordingly.
		 */
		ret = orangefs_inode_getattr(file->f_mapping->host, 0, 1);
		if (ret == -ESTALE)
			ret = -EIO;
		if (ret) {
			gossip_debug(GOSSIP_FILE_DEBUG,
				     "%s:%s:%d calling make bad inode\n",
				     __FILE__,
				     __func__,
				     __LINE__);
			return ret;
		}
	}

	gossip_debug(GOSSIP_FILE_DEBUG,
		     "orangefs_file_llseek: offset is %ld | origin is %d"
		     " | inode size is %lu\n",
		     (long)offset,
		     origin,
		     (unsigned long)i_size_read(inode));

	return generic_file_llseek(file, offset, origin);
}
Exemple #16
0
/**
 * Routines that retrieve and/or set ACLs for PVFS2 files.
 */
static struct posix_acl *
pvfs2_get_acl(struct inode *inode, int type)
{
    struct posix_acl *acl;
    int ret;
    char *key = NULL, *value = NULL;

    /* Won't work if you don't mount with the right set of options */
    if (get_acl_flag(inode) == 0) 
    {
        gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_get_acl: ACL options disabled on "
                "this FS!\n");
        return NULL;
    }
    switch (type)
    {
        case ACL_TYPE_ACCESS:
            key = PVFS2_XATTR_NAME_ACL_ACCESS;
            break;
        case ACL_TYPE_DEFAULT:
            key = PVFS2_XATTR_NAME_ACL_DEFAULT;
            break;
        default:
            gossip_err("pvfs2_get_acl: bogus value of type %d\n", type);
            return ERR_PTR(-EINVAL);
    }
    /*
     * Rather than incurring a network call just to determine the exact length of
     * the attribute, I just allocate a max length to save on the network call
     * Conceivably, we could pass NULL to pvfs2_inode_getxattr() to probe the length
     * of the value, but I don't do that for now.
     */
    value = (char *) kmalloc(PVFS_MAX_XATTR_VALUELEN, GFP_KERNEL);
    if (value == NULL)
    {
        gossip_err("pvfs2_get_acl: Could not allocate value ptr\n");
        return ERR_PTR(-ENOMEM);
    }
    gossip_debug(GOSSIP_ACL_DEBUG, "inode %llu, key %s, type %d\n", 
            llu(get_handle_from_ino(inode)), key, type);
    ret = pvfs2_inode_getxattr(inode, "", key, value, PVFS_MAX_XATTR_VALUELEN);
    /* if the key exists, convert it to an in-memory rep */
    if (ret > 0)
    {
        acl = pvfs2_acl_decode(value, ret);
    }
    else if (ret == -ENODATA || ret == -ENOSYS)
    {
        acl = NULL;
    }
    else {
        gossip_err("inode %llu retrieving acl's failed with error %d\n",
                llu(get_handle_from_ino(inode)), ret);
        acl = ERR_PTR(ret);
    }
    if (value) {
        kfree(value);
    }
    return acl;
}
Exemple #17
0
static int
pvfs2_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
{
    struct posix_acl *acl;
    int error;

    /* if we have not been mounted with acl option, ignore this */
    if (get_acl_flag(inode) == 0)
    {
        gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_xattr_get_acl: ACL options "
                "disabled on this FS!\n");
        return -EOPNOTSUPP;
    }
    acl = pvfs2_get_acl(inode, type);
    if (IS_ERR(acl))
    {
        error = PTR_ERR(acl);
        gossip_err("pvfs2_get_acl failed with error %d\n", error);
        goto out;
    }
    if (acl == NULL)
    {
        error = -ENODATA;
        goto out;
    }
    error = posix_acl_to_xattr(acl, buffer, size);
    posix_acl_release(acl);
    gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_xattr_get_acl: posix_acl_to_xattr "
            "returned %d\n", error);
out:
    return error;
}
Exemple #18
0
static int orangefs_fill_sb(struct super_block *sb,
		struct orangefs_fs_mount_response *fs_mount,
		void *data, int silent)
{
	int ret = -EINVAL;
	struct inode *root = NULL;
	struct dentry *root_dentry = NULL;
	struct orangefs_object_kref root_object;

	/* alloc and init our private orangefs sb info */
	sb->s_fs_info = kzalloc(sizeof(struct orangefs_sb_info_s), GFP_KERNEL);
	if (!ORANGEFS_SB(sb))
		return -ENOMEM;
	ORANGEFS_SB(sb)->sb = sb;

	ORANGEFS_SB(sb)->root_khandle = fs_mount->root_khandle;
	ORANGEFS_SB(sb)->fs_id = fs_mount->fs_id;
	ORANGEFS_SB(sb)->id = fs_mount->id;

	if (data) {
		ret = parse_mount_options(sb, data, silent);
		if (ret)
			return ret;
	}

	/* Hang the xattr handlers off the superblock */
	sb->s_xattr = orangefs_xattr_handlers;
	sb->s_magic = ORANGEFS_SUPER_MAGIC;
	sb->s_op = &orangefs_s_ops;
	sb->s_d_op = &orangefs_dentry_operations;

	sb->s_blocksize = orangefs_bufmap_size_query();
	sb->s_blocksize_bits = orangefs_bufmap_shift_query();
	sb->s_maxbytes = MAX_LFS_FILESIZE;

	root_object.khandle = ORANGEFS_SB(sb)->root_khandle;
	root_object.fs_id = ORANGEFS_SB(sb)->fs_id;
	gossip_debug(GOSSIP_SUPER_DEBUG,
		     "get inode %pU, fsid %d\n",
		     &root_object.khandle,
		     root_object.fs_id);

	root = orangefs_iget(sb, &root_object);
	if (IS_ERR(root))
		return PTR_ERR(root);

	gossip_debug(GOSSIP_SUPER_DEBUG,
		     "Allocated root inode [%p] with mode %x\n",
		     root,
		     root->i_mode);

	/* allocates and places root dentry in dcache */
	root_dentry = d_make_root(root);
	if (!root_dentry)
		return -ENOMEM;

	sb->s_export_op = &orangefs_export_ops;
	sb->s_root = root_dentry;
	return 0;
}
Exemple #19
0
/*
 * pvfs_bufmap_copy_from_pages() 
 *
 * Copies data to the mapped buffer from the specified set of target 
 * pages (typically the kernel's page-cache)
 * for a given size and number of pages.
 * NOTE: iovec is expected to store pointers to struct page.
 *
 * Returns 0 on success and -errno on failure.
 */
int pvfs_bufmap_copy_from_pages(int buffer_index, 
                                const struct iovec *vec,
                                unsigned long nr_segs,
                                size_t size)
{
    size_t amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
    int to_page_index = 0;
    void *from_kaddr = NULL, *to_kaddr = NULL;
    struct pvfs_bufmap_desc *to = &desc_array[buffer_index];
    struct page *page;

    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_from_pages: nr_pages %lu "
            "index %d, size %zd\n", nr_segs, buffer_index, size);

    down_read(&bufmap_init_sem);
    if (bufmap_init == 0)
    {
        gossip_err("pvfs_bufmap_copy_from_pages: not yet "
                    "initialized.\n");
        gossip_err("pvfs2: please confirm that pvfs2-client is running.\n");
        up_read(&bufmap_init_sem);
        return -EIO;
    }

    while (amt_copied < size)
    {
        if (to_page_index >= nr_segs) {
            gossip_err("pvfs_bufmap_copy_from_pages: count cannot exceed number of"
                       "pages(%lu)\n", nr_segs);
            up_read(&bufmap_init_sem);
            return -EIO;
        }
        page = (struct page *) vec[to_page_index].iov_base;
        if (page == NULL) {
            gossip_err("pvfs_bufmap_copy_from_pages: invalid page pointer\n");
            up_read(&bufmap_init_sem);
            return -EIO;
        }
        amt_remaining = (size - amt_copied);
        cur_copy_size = ((amt_remaining > PAGE_SIZE) ?
                          PAGE_SIZE : amt_remaining);
        gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_from_pages:"
                "from_page: %p, to_page: %p\n", page, to->page_array[to_page_index]);
        to_kaddr = pvfs2_kmap(to->page_array[to_page_index]);
        from_kaddr = pvfs2_kmap(page);
#if 0
        gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_from_pages -> "
                     "to_kaddr: %p, from_kaddr:%p, cur_copy_size: %d\n",
                     to_kaddr, from_kaddr, cur_copy_size);
#endif
        memcpy(to_kaddr, from_kaddr, cur_copy_size);
        pvfs2_kunmap(page);
        pvfs2_kunmap(to->page_array[to_page_index]);
        amt_copied += cur_copy_size;
        to_page_index++;
    }
    up_read(&bufmap_init_sem);
    return 0;
}
Exemple #20
0
/*
 * Remount as initiated by pvfs2-client-core on restart.  This is used to
 * repopulate mount information left from previous pvfs2-client-core.
 *
 * the idea here is that given a valid superblock, we're
 * re-initializing the user space client with the initial mount
 * information specified when the super block was first initialized.
 * this is very different than the first initialization/creation of a
 * superblock.  we use the special service_priority_operation to make
 * sure that the mount gets ahead of any other pending operation that
 * is waiting for servicing.  this means that the pvfs2-client won't
 * fail to start several times for all other pending operations before
 * the client regains all of the mount information from us.
 * NOTE: this function assumes that the request_mutex is already acquired!
 */
int orangefs_remount(struct orangefs_sb_info_s *orangefs_sb)
{
	struct orangefs_kernel_op_s *new_op;
	int ret = -EINVAL;

	gossip_debug(GOSSIP_SUPER_DEBUG, "orangefs_remount: called\n");

	new_op = op_alloc(ORANGEFS_VFS_OP_FS_MOUNT);
	if (!new_op)
		return -ENOMEM;
	strncpy(new_op->upcall.req.fs_mount.orangefs_config_server,
		orangefs_sb->devname,
		ORANGEFS_MAX_SERVER_ADDR_LEN);

	gossip_debug(GOSSIP_SUPER_DEBUG,
		     "Attempting ORANGEFS Remount via host %s\n",
		     new_op->upcall.req.fs_mount.orangefs_config_server);

	/*
	 * we assume that the calling function has already acquired the
	 * request_mutex to prevent other operations from bypassing
	 * this one
	 */
	ret = service_operation(new_op, "orangefs_remount",
		ORANGEFS_OP_PRIORITY | ORANGEFS_OP_NO_MUTEX);
	gossip_debug(GOSSIP_SUPER_DEBUG,
		     "orangefs_remount: mount got return value of %d\n",
		     ret);
	if (ret == 0) {
		/*
		 * store the id assigned to this sb -- it's just a
		 * short-lived mapping that the system interface uses
		 * to map this superblock to a particular mount entry
		 */
		orangefs_sb->id = new_op->downcall.resp.fs_mount.id;
		orangefs_sb->mount_pending = 0;
	}

	op_release(new_op);

	if (orangefs_userspace_version >= 20906) {
		new_op = op_alloc(ORANGEFS_VFS_OP_FEATURES);
		if (!new_op)
			return -ENOMEM;
		new_op->upcall.req.features.features = 0;
		ret = service_operation(new_op, "orangefs_features",
		    ORANGEFS_OP_PRIORITY | ORANGEFS_OP_NO_MUTEX);
		if (!ret)
			orangefs_features =
			    new_op->downcall.resp.features.features;
		else
			orangefs_features = 0;
		op_release(new_op);
	} else {
		orangefs_features = 0;
	}

	return ret;
}
Exemple #21
0
static int wait_for_a_slot(struct slot_args *slargs, int *buffer_index)
{
    int ret = -1, i = 0;
    DECLARE_WAITQUEUE(my_wait, current);

    add_wait_queue_exclusive(slargs->slot_wq, &my_wait);

    while(1)
    {
        set_current_state(TASK_INTERRUPTIBLE);

        /* check for available desc */
        spin_lock(slargs->slot_lock);
        for(i = 0; i < slargs->slot_count; i++)
        {
            if (slargs->slot_array[i] == 0)
            {
                slargs->slot_array[i] = 1;
                *buffer_index = i;
                ret = 0;
                break;
            }
        }
        spin_unlock(slargs->slot_lock);

        /* if we acquired a buffer, then break out of while */
        if (ret == 0)
        {
            break;
        }

        if (!signal_pending(current))
        {
            int timeout = MSECS_TO_JIFFIES(1000 * slot_timeout_secs);
            gossip_debug(GOSSIP_BUFMAP_DEBUG,
                         "[BUFMAP]: waiting %d seconds for a slot\n",
                         slot_timeout_secs);
            if (!schedule_timeout(timeout))
            {
                gossip_debug(GOSSIP_BUFMAP_DEBUG, "*** wait_for_a_slot timed out\n");
                ret = -ETIMEDOUT;
                break;
            }
            gossip_debug(GOSSIP_BUFMAP_DEBUG,
                         "[BUFMAP]: acquired slot\n");
            continue;
        }

        gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2: wait_for_a_slot() interrupted.\n");
        ret = -EINTR;
        break;
    }

    set_current_state(TASK_RUNNING);
    remove_wait_queue(slargs->slot_wq, &my_wait);

    return ret;
}
Exemple #22
0
/*
 * Perform a miscellaneous operation on a file.
 */
static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int ret = -ENOTTY;
	__u64 val = 0;
	unsigned long uval;

	gossip_debug(GOSSIP_FILE_DEBUG,
		     "orangefs_ioctl: called with cmd %d\n",
		     cmd);

	/*
	 * we understand some general ioctls on files, such as the immutable
	 * and append flags
	 */
	if (cmd == FS_IOC_GETFLAGS) {
		val = 0;
		ret = orangefs_inode_getxattr(file_inode(file),
					      ORANGEFS_XATTR_NAME_DEFAULT_PREFIX,
					      "user.pvfs2.meta_hint",
					      &val, sizeof(val));
		if (ret < 0 && ret != -ENODATA)
			return ret;
		else if (ret == -ENODATA)
			val = 0;
		uval = val;
		gossip_debug(GOSSIP_FILE_DEBUG,
			     "orangefs_ioctl: FS_IOC_GETFLAGS: %llu\n",
			     (unsigned long long)uval);
		return put_user(uval, (int __user *)arg);
	} else if (cmd == FS_IOC_SETFLAGS) {
		ret = 0;
		if (get_user(uval, (int __user *)arg))
			return -EFAULT;
		/*
		 * ORANGEFS_MIRROR_FL is set internally when the mirroring mode
		 * is turned on for a file. The user is not allowed to turn
		 * on this bit, but the bit is present if the user first gets
		 * the flags and then updates the flags with some new
		 * settings. So, we ignore it in the following edit. bligon.
		 */
		if ((uval & ~ORANGEFS_MIRROR_FL) &
		    (~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL))) {
			gossip_err("orangefs_ioctl: the FS_IOC_SETFLAGS only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n");
			return -EINVAL;
		}
		val = uval;
		gossip_debug(GOSSIP_FILE_DEBUG,
			     "orangefs_ioctl: FS_IOC_SETFLAGS: %llu\n",
			     (unsigned long long)val);
		ret = orangefs_inode_setxattr(file_inode(file),
					      ORANGEFS_XATTR_NAME_DEFAULT_PREFIX,
					      "user.pvfs2.meta_hint",
					      &val, sizeof(val), 0);
	}

	return ret;
}
Exemple #23
0
static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
{
	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
	struct orangefs_kernel_op_s *new_op;
	loff_t orig_size;
	int ret = -EINVAL;

	gossip_debug(GOSSIP_INODE_DEBUG,
		     "%s: %pU: Handle is %pU | fs_id %d | size is %llu\n",
		     __func__,
		     get_khandle_from_ino(inode),
		     &orangefs_inode->refn.khandle,
		     orangefs_inode->refn.fs_id,
		     iattr->ia_size);

	/* Ensure that we have a up to date size, so we know if it changed. */
	ret = orangefs_inode_getattr(inode, 0, 1);
	if (ret == -ESTALE)
		ret = -EIO;
	if (ret) {
		gossip_err("%s: orangefs_inode_getattr failed, ret:%d:.\n",
		    __func__, ret);
		return ret;
	}
	orig_size = i_size_read(inode);

	truncate_setsize(inode, iattr->ia_size);

	new_op = op_alloc(ORANGEFS_VFS_OP_TRUNCATE);
	if (!new_op)
		return -ENOMEM;

	new_op->upcall.req.truncate.refn = orangefs_inode->refn;
	new_op->upcall.req.truncate.size = (__s64) iattr->ia_size;

	ret = service_operation(new_op, __func__,
				get_interruptible_flag(inode));

	/*
	 * the truncate has no downcall members to retrieve, but
	 * the status value tells us if it went through ok or not
	 */
	gossip_debug(GOSSIP_INODE_DEBUG,
		     "orangefs: orangefs_truncate got return value of %d\n",
		     ret);

	op_release(new_op);

	if (ret != 0)
		return ret;

	if (orig_size != i_size_read(inode))
		iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME;

	return ret;
}
Exemple #24
0
int PVFS_Request_free(PVFS_Request * req)
{
    PVFS_Request reqp;
    if (req == NULL)
    {
        gossip_lerr("PVFS_Request_free: NULL pointer argument\n");
        return PVFS_ERR_REQ;
    }
    if (*req == NULL)
    {
        gossip_lerr("PVFS_Request_free: pointer to NULL pointer argument\n");
        return PVFS_ERR_REQ;
    }
    if ((*req)->refcount <= 0)
    {
        /* if refcount is 0 then it has already been freed */
        /* if less than 0 it should not be freed */
        /* can't be sure if this is users's variable or not */
        gossip_debug(GOSSIP_REQUEST_DEBUG, "don't free special request\n");
        return PVFS_SUCCESS;
    }
    PINT_REQUEST_REFDEC(*req);
    if ((*req)->refcount > 0)
    {
        /* not ready to free this yet */
        *req = NULL;
        gossip_debug(GOSSIP_REQUEST_DEBUG, "don't free referenced request\n");
        return PVFS_SUCCESS;
    }
    if (PINT_REQUEST_IS_PACKED(*req))
    {
        /* these are contiguous and have no external refs */
        free(*req);
        *req = NULL;
        gossip_debug(GOSSIP_REQUEST_DEBUG, "free packed request\n");
        return PVFS_SUCCESS;
    }
    /* this deals with the sreq chain */
    reqp = (*req)->sreq;
    while (reqp)
    {
        PVFS_Request reqp_next;
        PVFS_Request_free(&(reqp->ereq));
        /* this is a little awkward but it works */
        reqp_next = reqp->sreq;
        free(reqp);
        gossip_debug(GOSSIP_REQUEST_DEBUG, "free sreq linked request\n");
        reqp = reqp_next;
    }
    /* now deal with the main struct */
    PVFS_Request_free(&((*req)->ereq));
    free(*req);
    *req = NULL;
    gossip_debug(GOSSIP_REQUEST_DEBUG, "free unpacked request\n");
    return PVFS_SUCCESS;
}
Exemple #25
0
static PINT_sm_action readdir_msg_setup_msgpair(
        struct PINT_smcb *smcb, job_status_s *js_p)
{
    struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
    int ret = -PVFS_EINVAL;
    PINT_sm_msgpair_state *msg_p = NULL;

    gossip_debug(GOSSIP_CLIENT_DEBUG, "readdir state: "
                 "readdir_msg_setup_msgpair\n");

    if (js_p->error_code)
    {
        return SM_ACTION_COMPLETE;
    }
    js_p->error_code = 0;

    gossip_debug(GOSSIP_READDIR_DEBUG," readdir: posting readdir req\n");

    gossip_debug(
        GOSSIP_READDIR_DEBUG, "%llu|%d | token is %llu | limit is %d\n",
        llu(sm_p->object_ref.handle),
        sm_p->object_ref.fs_id,
        llu(sm_p->readdir.pos_token),
        sm_p->readdir.dirent_limit);

    PINT_msgpair_init(&sm_p->msgarray_op);
    msg_p = &sm_p->msgarray_op.msgpair;

    PINT_SERVREQ_READDIR_FILL(
        msg_p->req,
        *sm_p->cred_p,
        sm_p->object_ref.fs_id,
        sm_p->object_ref.handle,
        sm_p->u.readdir.pos_token,
        sm_p->u.readdir.dirent_limit,
        sm_p->hints);

    msg_p->fs_id = sm_p->object_ref.fs_id;
    msg_p->handle = sm_p->object_ref.handle;
    msg_p->retry_flag = PVFS_MSGPAIR_RETRY;
    msg_p->comp_fn = readdir_msg_comp_fn;

    ret = PINT_cached_config_map_to_server(
        &msg_p->svr_addr, sm_p->object_ref.handle,
        sm_p->object_ref.fs_id);

    if (ret)
    {
        gossip_err("Failed to map meta server address\n");
        js_p->error_code = ret;
    }

    PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
    return SM_ACTION_COMPLETE;
}
Exemple #26
0
/*
 * NOTE: information filled in here is typically reflected in the
 * output of the system command 'df'
*/
static int orangefs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	int ret = -ENOMEM;
	struct orangefs_kernel_op_s *new_op = NULL;
	int flags = 0;
	struct super_block *sb = NULL;

	sb = dentry->d_sb;

	gossip_debug(GOSSIP_SUPER_DEBUG,
		     "orangefs_statfs: called on sb %p (fs_id is %d)\n",
		     sb,
		     (int)(ORANGEFS_SB(sb)->fs_id));

	new_op = op_alloc(ORANGEFS_VFS_OP_STATFS);
	if (!new_op)
		return ret;
	new_op->upcall.req.statfs.fs_id = ORANGEFS_SB(sb)->fs_id;

	if (ORANGEFS_SB(sb)->flags & ORANGEFS_OPT_INTR)
		flags = ORANGEFS_OP_INTERRUPTIBLE;

	ret = service_operation(new_op, "orangefs_statfs", flags);

	if (new_op->downcall.status < 0)
		goto out_op_release;

	gossip_debug(GOSSIP_SUPER_DEBUG,
		     "%s: got %ld blocks available | "
		     "%ld blocks total | %ld block size | "
		     "%ld files total | %ld files avail\n",
		     __func__,
		     (long)new_op->downcall.resp.statfs.blocks_avail,
		     (long)new_op->downcall.resp.statfs.blocks_total,
		     (long)new_op->downcall.resp.statfs.block_size,
		     (long)new_op->downcall.resp.statfs.files_total,
		     (long)new_op->downcall.resp.statfs.files_avail);

	buf->f_type = sb->s_magic;
	memcpy(&buf->f_fsid, &ORANGEFS_SB(sb)->fs_id, sizeof(buf->f_fsid));
	buf->f_bsize = new_op->downcall.resp.statfs.block_size;
	buf->f_namelen = ORANGEFS_NAME_MAX;

	buf->f_blocks = (sector_t) new_op->downcall.resp.statfs.blocks_total;
	buf->f_bfree = (sector_t) new_op->downcall.resp.statfs.blocks_avail;
	buf->f_bavail = (sector_t) new_op->downcall.resp.statfs.blocks_avail;
	buf->f_files = (sector_t) new_op->downcall.resp.statfs.files_total;
	buf->f_ffree = (sector_t) new_op->downcall.resp.statfs.files_avail;
	buf->f_frsize = sb->s_blocksize;

out_op_release:
	op_release(new_op);
	gossip_debug(GOSSIP_SUPER_DEBUG, "orangefs_statfs: returning %d\n", ret);
	return ret;
}
Exemple #27
0
static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl,
			      int type)
{
	int error = 0;
	void *value = NULL;
	size_t size = 0;
	const char *name = NULL;

	switch (type) {
	case ACL_TYPE_ACCESS:
		name = XATTR_NAME_POSIX_ACL_ACCESS;
		break;
	case ACL_TYPE_DEFAULT:
		name = XATTR_NAME_POSIX_ACL_DEFAULT;
		break;
	default:
		gossip_err("%s: invalid type %d!\n", __func__, type);
		return -EINVAL;
	}

	gossip_debug(GOSSIP_ACL_DEBUG,
		     "%s: inode %pU, key %s type %d\n",
		     __func__, get_khandle_from_ino(inode),
		     name,
		     type);

	if (acl) {
		size = posix_acl_xattr_size(acl->a_count);
		value = kmalloc(size, GFP_KERNEL);
		if (!value)
			return -ENOMEM;

		error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
		if (error < 0)
			goto out;
	}

	gossip_debug(GOSSIP_ACL_DEBUG,
		     "%s: name %s, value %p, size %zd, acl %p\n",
		     __func__, name, value, size, acl);
	/*
	 * Go ahead and set the extended attribute now. NOTE: Suppose acl
	 * was NULL, then value will be NULL and size will be 0 and that
	 * will xlate to a removexattr. However, we don't want removexattr
	 * complain if attributes does not exist.
	 */
	error = orangefs_inode_setxattr(inode, name, value, size, 0);

out:
	kfree(value);
	if (!error)
		set_cached_acl(inode, type, acl);
	return error;
}
Exemple #28
0
static PINT_sm_action setattr_msg_setup_msgpair(
        struct PINT_smcb *smcb, job_status_s *js_p)
{
    struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
    int ret = -PVFS_EINVAL;
    PINT_sm_msgpair_state *msg_p = NULL;
    PVFS_ds_type objtype;

    js_p->error_code = 0;

    gossip_debug(GOSSIP_CLIENT_DEBUG," setattr: posting setattr req\n");

    PINT_msgpair_init(&sm_p->msgarray_op);
    msg_p = &sm_p->msgarray_op.msgpair;

    objtype = ((sm_p->u.setattr.sys_attr.mask & PVFS_ATTR_SYS_TYPE) ? 
         sm_p->u.setattr.sys_attr.objtype : PVFS_TYPE_NONE);

    PINT_SERVREQ_SETATTR_FILL(
        msg_p->req,
        *sm_p->cred_p,
        sm_p->object_ref.fs_id,
        sm_p->object_ref.handle,
        objtype,
        sm_p->u.setattr.sys_attr,
        0,
        sm_p->hints);

    /* clients should not be able to mess with dfile and distribution
     * information here.  Those parameters should only be set at create time.
     * Maybe at some point we'll have a utility to adjust those attributes.  At
     * this time if they somehow get changed we'll have garbage on disk */

    msg_p->fs_id = sm_p->object_ref.fs_id;
    msg_p->handle = sm_p->object_ref.handle;
    msg_p->retry_flag = PVFS_MSGPAIR_RETRY;
    msg_p->comp_fn = setattr_msg_comp_fn;

    gossip_debug(
            GOSSIP_CLIENT_DEBUG, "setattr attr mask sent to server: 0x%x\n",
            (int)sm_p->u.setattr.sys_attr.mask);

    ret = PINT_cached_config_map_to_server(
        &msg_p->svr_addr, msg_p->handle, msg_p->fs_id);

    if (ret)
    {
        gossip_err("Failed to map meta server address\n");
        js_p->error_code = ret;
    }

    PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
    return SM_ACTION_COMPLETE;
}
Exemple #29
0
/*
 * PVFS2 ACL encode 
 * What this does is encode the posix_acl structure
 * into little-endian bytefirst using the htobmi* macros
 * and stuffs it into a buffer for storage.
 */
static void *
pvfs2_acl_encode(const struct posix_acl *acl, size_t *size)
{
    char *e, *ptr;
    size_t n;

    *size = acl->a_count * sizeof(pvfs2_acl_entry);
    gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_acl_encode: acl encoded %ld bytes "
            " (%d entries)\n", (long) *size, acl->a_count);
    e = (char *)kmalloc(*size, GFP_KERNEL);
    if (!e) 
    {
        gossip_err("pvfs2_acl_encode: Could not allocate %d bytes "
                "for acl encode\n", (int) *size);
        return ERR_PTR(-ENOMEM);
    }
    ptr = e;
    for (n = 0; n < acl->a_count; n++) 
    {
        pvfs2_acl_entry *entry = (pvfs2_acl_entry *)e;

        entry->p_tag  = htobmi32(acl->a_entries[n].e_tag);
        entry->p_perm = htobmi32(acl->a_entries[n].e_perm);
        switch (acl->a_entries[n].e_tag) 
        {
            case ACL_USER:
            case ACL_GROUP:
                entry->p_id = htobmi32(acl->a_entries[n].e_id);
                e += sizeof(pvfs2_acl_entry);
                break;
            case ACL_USER_OBJ:
            case ACL_GROUP_OBJ:
            case ACL_MASK:
            case ACL_OTHER:
                entry->p_id = htobmi32(ACL_UNDEFINED_ID);
                e += sizeof(pvfs2_acl_entry);
                break;

            default:
                gossip_err("pvfs2_acl_encode: bogus value of e_tag %d\n",
                        acl->a_entries[n].e_tag);
                goto fail;
        }
        gossip_debug(GOSSIP_ACL_DEBUG, "Encoded acl entry %zd "
                "(p_tag %d, p_perm %d, p_id %d)\n",
                n, acl->a_entries[n].e_tag, acl->a_entries[n].e_perm, 
                acl->a_entries[n].e_id);
    }
    return (char *) ptr;
fail:
    kfree(ptr);
    gossip_err("pvfs2_acl_encode: returning EINVAL\n");
    return ERR_PTR(-EINVAL);
}
Exemple #30
0
/* pvfs_bufmap_copy_from_user()
 *
 * copies data from a user space address to a mapped buffer
 *
 * returns 0 on success, -errno on failure
 */
int pvfs_bufmap_copy_from_user(int buffer_index, void __user *from, size_t size)
{
    size_t ret = 0, amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
    void __user *from_kaddr = from;
    void *to_kaddr = NULL;
    int to_page_index = 0;
    struct pvfs_bufmap_desc *to = &desc_array[buffer_index];
    char* tmp_printer = NULL;
    int tmp_int = 0;

    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_from_user: from %p, index %d, "
                "size %zd\n", from, buffer_index, size);

    down_read(&bufmap_init_sem);
    if (bufmap_init == 0)
    {
        gossip_err("pvfs_bufmap_copy_from_user: not yet "
                    "initialized.\n");
        gossip_err("pvfs2: please confirm that pvfs2-client daemon is running.\n");
        up_read(&bufmap_init_sem);
        return -EIO;
    }

    while(amt_copied < size)
    {
        amt_remaining = (size - amt_copied);
        cur_copy_size =
            ((amt_remaining > PAGE_SIZE) ? PAGE_SIZE : amt_remaining);

        to_kaddr = pvfs2_kmap(to->page_array[to_page_index]);
        ret = copy_from_user(to_kaddr, from_kaddr, cur_copy_size);
        if (!tmp_printer)
        {
            tmp_printer = (char*)(to_kaddr);
            tmp_int += tmp_printer[0];
            gossip_debug(GOSSIP_BUFMAP_DEBUG, "First character (integer value) in pvfs_bufmap_copy_from_user: %d\n", tmp_int);
        }

        pvfs2_kunmap(to->page_array[to_page_index]);

        if (ret)
        {
            gossip_debug(GOSSIP_BUFMAP_DEBUG, "Failed to copy data from user space\n");
            up_read(&bufmap_init_sem);
            return -EFAULT;
        }

        from_kaddr += cur_copy_size;
        amt_copied += cur_copy_size;
        to_page_index++;
    }
    up_read(&bufmap_init_sem);
    return 0;
}