예제 #1
0
파일: file.c 프로젝트: 513855417/linux
static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
{
	struct file *file = iocb->ki_filp;
	loff_t pos;
	ssize_t rc;

	BUG_ON(iocb->private);

	gossip_debug(GOSSIP_FILE_DEBUG, "orangefs_file_write_iter\n");

	inode_lock(file->f_mapping->host);

	/* Make sure generic_write_checks sees an up to date inode size. */
	if (file->f_flags & O_APPEND) {
		rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1);
		if (rc == -ESTALE)
			rc = -EIO;
		if (rc) {
			gossip_err("%s: orangefs_inode_getattr failed, "
			    "rc:%zd:.\n", __func__, rc);
			goto out;
		}
	}

	if (file->f_pos > i_size_read(file->f_mapping->host))
		orangefs_i_size_write(file->f_mapping->host, file->f_pos);

	rc = generic_write_checks(iocb, iter);

	if (rc <= 0) {
		gossip_err("%s: generic_write_checks failed, rc:%zd:.\n",
			   __func__, rc);
		goto out;
	}

	/*
	 * if we are appending, generic_write_checks would have updated
	 * pos to the end of the file, so we will wait till now to set
	 * pos...
	 */
	pos = *(&iocb->ki_pos);

	rc = do_readv_writev(ORANGEFS_IO_WRITE,
			     file,
			     &pos,
			     iter);
	if (rc < 0) {
		gossip_err("%s: do_readv_writev failed, rc:%zd:.\n",
			   __func__, rc);
		goto out;
	}

	iocb->ki_pos = pos;
	g_orangefs_stats.writes++;

out:

	inode_unlock(file->f_mapping->host);
	return rc;
}
예제 #2
0
파일: file.c 프로젝트: 513855417/linux
/*
 * 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;
}
예제 #3
0
파일: acl.c 프로젝트: Goon83/SALB
/**
 * 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;
}
예제 #4
0
파일: acl.c 프로젝트: Goon83/SALB
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;
}
예제 #5
0
void dbpf_open_cache_initialize(void)
{
    int i = 0, ret = 0;

    gen_mutex_lock(&cache_mutex);

    /* run through preallocated cache elements to initialize
     * and put them on the free list
     */
    if (OPEN_CACHE_SIZE == 0)
    {
	gossip_err("Warning: dbpf_open_cache disabled.\n");
    }

    for (i = 0; i < OPEN_CACHE_SIZE; i++)
    {
        prealloc[i].fd = -1;
	qlist_add(&prealloc[i].queue_link, &free_list);
    }

    gen_mutex_unlock(&cache_mutex);

    /* Initialize and create the worker thread for threaded deletes */
    INIT_QLIST_HEAD(&dbpf_unlink_context.global_list);
    pthread_mutex_init(&dbpf_unlink_context.mutex, NULL);
    pthread_cond_init(&dbpf_unlink_context.data_available, NULL);
    ret = pthread_create(&dbpf_unlink_context.thread_id, NULL, unlink_bstream, (void*)&dbpf_unlink_context);
    if(ret)
    {
        gossip_err("dbpf_open_cache_initialize: failed [%d]\n", ret);
        return;
    }
}
예제 #6
0
/*
 * Used by both encode functions, request and response, to set
 * up the one buffer which will hold the encoded message.
 */
