Esempio n. 1
0
static int alloc_requests(struct eth_dev *dev, struct gether *link, unsigned n)
{
	int	status;

	spin_lock(&dev->req_lock);
	status = prealloc(&dev->tx_reqs, link->in_ep, n);
	if (status < 0)
		goto fail;
	status = prealloc(&dev->rx_reqs, link->out_ep, n);
	if (status < 0)
		goto fail;
	goto done;
fail:
	ether_printk(0,"uether::%s can't alloc request\n",__func__);
done:
	spin_unlock(&dev->req_lock);
	return status;
}
Esempio n. 2
0
static int alloc_requests(struct eth_dev *dev, struct gether *link, unsigned n)
{
    int	status;

    spin_lock(&dev->req_lock);
    status = prealloc(&dev->tx_reqs, link->in_ep, n);
    if (status < 0)
        goto fail;
    status = prealloc(&dev->rx_reqs, link->out_ep, n);
    if (status < 0)
        goto fail;
    goto done;
fail:
    DBG(dev, "can't alloc requests\n");
done:
    spin_unlock(&dev->req_lock);
    return status;
}
USObstacleModelProvider::USObstacleModelProvider()
: gridSize(2.f * (maxDistance + obstacleThickness +
                  std::max(std::max(std::max(leftToLeft.translation.abs(), leftToRight.translation.abs()),
                                    rightToLeft.translation.abs()), rightToRight.translation.abs()))),
  grid(gridSize, gridSizeInCells, gridSizeInCells, initCell),
  lastUSTimeStamp(0), lastDecay(0), lastTimePenalized(0),
  lastGameState(STATE_INITIAL), lastPenaltyState(PENALTY_NONE)
{
  prealloc();
}
Esempio n. 4
0
File: farm.c Progetto: yamt/sheepdog
static int farm_write(uint64_t oid, struct siocb *iocb, int create)
{
	int flags = def_open_flags, fd, ret = SD_RES_SUCCESS;
	char path[PATH_MAX];
	ssize_t size;

	if (iocb->epoch < sys_epoch()) {
		dprintf("%"PRIu32" sys %"PRIu32"\n", iocb->epoch, sys_epoch());
		return SD_RES_OLD_NODE_VER;
	}
	if (!is_data_obj(oid))
		flags &= ~O_DIRECT;

	if (create)
		flags |= O_CREAT | O_TRUNC;

	sprintf(path, "%s%016"PRIx64, obj_path, oid);
	fd = open(path, flags, def_fmode);
	if (fd < 0)
		return err_to_sderr(oid, errno);

	if (flock(fd, LOCK_EX) < 0) {
		ret = SD_RES_EIO;
		eprintf("%m\n");
		goto out;
	}
	if (create && !(iocb->flags & SD_FLAG_CMD_COW)) {
		ret = prealloc(fd, get_objsize(oid));
		if (ret != SD_RES_SUCCESS) {
			if (flock(fd, LOCK_UN) < 0) {
				ret = SD_RES_EIO;
				eprintf("%m\n");
				goto out;
			}
			goto out;
		}
	}
	size = xpwrite(fd, iocb->buf, iocb->length, iocb->offset);
	if (flock(fd, LOCK_UN) < 0) {
		ret = SD_RES_EIO;
		eprintf("%m\n");
		goto out;
	}
	if (size != iocb->length) {
		eprintf("%m\n");
		ret = SD_RES_EIO;
		goto out;
	}

	trunk_update_entry(oid);
out:
	close(fd);
	return ret;
}
Esempio n. 5
0
int default_create_and_write(uint64_t oid, struct siocb *iocb)
{
	char path[PATH_MAX], tmp_path[PATH_MAX];
	int flags = get_open_flags(oid, true);
	int ret, fd;
	uint32_t len = iocb->length;

	get_obj_path(oid, path);
	get_tmp_obj_path(oid, tmp_path);

	fd = open(tmp_path, flags, def_fmode);
	if (fd < 0) {
		if (errno == EEXIST)
			/* This happens if node membership changes during object
			 * creation; while gateway retries a CREATE request,
			 * recovery process could also recover the object at the
			 * same time.  They should try to write the same date,
			 * so it is okay to simply return success here. */
			dprintf("%s exists\n", tmp_path);
			return SD_RES_SUCCESS;

		eprintf("failed to open %s: %m\n", tmp_path);
		return err_to_sderr(oid, errno);
	}

	if (iocb->offset != 0 || iocb->length != get_objsize(oid)) {
		ret = prealloc(fd, get_objsize(oid));
		if (ret != SD_RES_SUCCESS)
			goto out;
	}

	ret = xpwrite(fd, iocb->buf, len, iocb->offset);
	if (ret != len) {
		eprintf("failed to write object. %m\n");
		ret = err_to_sderr(oid, errno);
		goto out;
	}

	ret = rename(tmp_path, path);
	if (ret < 0) {
		eprintf("failed to rename %s to %s: %m\n", tmp_path, path);
		ret = err_to_sderr(oid, errno);
		goto out;
	}
	dprintf("%"PRIx64"\n", oid);
	ret = SD_RES_SUCCESS;
out:
	if (ret != SD_RES_SUCCESS)
		unlink(tmp_path);
	close(fd);
	return ret;
}
Esempio n. 6
0
static void
test_realloc(size_t org, size_t dest)
{
	int err;
	struct palloc_heap *heap = &mock_pop->heap;
	err = pmalloc(mock_pop, &addr->ptr, org);
	UT_ASSERTeq(err, 0);
	UT_ASSERT(palloc_usable_size(heap, addr->ptr) >= org);
	err = prealloc(mock_pop, &addr->ptr, dest);
	UT_ASSERTeq(err, 0);
	UT_ASSERT(palloc_usable_size(heap, addr->ptr) >= dest);
	pfree(mock_pop, &addr->ptr);
}
Esempio n. 7
0
static int create_journal_file(const char *root, const char *name)
{
	int fd, flags = O_DSYNC | O_RDWR | O_TRUNC | O_CREAT | O_DIRECT;
	char path[PATH_MAX];

	snprintf(path, sizeof(path), "%s/%s", root, name);
	fd = open(path, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
	if (fd < 0) {
		sd_err("open %s %m", name);
		return -1;
	}
	if (prealloc(fd, jfile_size) < 0) {
		sd_err("prealloc %s %m", name);
		return -1;
	}

	return fd;
}
Esempio n. 8
0
    FileDescriptor::FileDescriptor (const std::string& fname,
                                    size_t             length,
                                    bool               allocate,
                                    bool               sync_)
        throw (gu::Exception)
        : value (open (fname.c_str(), CREATE_FLAGS, S_IRUSR | S_IWUSR)),
          name  (fname),
          size  (length),
          sync  (sync_)
    {
        constructor_common();

        off_t const current_size(lseek (value, 0, SEEK_END));

        if (current_size < size)
        {
            if (allocate)
            {
                // reserve space that hasn't been reserved
                prealloc (current_size);
            }
            else
            {
                write_byte (size - 1); // reserve size
            }
        }
        else if (current_size > size)
        {
            log_info << "Truncating '" << name << "' to " << size << " bytes.";

            if (ftruncate(value, size))
            {
                gu_throw_error(errno) << "Failed to truncate '" << name
                                      << "' to " << size << " bytes.";
            }
        }
        else
        {
            log_info << "Reusing existing '" << name << "'.";
        }
    }
Esempio n. 9
0
File: alloc.c Progetto: Karm/unbound
alloc_special_t* 
alloc_special_obtain(struct alloc_cache* alloc)
{
	alloc_special_t* p;
	log_assert(alloc);
	/* see if in local cache */
	if(alloc->quar) {
		p = alloc->quar;
		alloc->quar = alloc_special_next(p);
		alloc->num_quar--;
		p->id = alloc_get_id(alloc);
		return p;
	}
	/* see if in global cache */
	if(alloc->super) {
		/* could maybe grab alloc_max/2 entries in one go,
		 * but really, isn't that just as fast as this code? */
		lock_quick_lock(&alloc->super->lock);
		if((p = alloc->super->quar)) {
			alloc->super->quar = alloc_special_next(p);
			alloc->super->num_quar--;
		}
		lock_quick_unlock(&alloc->super->lock);
		if(p) {
			p->id = alloc_get_id(alloc);
			return p;
		}
	}
	/* allocate new */
	prealloc(alloc);
	if(!(p = (alloc_special_t*)malloc(sizeof(alloc_special_t)))) {
		log_err("alloc_special_obtain: out of memory");
		return NULL;
	}
	alloc_setup_special(p);
	p->id = alloc_get_id(alloc);
	return p;
}
Esempio n. 10
0
int default_create_and_write(uint64_t oid, const struct siocb *iocb)
{
	char path[PATH_MAX], tmp_path[PATH_MAX];
	int flags = prepare_iocb(oid, iocb, true);
	int ret, fd;
	uint32_t len = iocb->length;
	size_t obj_size;

	sd_debug("%"PRIx64, oid);
	get_store_path(oid, iocb->ec_index, path);
	get_store_tmp_path(oid, iocb->ec_index, tmp_path);
	fd = open(tmp_path, flags, sd_def_fmode);
	if (fd < 0) {
		if (errno == EEXIST) {
			/*
			 * This happens if node membership changes during object
			 * creation; while gateway retries a CREATE request,
			 * recovery process could also recover the object at the
			 * same time.  They should try to write the same date,
			 * so it is okay to simply return success here.
			 */
			sd_debug("%s exists", tmp_path);
			return SD_RES_SUCCESS;
		}

		sd_err("failed to open %s: %m", tmp_path);
		return err_to_sderr(path, oid, errno);
	}

	obj_size = get_store_objsize(oid);
	ret = prealloc(fd, obj_size);
	if (ret < 0) {
	          ret = err_to_sderr(path, oid, errno);
		  goto out;
	}

	ret = xpwrite(fd, iocb->buf, len, iocb->offset);
	if (ret != len) {
		sd_err("failed to write object. %m");
		ret = err_to_sderr(path, oid, errno);
		goto out;
	}

	/*
	 * Modern FS like ext4, xfs defaults to automatic syncing of files after
	 * replace-via-rename and replace-via-truncate operations. So rename
	 * without fsync() is actually safe.
	 */
	ret = rename(tmp_path, path);
	if (ret < 0) {
		sd_err("failed to rename %s to %s: %m", tmp_path, path);
		ret = err_to_sderr(path, oid, errno);
		goto out;
	}

	ret = SD_RES_SUCCESS;
	objlist_cache_insert(oid);
out:
	if (ret != SD_RES_SUCCESS && unlink(tmp_path) != 0)
		sd_err("failed to unlink %s: %m", tmp_path);
	close(fd);
	return ret;
}
Esempio n. 11
0
int default_create_and_write(uint64_t oid, const struct siocb *iocb)
{
	char path[PATH_MAX], tmp_path[PATH_MAX];
	int flags = prepare_iocb(oid, iocb, true);
	int ret, fd;
	uint32_t len = iocb->length;
	size_t obj_size;
	uint64_t offset = iocb->offset;

	sd_debug("%"PRIx64, oid);
	get_store_path(oid, iocb->ec_index, path);
	get_store_tmp_path(oid, iocb->ec_index, tmp_path);

	if (uatomic_is_true(&sys->use_journal) &&
	    journal_write_store(oid, iocb->buf, iocb->length,
				iocb->offset, true)
	    != SD_RES_SUCCESS) {
		sd_err("turn off journaling");
		uatomic_set_false(&sys->use_journal);
		flags |= O_DSYNC;
		sync();
	}

	fd = open(tmp_path, flags, sd_def_fmode);
	if (fd < 0) {
		if (errno == EEXIST) {
			/*
			 * This happens if node membership changes during object
			 * creation; while gateway retries a CREATE request,
			 * recovery process could also recover the object at the
			 * same time.  They should try to write the same date,
			 * so it is okay to simply return success here.
			 */
			sd_debug("%s exists", tmp_path);
			return SD_RES_SUCCESS;
		}

		sd_err("failed to open %s: %m", tmp_path);
		return err_to_sderr(path, oid, errno);
	}

	obj_size = get_store_objsize(oid);

	trim_zero_blocks(iocb->buf, &offset, &len);

	if (offset != 0 || len != get_objsize(oid)) {
		if (is_sparse_object(oid))
			ret = xftruncate(fd, obj_size);
		else
			ret = prealloc(fd, obj_size);
		if (ret < 0) {
			ret = err_to_sderr(path, oid, errno);
			goto out;
		}
	}

	ret = xpwrite(fd, iocb->buf, len, offset);
	if (ret != len) {
		sd_err("failed to write object. %m");
		ret = err_to_sderr(path, oid, errno);
		goto out;
	}

	ret = rename(tmp_path, path);
	if (ret < 0) {
		sd_err("failed to rename %s to %s: %m", tmp_path, path);
		ret = err_to_sderr(path, oid, errno);
		goto out;
	}

	ret = SD_RES_SUCCESS;
	objlist_cache_insert(oid);
out:
	if (ret != SD_RES_SUCCESS)
		unlink(tmp_path);
	close(fd);
	return ret;
}
static pthread_rwlock_t g_pmp_rwlock = PTHREAD_RWLOCK_INITIALIZER;

/******************************************************************************
 ** JNI implementations
 *****************************************************************************/

JNIEXPORT
jlong JNICALL Java_org_apache_mnemonic_service_memory_internal_PMemServiceImpl_nallocate(JNIEnv* env,
    jobject this, jlong id, jlong size, jboolean initzero) {
  PMPool *pool;
  jlong ret = 0L;
  void *p;
  pthread_rwlock_rdlock(&g_pmp_rwlock);
  pool = g_pmpool_arr + id;
  p = prealloc(pool, NULL, size, initzero ? 1 : 0);
  if (NULL != p) {
    ret = addr_to_java(p);
  }
  pthread_rwlock_unlock(&g_pmp_rwlock);
  return ret;
}

JNIEXPORT
jlong JNICALL Java_org_apache_mnemonic_service_memory_internal_PMemServiceImpl_nreallocate(JNIEnv* env,
    jobject this, jlong id, jlong addr, jlong size, jboolean initzero) {
  PMPool *pool;
  jlong ret = 0L;
  void *p;
  pthread_rwlock_rdlock(&g_pmp_rwlock);
  pool = g_pmpool_arr + id;
Esempio n. 13
0
		}

		sd_err("failed to open %s: %m", tmp_path);
		return err_to_sderr(path, oid, errno);
	}

	if (ec) {
		uint8_t policy = iocb->copy_policy ?:
			get_vdi_copy_policy(oid_to_vid(oid));
		int d;
		ec_policy_to_dp(policy, &d, NULL);
		obj_size = SD_DATA_OBJ_SIZE / d;
	} else
		obj_size = get_objsize(oid);

	ret = prealloc(fd, obj_size);
	if (ret < 0) {
		ret = err_to_sderr(path, oid, errno);
		goto out;
	}

	ret = xpwrite(fd, iocb->buf, len, iocb->offset);
	if (ret != len) {
		sd_err("failed to write object. %m");
		ret = err_to_sderr(path, oid, errno);
		goto out;
	}

	ret = rename(tmp_path, path);
	if (ret < 0) {
		sd_err("failed to rename %s to %s: %m", tmp_path, path);
Esempio n. 14
0
int default_create_and_write(uint64_t oid, const struct siocb *iocb)
{
	char path[PATH_MAX], tmp_path[PATH_MAX];
	int flags = get_open_flags(oid, true, iocb->flags);
	int ret, fd;
	uint32_t len = iocb->length;

	get_obj_path(oid, path);
	get_tmp_obj_path(oid, tmp_path);

	if (uatomic_is_true(&sys->use_journal) &&
	    journal_file_write(oid, iocb->buf, iocb->length, iocb->offset, true)
	    != SD_RES_SUCCESS) {
		sd_eprintf("turn off journaling");
		uatomic_set_false(&sys->use_journal);
		flags |= O_DSYNC;
		sync();
	}

	fd = open(tmp_path, flags, def_fmode);
	if (fd < 0) {
		if (errno == EEXIST) {
			/*
			 * This happens if node membership changes during object
			 * creation; while gateway retries a CREATE request,
			 * recovery process could also recover the object at the
			 * same time.  They should try to write the same date,
			 * so it is okay to simply return success here.
			 */
			sd_dprintf("%s exists", tmp_path);
			return SD_RES_SUCCESS;
		}

		sd_eprintf("failed to open %s: %m", tmp_path);
		return err_to_sderr(oid, errno);
	}

	if (iocb->offset != 0 || iocb->length != get_objsize(oid)) {
		ret = prealloc(fd, get_objsize(oid));
		if (ret < 0) {
			ret = err_to_sderr(oid, errno);
			goto out;
		}
	}

	ret = xpwrite(fd, iocb->buf, len, iocb->offset);
	if (ret != len) {
		sd_eprintf("failed to write object. %m");
		ret = err_to_sderr(oid, errno);
		goto out;
	}

	ret = rename(tmp_path, path);
	if (ret < 0) {
		sd_eprintf("failed to rename %s to %s: %m", tmp_path, path);
		ret = err_to_sderr(oid, errno);
		goto out;
	}
	sd_dprintf("%"PRIx64, oid);
	ret = SD_RES_SUCCESS;
out:
	if (ret != SD_RES_SUCCESS)
		unlink(tmp_path);
	close(fd);
	return ret;
}
Esempio n. 15
0
void* run(void* arg)
{
	unsigned long i;
	char iamreader;
	int key; long t = (long) arg; long nbn;//same cache line for the best rand!
	double start, end;
	node_t **hd;
	lock_t *lck;

	set_affinity(t);

	/************ init *****************/
	thd_ins = 0;
	thd_del = 0;
	thd_sea = 0;
	nbmallocs = 0;
	nbretry = 0;
	nbrelink = 0;
	nbreprev = 0;
	nbfl = 0;
	thread=t;
	thd_nbupdaters=nbupdaters;
	setsignals();
	iamreader = t >= nbupdaters ? 1 : 0;
	if(!iamreader)	prealloc();
	mysrand(t^time(NULL));
	/************** init done **************/

	/************** barrier ****************/
	atomic_xadd4(&ready, 1);
	while(!go) memory_barrier();

	/******************* START ****************/
	start = d_gettimeofday();
#ifdef RCU
	rcu_register_thread();
#endif

	i=0;
	do{
		key = myrand()%nbkeys;
		//key = rand_r(&thd_seed)%nbthreads;
		//key = (t+key)%nbkeys;
		//key = random() % nbkeys;
		//if(i%100000) printf("%d %d\n", thread, key);

		get_buckets(key, &hd, &lck);
		if(iamreader)
		{
			thd_sea += search(key, hd, lck);
			if(i>= NB_TEST) break;
		}
		else
		{
			if(i%2)
				thd_ins += insert(key, hd, lck);
			else
				thd_del += delete(key, hd, lck);
			if(done) {
				//printf("writer stopped\n");
				break;
			}
		}
		//if(!(i%10000)) 
			//printf("%d loop %d\n", t, i);
#ifdef RCU_QSBR
#if ((defined RCU_QSBR_ACCELERATE) || (defined RCU_Q10))
#ifdef RCU_Q10
		if(!(i%10)) 
#else
		if(!(i%100)) 
#endif
#endif
			rcu_quiescent_state();
#endif
	}while(++i);

#ifdef RCU
	//if(!iamreader) rcu_barrier();
	//printf("iamreader %d, ops %d\n", iamreader, i);
	rcu_unregister_thread();
#endif

	end = d_gettimeofday(); 
	/******************* END ****************/

	
	//number of ops done
	thd_ops[t] = i;
	
	//printf("nbmallocs %g\n", nbmallocs);
	thd_mallocs[t] = nbmallocs;
	thd_retry[t] = nbretry;
	thd_relink[t] = nbrelink;
	thd_reprev[t] = nbreprev;

	//if(t==0) printf("%lu | nbblocked %g\n", t, nbblockeds);
#ifdef RCU
	thd_blockeds[t] = atomic_read_ptr(&rcublockeds);
#else
	thd_blockeds[t] = nbblockeds;
#endif

	//average time per ops
	avg_time[t] = (((end - start))/i);

	//total time
	thd_time[t] = (end - start);

	suc_ins[t] = thd_ins;
	suc_sea[t] = thd_sea;
	suc_del[t] = thd_del;

	return NULL;
}
Esempio n. 16
0
void ADIOI_HFS_Fcntl(ADIO_File fd, int flag, ADIO_Fcntl_t *fcntl_struct, int *error_code)
{
    int  i, ntimes, err;
    ADIO_Offset curr_fsize, alloc_size, size, len, done;
    ADIO_Status status;
    char *buf;
#ifndef PRINT_ERR_MSG
    static char myname[] = "ADIOI_HFS_FCNTL";
#endif

    switch(flag) {
    case ADIO_FCNTL_GET_FSIZE:
	fcntl_struct->fsize = lseek64(fd->fd_sys, 0, SEEK_END);
#ifdef HPUX
	if (fd->fp_sys_posn != -1) 
	     lseek64(fd->fd_sys, fd->fp_sys_posn, SEEK_SET);
/* not required in SPPUX since there we use pread/pwrite */
#endif
	if (fcntl_struct->fsize == -1) {
#ifdef MPICH2
	    *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", 
		"**io %s", strerror(errno));
#elif defined(PRINT_ERR_MSG)
		*error_code = MPI_ERR_UNKNOWN;
#else /* MPICH-1 */
		*error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
				myname, "I/O Error", "%s", strerror(errno));
		ADIOI_Error(fd, *error_code, myname);	    
#endif
	}
	else *error_code = MPI_SUCCESS;
	break;

    case ADIO_FCNTL_SET_DISKSPACE:
	/* will be called by one process only */

#ifdef HPUX
	err = prealloc64(fd->fd_sys, fcntl_struct->diskspace);
	/* prealloc64 works only if file is of zero length */
	if (err && (errno != ENOTEMPTY)) {
#ifdef MPICH2
	    *error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", 
		"**io %s", strerror(errno));
#elif defined(PRINT_ERR_MSG)
	    *error_code = MPI_ERR_UNKNOWN;
#else
	    *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
			      myname, "I/O Error", "%s", strerror(errno));
	    ADIOI_Error(fd, *error_code, myname);
