1 /* BLURB lgpl
2 
3                            Coda File System
4                               Release 5
5 
6           Copyright (c) 1987-2010 Carnegie Mellon University
7                   Additional copyrights listed below
8 
9 This  code  is  distributed "AS IS" without warranty of any kind under
10 the  terms of the  GNU  Library General Public Licence  Version 2,  as
11 shown in the file LICENSE. The technical and financial contributors to
12 Coda are listed in the file CREDITS.
13 
14                         Additional copyrights
15                            none currently
16 
17 #*/
18 
19 
20 #include <stdio.h>
21 #include "rds_private.h"
22 
23 	    /************** NOTE: ***************/
24 /* we create our own transactions in the following routines, even
25  * though there is a tid in the interface. This might result in unreferenced
26  * objects if the thread which malloc'ed the object decides to abort. These
27  * routines have no way of knowing if such an event happens. Also, if the user
28  * free's then aborts, could have pointers into the free list objects.
29  *
30  * Interface has been changed so that if a user feels confident that his
31  * transactions are serialized, (the above problem won't arise), he can pass
32  * in a non-null tid ptr and it will be used. So if you aren't sure, make the
33  * tidptr is zero!
34  */
35 
36 /* Preallocate nblocks of size bytes. Used to fill free lists with blocks
37  * of appropriate size so splits won't happen during rds_malloc().
38  */
39 
40 int
rds_prealloc(size,nblocks,tid,err)41 rds_prealloc(size, nblocks, tid, err)
42      unsigned long size, nblocks;
43      rvm_tid_t     *tid;
44      int	   *err;
45 {
46     free_block_t *bp;
47     rvm_tid_t *atid;
48     int i;
49     rvm_return_t rvmerr;
50 
51     if (!HEAP_INIT) {  /* Make sure the heap is initialized */
52 	(*err) = EHEAP_INIT;
53 	return -1;
54     }
55 
56     /* Reserve bytes to hold the block's size and 2 guards, hidden from user */
57     /* Calculate the chunk size which holds that many bytes. */
58     size = ((size + RDS_BLOCK_HDR_SIZE) / RDS_CHUNK_SIZE) + 1;
59 
60     /*
61      * if size == maxlist, then preallocing is pointless. The new object
62      * is placed on the beginning of the list, then every split after that
63      * will return that same block, and put_block will put it back at the head.
64      */
65     if (size == RDS_MAXLIST) {
66 	*err = SUCCESS;
67 	return -1;
68     }
69 
70     if (tid == NULL) {		     /* Use input tid if non-null */
71 	atid = rvm_malloc_tid();
72 	rvmerr = rvm_begin_transaction(atid, restore);
73 	if (rvmerr != RVM_SUCCESS) {
74 	    (*err) = (int) rvmerr;
75 	    rvm_free_tid(atid);
76 	    return -1;
77 	}
78     } else
79 	atid = tid;
80 
81     /* Update statistics */
82     rvmerr = rvm_set_range(atid, &RDS_STATS, sizeof(rds_stats_t));
83     if ((rvmerr != RVM_SUCCESS) && (tid == NULL)) {
84 	rvm_abort_transaction(atid);
85 	(*err) = (int)rvmerr;
86 	rvm_free_tid(atid);
87 	return -1;
88     }
89     RDS_STATS.prealloc++;	/* Update statistics. */
90 
91     *err = SUCCESS; 		/* Initialize the error value */
92 
93     /*
94      * Here I put the critical section within the loop. I don't think prealloc
95      * needs to be streamlined and it allows slightly more parallelization.
96      */
97 
98     for (i = 0; i < nblocks; i++) {
99 	START_CRITICAL;
100 	{
101 	    /* Get a block */
102 	    bp = split(size, atid, err);
103 	    if (bp != NULL) {
104 		/* Add the block to the appropriate list. */
105 		put_block(bp, atid, err);
106 	    }
107 	}
108 	END_CRITICAL;
109 
110 	if (*err != SUCCESS) {
111 	    if (tid == NULL) {
112 		rvm_abort_transaction(atid);
113 		rvm_free_tid(atid);
114 	    }
115 	    return -1;
116 	}
117     }
118 
119     if (tid == NULL) {
120 	rvmerr = rvm_end_transaction(atid, no_flush);
121 	if (rvmerr != RVM_SUCCESS) {
122 	    (*err) = (int) rvmerr;
123 	    rvm_free_tid(atid);
124 	    return -1;
125 	}
126 
127 	rvm_free_tid(atid);
128     }
129 
130     *err = SUCCESS;
131     return 0;
132 }
133 
134 
135 
136