static int
encode_common(struct PINT_encoded_msg *target_msg, int maxsize)
{
    int ret = 0;
    void *buf = NULL;

    gossip_debug(GOSSIP_ENDECODE_DEBUG,"encode_common\n");
    /* this encoder always uses just one buffer */
    BF_ENCODE_TARGET_MSG_INIT(target_msg);

    /* allocate the max size buffer to avoid the work of calculating it */
    buf = (initializing_sizes ? malloc(maxsize) :
           BMI_memalloc(target_msg->dest, maxsize, BMI_SEND));
    if (!buf)
    {
        gossip_err("Error: failed to BMI_malloc memory for response.\n");
        gossip_err("Error: is BMI address %llu still valid?\n", llu(target_msg->dest));
	ret = -PVFS_ENOMEM;
	goto out;
    }

    target_msg->buffer_list[0] = buf;
    target_msg->alloc_size_list[0] = maxsize;
    target_msg->ptr_current = buf;

    /* generic header */
    memcpy(target_msg->ptr_current, le_bytefield_table.generic_header,
           PINT_ENC_GENERIC_HEADER_SIZE);
    target_msg->ptr_current += PINT_ENC_GENERIC_HEADER_SIZE;

 out:
    return ret;
}
예제 #7
0
파일: pvfs2-bufmap.c 프로젝트: Goon83/SALB
/*
 * 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;
}
예제 #8
0
static PINT_sm_action  test_recv_one_msg_f(
        struct PINT_smcb *smcb, job_status_s *js_p)
{
        struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
       	
	int ret;

	gossip_debug(GOSSIP_SERVER_DEBUG, "\n\n%s: entry\n\n", __func__);    
	

	s_op->msgarray_op.msgpair.max_resp_sz = PINT_encode_calc_max_size(
		PINT_ENCODE_RESP, 
		PVFS_SERV_WRITE_COMPLETION,
		ENCODING_LE_BFIELD);
	s_op->msgarray_op.msgpair.encoded_resp_p = BMI_memalloc(
		s_op->addr, //s_op->msgarray_op.msgpair.svr_addr,
		s_op->msgarray_op.msgpair.max_resp_sz,
		BMI_RECV);

	if (!s_op->msgarray_op.msgpair.encoded_resp_p)
	{
		gossip_err("BMI_memalloc (for write ack) failed\n");
		return -PVFS_ENOMEM;
	}
	//gossip_debug(GOSSIP_LB_DEBUG, "bmi memalloc success\n");
	
	/*
	  pre-post this recv with an infinite timeout and adjust it
	  after the flow completes since we don't know how long a flow
	  can take at this point
	*/ 
	ret = job_bmi_recv(
		s_op->addr, //s_op->msgarray_op.msgpair.svr_addr,
		s_op->msgarray_op.msgpair.encoded_resp_p,
		s_op->msgarray_op.msgpair.max_resp_sz,
		5,
		BMI_PRE_ALLOC,
		smcb, 
		IO_SM_PHASE_FINAL_ACK,
		js_p,
		&s_op->msgarray_op.msgpair.recv_id,
		server_job_context,
		JOB_TIMEOUT_INF, NULL);
	if (ret < 0)
	{
		gossip_err("job_bmi_recv (write ack) failed\n");
	}else{
		gossip_debug(GOSSIP_LB_DEBUG, "job_bmi_recv correct:ret = %d\n", ret);	
	} 

	return ret;
//	assert(ret == 0);
    
}
예제 #9
0
파일: pvfs2-bufmap.c 프로젝트: Goon83/SALB
/* 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;
}
예제 #10
0
파일: acl.c 프로젝트: Goon83/SALB
/*
 * 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);
}
예제 #11
0
파일: acl.c 프로젝트: Lyude/linux
struct posix_acl *orangefs_get_acl(struct inode *inode, int type)
{
	struct posix_acl *acl;
	int ret;
	char *key = NULL, *value = NULL;

	switch (type) {
	case ACL_TYPE_ACCESS:
		key = XATTR_NAME_POSIX_ACL_ACCESS;
		break;
	case ACL_TYPE_DEFAULT:
		key = XATTR_NAME_POSIX_ACL_DEFAULT;
		break;
	default:
		gossip_err("orangefs_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
	 * orangefs_inode_getxattr() to probe the length of the value, but
	 * I don't do that for now.
	 */
	value = kmalloc(ORANGEFS_MAX_XATTR_VALUELEN, GFP_KERNEL);
	if (!value)
		return ERR_PTR(-ENOMEM);

	gossip_debug(GOSSIP_ACL_DEBUG,
		     "inode %pU, key %s, type %d\n",
		     get_khandle_from_ino(inode),
		     key,
		     type);
	ret = orangefs_inode_getxattr(inode, key, value,
				      ORANGEFS_MAX_XATTR_VALUELEN);
	/* if the key exists, convert it to an in-memory rep */
	if (ret > 0) {
		acl = posix_acl_from_xattr(&init_user_ns, value, ret);
	} else if (ret == -ENODATA || ret == -ENOSYS) {
		acl = NULL;
	} else {
		gossip_err("inode %pU retrieving acl's failed with error %d\n",
			   get_khandle_from_ino(inode),
			   ret);
		acl = ERR_PTR(ret);
	}
	/* kfree(NULL) is safe, so don't worry if value ever got used */
	kfree(value);
	return acl;
}
예제 #12
0
파일: acl.c 프로젝트: Goon83/SALB
/*
 * Handles the case when a chmod is done for an inode that may have an
 * access control list.
 * The inode->i_mode field is updated to the desired value by the caller
 * before calling this function which returns 0 on success and a -ve
 * number on failure.
 */