#endif
	    return;
	}
	if (err && (errno == ENOTEMPTY)) {
#endif

#ifdef SPPUX
	/* SPPUX has no prealloc64. therefore, use prealloc
           if size < (2GB - 1), otherwise use long method. */
        if (fcntl_struct->diskspace <= 2147483647) {
	    err = prealloc(fd->fd_sys, (off_t) fcntl_struct->diskspace);
	    if (err && (errno != ENOTEMPTY)) {
#ifdef MPICH2
		*error_code = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io",
		    "**io %s", strerror(errno));
#elif defined(PRINT_ERR_MSG)
    	        *error_code = MPI_ERR_UNKNOWN;
#else
		*error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
			      myname, "I/O Error", "%s", strerror(errno));
		ADIOI_Error(fd, *error_code, myname);
#endif
	        return;
	    }
	}    

	if ((fcntl_struct->diskspace > 2147483647) || 
	    (err && (errno == ENOTEMPTY))) {
#endif
		ADIOI_GEN_Prealloc(fd,fcntl_struct->diskspace, error_code);
	    }
	    ADIOI_Free(buf);
#ifdef HPUX
	    if (fd->fp_sys_posn != -1) 
		lseek64(fd->fd_sys, fd->fp_sys_posn, SEEK_SET);
	    /* not required in SPPUX since there we use pread/pwrite */