int pvfs2_acl_chmod(struct inode *inode)
{
    struct posix_acl *acl, *clone;
    int error;

    if (get_acl_flag(inode) == 0)
    {
        gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_acl_chmod: ACL options "
                "disabled on this FS!\n");
        return 0;
    }
    if (S_ISLNK(inode->i_mode))
    {
        gossip_err("pvfs2_acl_chmod: operation not permitted on symlink!\n");
        error = -EACCES;
        goto out;
    }
    acl = pvfs2_get_acl(inode, ACL_TYPE_ACCESS);
    if (IS_ERR(acl))
    {
        error = PTR_ERR(acl);
        gossip_err("pvfs2_acl_chmod: get acl (access) failed with %d\n", error);
        goto out;
    }
    if(!acl)
    {
        error = 0;
        goto out;
    }
    clone = posix_acl_clone(acl, GFP_KERNEL);
    posix_acl_release(acl);
    if (!clone)
    {
        gossip_err("pvfs2_acl_chmod failed with ENOMEM\n");
        error = -ENOMEM;
        goto out;
    }
    error = posix_acl_chmod_masq(clone, inode->i_mode);
    if (!error)
    {
        error = pvfs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
        gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_acl_chmod: pvfs2 set acl "
                "(access) returned %d\n", error);
    }
    posix_acl_release(clone);
out:
    return error;
}
예제 #13
0
파일: super.c 프로젝트: 020gzh/linux
static struct inode *orangefs_alloc_inode(struct super_block *sb)
{
	struct orangefs_inode_s *orangefs_inode;

	orangefs_inode = kmem_cache_alloc(orangefs_inode_cache, GFP_KERNEL);
	if (orangefs_inode == NULL) {
		gossip_err("Failed to allocate orangefs_inode\n");
		return NULL;
	}

	/*
	 * We want to clear everything except for rw_semaphore and the
	 * vfs_inode.
	 */
	memset(&orangefs_inode->refn.khandle, 0, 16);
	orangefs_inode->refn.fs_id = ORANGEFS_FS_ID_NULL;
	orangefs_inode->last_failed_block_index_read = 0;
	memset(orangefs_inode->link_target, 0, sizeof(orangefs_inode->link_target));
	orangefs_inode->pinode_flags = 0;

	gossip_debug(GOSSIP_SUPER_DEBUG,
		     "orangefs_alloc_inode: allocated %p\n",
		     &orangefs_inode->vfs_inode);
	return &orangefs_inode->vfs_inode;
}
예제 #14
0
파일: acl.c 프로젝트: Lyude/linux
int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
	int error;
	struct iattr iattr;
	int rc;

	if (type == ACL_TYPE_ACCESS && acl) {
		/*
		 * posix_acl_update_mode checks to see if the permissions
		 * described by the ACL can be encoded into the
		 * object's mode. If so, it sets "acl" to NULL
		 * and "mode" to the new desired value. It is up to
		 * us to propagate the new mode back to the server...
		 */
		error = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
		if (error) {
			gossip_err("%s: posix_acl_update_mode err: %d\n",
				   __func__,
				   error);
			return error;
		}

		if (acl) {
			rc = __orangefs_set_acl(inode, acl, type);
		} else {
			iattr.ia_valid = ATTR_MODE;
			rc = orangefs_inode_setattr(inode, &iattr);
		}

		return rc;

	} else {
		return -EINVAL;
	}
}
예제 #15
0
파일: acl.c 프로젝트: Goon83/SALB
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;
}
예제 #16
0
파일: msgpairarray.c 프로젝트: Goon83/SALB
/* PINT_serv_msgpair_array_resolve_addrs()
 *
 * fills in BMI address of server for each entry in the msgpair array,
 * based on the handle and fsid
 *
 * returns 0 on success, -PVFS_error on failure
 */
int PINT_serv_msgpairarray_resolve_addrs(
    PINT_sm_msgarray_op *mop)
{
    int i = 0;
    int ret = -PVFS_EINVAL;

    if ((mop->count > 0) && mop->msgarray)
    {
        for(i = 0; i < mop->count; i++)
        {
            PINT_sm_msgpair_state *msg_p = &mop->msgarray[i];
            assert(msg_p);

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

            if (ret != 0)
            {
                gossip_err("Failed to map server address to handle\n");
                break;
            }

            gossip_debug(GOSSIP_MSGPAIR_DEBUG,
                         " mapped handle %llu to server %lld\n",
                         llu(msg_p->handle), lld(msg_p->svr_addr));
        }
    }
    return ret;
}
예제 #17
0
파일: remove.c 프로젝트: Goon83/SALB
static PINT_sm_action remove_datafile_remove_failure(
        struct PINT_smcb *smcb, job_status_s *js_p)
{
    struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
    gossip_err("Error: failed removing one or more datafiles associated with the meta handle %llu\n", llu(sm_p->object_ref.handle));
    HANDLE_REMOVE_ERROR("datafile_remove_failure");
    return SM_ACTION_COMPLETE;
}
예제 #18
0
static int queues_post(struct PINT_manager_s *manager,
                       PINT_worker_inst *inst,
                       PINT_queue_id id,
                       PINT_operation_t *operation)
{
    struct PINT_worker_queues_s *w;
    int ret;
    PINT_worker_id wid;
    struct PINT_queue_s *queue;
    PINT_queue_id queue_id;

    w = &inst->queues;

    gen_mutex_lock(&w->mutex);

    if(qlist_empty(&w->queues))
    {
        gossip_err("%s: cannot post an operation without first adding queues "
                   "to the queue worker\n", __func__);
        gen_mutex_unlock(&w->mutex);
        return -PVFS_EINVAL;
    }

    id_gen_fast_register(&wid, w);

    /* if the queue_id is zero, then assume that there's
     * only one queue maintained by this worker and use that
     */
    if(id == 0)
    {
        /* a dirty hack to check that the list of queues only has one element */
        if(w->queues.next->next != &w->queues)
        {
            gossip_err("%s: no queue id was specified and there's more than "
                       "one queue being managed by this worker\n", __func__);
            gen_mutex_unlock(&w->mutex);
            return -PVFS_EINVAL;
        }

        /* there must be only one queue, so just use that */
        queue = qlist_entry(w->queues.next, struct PINT_queue_s, link);
        queue_id = queue->id;

    }
    else
    {
예제 #19
0
파일: pvfs2-bufmap.c 프로젝트: Goon83/SALB
/* pvfs_bufmap_copy_to_user()
 *
 * copies data out of a mapped buffer to a user space address
 *
 * returns 0 on success, -errno on failure
 */
int pvfs_bufmap_copy_to_user(void __user *to, int buffer_index, size_t size)
{
    size_t ret = 0, amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
    int from_page_index = 0;
    void *from_kaddr = NULL;
    void __user *to_kaddr = to;
    struct pvfs_bufmap_desc *from = &desc_array[buffer_index];

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

    down_read(&bufmap_init_sem);
    if (bufmap_init == 0)
    {
        gossip_err("pvfs_bufmap_copy_to_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);

        from_kaddr = pvfs2_kmap(from->page_array[from_page_index]);
        ret = copy_to_user(to_kaddr, from_kaddr, cur_copy_size);
        pvfs2_kunmap(from->page_array[from_page_index]);

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

        to_kaddr += cur_copy_size;
        amt_copied += cur_copy_size;
        from_page_index++;
    }
    up_read(&bufmap_init_sem);
    return 0;
}
예제 #20
0
파일: file.c 프로젝트: 513855417/linux
/*
 * 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;
}
예제 #21
0
/* perf_update_error()
 *
 * cleans up any resources consumed by this state machine and ends
 * execution of the machine
 */
static PINT_sm_action perf_update_error(
        struct PINT_smcb *smcb, job_status_s *js_p)
{
    gossip_err("Error: stopping server performance monitoring.\n");

    PINT_perf_finalize(PINT_server_pc);

    return(server_state_machine_complete(smcb));
}
예제 #22
0
파일: inode.c 프로젝트: acton393/linux
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;
}
예제 #23
0
파일: op-list.c 프로젝트: kandycs/PVFS-AS
/*
 * op_list_dump()
 *
 * dumps the contents of the op list to stderr
 *
 * returns 0 on success, -errno on failure
 */
void op_list_dump(op_list_p olp)
{
    op_list_p tmp_entry = NULL;

    gossip_err("op_list_dump():\n");
    qlist_for_each(tmp_entry, olp)
    {
	gossip_print_op(qlist_entry(tmp_entry, struct method_op,
				    op_list_entry));
    }
예제 #24
0
파일: sys-readdir.c 프로젝트: Goon83/SALB
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;
}
예제 #25
0
/* socket_collection_init()
 * 
 * creates a new socket collection.  It also acquires the server socket
 * from the caller if it is available.  Passing in a negative value
 * indicates that this is being used on a client node and there is no
 * server socket.
 *
 * returns a pointer to the collection on success, NULL on failure.
 */
socket_collection_p BMI_socket_collection_init(int new_server_socket)
{
    struct epoll_event event;
    socket_collection_p tmp_scp = NULL;
    int ret = -1;

    tmp_scp = (struct socket_collection*) malloc(sizeof(struct
	socket_collection));
    if(!tmp_scp)
    {
	return(NULL);
    }

    memset(tmp_scp, 0, sizeof(struct socket_collection));

    tmp_scp->epfd = epoll_create(EPOLL_CREATE_SIZE);
    if(tmp_scp->epfd < 0)
    {
        gossip_err("Error: epoll_create() failure: %s.\n", strerror(errno));
        free(tmp_scp);
        return(NULL);
    }

    tmp_scp->server_socket = new_server_socket;

    if(new_server_socket > -1)
    {
        memset(&event, 0, sizeof(event));
        event.events = (EPOLLIN|EPOLLERR|EPOLLHUP);
        event.data.ptr = NULL;
        ret = epoll_ctl(tmp_scp->epfd, EPOLL_CTL_ADD, new_server_socket,
            &event);
        if(ret < 0 && errno != EEXIST)
        {
            gossip_err("Error: epoll_ctl() failure: %s.\n", strerror(errno));
            free(tmp_scp);
            return(NULL);
        }
    }

    return (tmp_scp);
}
예제 #26
0
파일: acl.c 프로젝트: Goon83/SALB
static int pvfs2_xattr_set_acl_default(struct inode *inode, 
        const char *name, const void *buffer, size_t size, int flags)
{
    gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_xattr_set_acl_default: %s\n", name);
    if (strcmp(name, "") != 0)
    {
        gossip_err("set_acl_default invalid name %s\n", name);
        return -EINVAL;
    }
    return pvfs2_xattr_set_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
}
예제 #27
0
파일: acl.c 프로젝트: Lyude/linux
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;
}
예제 #28
0
파일: acl.c 프로젝트: Goon83/SALB
static int pvfs2_xattr_get_acl_access(struct inode *inode,
        const char *name, void *buffer, size_t size)
{
    gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_xattr_get_acl_access %s\n", name);
    if (strcmp(name, "") != 0)
    {
        gossip_err("get_acl_access invalid name %s\n", name);
        return -EINVAL;
    }
    return pvfs2_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
}
예제 #29
0
파일: sys-setattr.c 프로젝트: Goon83/SALB
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;
}
예제 #30
0
파일: msgpairarray.c 프로젝트: Goon83/SALB
int PINT_serv_decode_resp(PVFS_fs_id fs_id,
                          void *encoded_resp_p,
                          struct PINT_decoded_msg *decoded_resp_p,
                          PVFS_BMI_addr_t *svr_addr_p,
                          int actual_resp_sz,
                          struct PVFS_server_resp **resp_out_pp)
{
    int ret = -1, server_type = 0;
    const char *server_string;

    ret = PINT_decode(encoded_resp_p, PINT_DECODE_RESP,
                      decoded_resp_p, /* holds data on decoded resp */
                      *svr_addr_p, actual_resp_sz);
    if (ret > -1)
    {
        *resp_out_pp = (struct PVFS_server_resp *)decoded_resp_p->buffer;
        if ((*resp_out_pp)->op == PVFS_SERV_PROTO_ERROR)
        {

            gossip_err("Error: server does not seem to understand "
                       "the protocol that this client is using.\n");
            gossip_err("   Please check server logs for more "
                       "information.\n");

            if (fs_id != PVFS_FS_ID_NULL)
            {
                server_string = PINT_cached_config_map_addr(
                    fs_id, *svr_addr_p, &server_type);
                gossip_err("   Server: %s.\n", server_string);
            }
            else
            {
                gossip_err("   Server: unknown; probably an error "
                           "contacting server listed in pvfs2tab "
                           "file.\n");
            }
            return(-EPROTONOSUPPORT);
        }
    }
    return ret;
}