#endif
	}
	*error_code = MPI_SUCCESS;
	break;

    case ADIO_FCNTL_SET_ATOMICITY:
	fd->atomicity = (fcntl_struct->atomicity == 0) ? 0 : 1;
	*error_code = MPI_SUCCESS;
	break;

    default:
	FPRINTF(stderr, "Unknown flag passed to ADIOI_HFS_Fcntl\n");
	MPI_Abort(MPI_COMM_WORLD, 1);
    }
}
Esempio n. 17
0
void ADIOI_HFS_Fcntl(ADIO_File fd, int flag, ADIO_Fcntl_t *fcntl_struct, int *error_code)
{
    MPI_Datatype copy_etype, copy_filetype;
    int combiner, i, j, k, filetype_is_contig, ntimes, err;
    ADIOI_Flatlist_node *flat_file;
    ADIO_Offset curr_fsize, alloc_size, size, len, done;
    ADIO_Status status;
    char *buf;
#ifndef PRINT_ERR_MSG
    static char myname[] = "ADIOI_HFS_FCNTL";
#endif

    switch(flag) {
    case ADIO_FCNTL_SET_VIEW:
        /* free copies of old etypes and filetypes and delete flattened 
           version of filetype if necessary */

	MPI_Type_get_envelope(fd->etype, &i, &j, &k, &combiner);
	if (combiner != MPI_COMBINER_NAMED) MPI_Type_free(&(fd->etype));

	ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
	if (!filetype_is_contig) ADIOI_Delete_flattened(fd->filetype);

	MPI_Type_get_envelope(fd->filetype, &i, &j, &k, &combiner);
	if (combiner != MPI_COMBINER_NAMED) MPI_Type_free(&(fd->filetype));

	/* set new info */
	ADIO_SetInfo(fd, fcntl_struct->info, &err);

        /* set new etypes and filetypes */

	MPI_Type_get_envelope(fcntl_struct->etype, &i, &j, &k, &combiner);
	if (combiner == MPI_COMBINER_NAMED) fd->etype = fcntl_struct->etype;
	else {
	    MPI_Type_contiguous(1, fcntl_struct->etype, &copy_etype);
	    MPI_Type_commit(&copy_etype);
	    fd->etype = copy_etype;
	}
	MPI_Type_get_envelope(fcntl_struct->filetype, &i, &j, &k, &combiner);
	if (combiner == MPI_COMBINER_NAMED) 
	    fd->filetype = fcntl_struct->filetype;
	else {
	    MPI_Type_contiguous(1, fcntl_struct->filetype, &copy_filetype);
	    MPI_Type_commit(&copy_filetype);
	    fd->filetype = copy_filetype;
	    ADIOI_Flatten_datatype(fd->filetype);
            /* this function will not flatten the filetype if it turns out
               to be all contiguous. */
	}

	MPI_Type_size(fd->etype, &(fd->etype_size));
	fd->disp = fcntl_struct->disp;

        /* reset MPI-IO file pointer to point to the first byte that can
           be accessed in this view. */

        ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
	if (filetype_is_contig) fd->fp_ind = fcntl_struct->disp;
	else {
	    flat_file = ADIOI_Flatlist;
	    while (flat_file->type != fd->filetype) 
		flat_file = flat_file->next;
	    for (i=0; i<flat_file->count; i++) {
		if (flat_file->blocklens[i]) {
		    fd->fp_ind = fcntl_struct->disp + flat_file->indices[i];
		    break;
		}
	    }
	}
	*error_code = MPI_SUCCESS;
	break;

    case ADIO_FCNTL_GET_FSIZE:
	fcntl_struct->fsize = lseek64(fd->fd_sys, 0, SEEK_END);
#ifdef PRINT_ERR_MSG
	*error_code = (fcntl_struct->fsize == -1) ? MPI_ERR_UNKNOWN : MPI_SUCCESS;
#else
    if (fcntl_struct->fsize == -1) {
	*error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
			      myname, "I/O Error", "%s", strerror(errno));
	ADIOI_Error(fd, *error_code, myname);	    
    }
    else *error_code = MPI_SUCCESS;
#endif
	break;

    case ADIO_FCNTL_SET_DISKSPACE:
	/* will be called by one process only */

#ifdef SPPUX
	/* SPPUX has no prealloc64. therefore, use prealloc
           if size < (2GB - 1), otherwise use long method. */
        if (fcntl_struct->diskspace <= 2147483647) {
	    err = prealloc(fd->fd_sys, (off_t) fcntl_struct->diskspace);
	    if (err && (errno != ENOTEMPTY)) {
#ifdef PRINT_ERR_MSG
    	        *error_code = MPI_ERR_UNKNOWN;
#else
		*error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR,
			      myname, "I/O Error", "%s", strerror(errno));
		ADIOI_Error(fd, *error_code, myname);
#endif
	        return;
	    }
	}    

	if ((fcntl_struct->diskspace > 2147483647) || 
	    (err && (errno == ENOTEMPTY))) {
#endif

        
	/* Explicitly write to allocate space. Since there could be
	   holes in the file, I need to read up to the current file
	   size, write it back, and then write beyond that depending
	   on how much preallocation is needed.
           read/write in sizes of no more than ADIOI_PREALLOC_BUFSZ */

	    curr_fsize = lseek64(fd->fd_sys, 0, SEEK_END);
	    alloc_size = fcntl_struct->diskspace;

	    size = ADIOI_MIN(curr_fsize, alloc_size);
	    
	    ntimes = (size + ADIOI_PREALLOC_BUFSZ - 1)/ADIOI_PREALLOC_BUFSZ;
	    buf = (char *) ADIOI_Malloc(ADIOI_PREALLOC_BUFSZ);
	    done = 0;

	    for (i=0; i<ntimes; i++) {
		len = ADIOI_MIN(size-done, ADIOI_PREALLOC_BUFSZ);
		ADIO_ReadContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET, 
                      done, &status, error_code);
		if (*error_code != MPI_SUCCESS) {
#ifdef PRINT_ERR_MSG
		    FPRINTF(stderr, "ADIOI_HFS_Fcntl: To preallocate disk space, ROMIO needs to read the file and write it back, but is unable to read the file. Please give the file read permission and open it with MPI_MODE_RDWR.\n");
		    MPI_Abort(MPI_COMM_WORLD, 1);
#else
		    *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_PREALLOC_PERM,
			      myname, (char *) 0, (char *) 0);
		    ADIOI_Error(fd, *error_code, myname);
		    return;  
#endif
		}
		ADIO_WriteContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
                         done,  &status, error_code);
		if (*error_code != MPI_SUCCESS) return;
		done += len;
	    }

	    if (alloc_size > curr_fsize) {
		memset(buf, 0, ADIOI_PREALLOC_BUFSZ); 
		size = alloc_size - curr_fsize;
		ntimes = (size + ADIOI_PREALLOC_BUFSZ - 1)/ADIOI_PREALLOC_BUFSZ;
		for (i=0; i<ntimes; i++) {
		    len = ADIOI_MIN(alloc_size-done, ADIOI_PREALLOC_BUFSZ);
		    ADIO_WriteContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET, 
				     done, &status, error_code);
		    if (*error_code != MPI_SUCCESS) return;
		    done += len;  
		}
	    }
	    ADIOI_Free(buf);
#ifdef SPPUX
	}
#endif
	*error_code = MPI_SUCCESS;
	break;

    case ADIO_FCNTL_SET_IOMODE:
        /* for implementing PFS I/O modes. will not occur in MPI-IO
           implementation.*/
	if (fd->iomode != fcntl_struct->iomode) {
	    fd->iomode = fcntl_struct->iomode;
	    MPI_Barrier(MPI_COMM_WORLD);
	}
	*error_code = MPI_SUCCESS;
	break;

    case ADIO_FCNTL_SET_ATOMICITY:
	fd->atomicity = (fcntl_struct->atomicity == 0) ? 0 : 1;
	*error_code = MPI_SUCCESS;
	break;

    default:
	FPRINTF(stderr, "Unknown flag passed to ADIOI_HFS_Fcntl\n");
	MPI_Abort(MPI_COMM_WORLD, 1);
    }
}