archrelease: copy trunk to extra-x86_64
[arch-packages.git] / db5.3 / trunk / db-5.3.21-memp_stat-upstream-fix.patch
blob9e3d52b68ef73398a46172bad99102b6d355e9a8
1 diff -r -u db-5.3.21_orig/src/mp/mp_stat.c db-5.3.21/src/mp/mp_stat.c
2 --- db-5.3.21_orig/src/mp/mp_stat.c 2012-05-12 01:57:53.000000000 +0800
3 +++ db-5.3.21/src/mp/mp_stat.c 2015-05-19 15:07:09.000000000 +0800
4 @@ -87,6 +87,13 @@
5 u_int32_t i;
6 uintmax_t tmp_wait, tmp_nowait;
8 + /*
9 + * The array holding the lengths related to the buffer allocated for *fspp.
10 + * The first element of the array holds the number of entries allocated.
11 + * The second element of the array holds the total number of bytes allocated.
12 + */
13 + u_int32_t fsp_len[2];
15 dbmp = env->mp_handle;
16 mp = dbmp->reginfo[0].primary;
18 @@ -193,32 +200,53 @@
19 if (fspp != NULL) {
20 *fspp = NULL;
22 - /* Count the MPOOLFILE structures. */
23 - i = 0;
24 - len = 0;
25 - if ((ret = __memp_walk_files(env,
26 - mp, __memp_count_files, &len, &i, flags)) != 0)
27 - return (ret);
28 + while (*fspp == NULL) {
29 + /* Count the MPOOLFILE structures. */
30 + i = 0;
31 + /*
32 + * Allow space for the first __memp_get_files() to align the
33 + * structure array to uintmax_t, DB_MPOOL_STAT's most
34 + * restrictive field. [#23150]
35 + */
36 + len = sizeof(uintmax_t);
37 + if ((ret = __memp_walk_files(env,
38 + mp, __memp_count_files, &len, &i, flags)) != 0)
39 + return (ret);
41 + if (i == 0)
42 + return (0);
44 + /*
45 + * Copy the number of DB_MPOOL_FSTAT entries and the number of
46 + * bytes allocated for them into fsp_len. Do not count the space
47 + * reserved for allignment.
48 + */
49 + fsp_len[0] = i;
50 + fsp_len[1] = len - sizeof(uintmax_t);
52 - if (i == 0)
53 - return (0);
54 - len += sizeof(DB_MPOOL_FSTAT *); /* Trailing NULL */
55 + len += sizeof(DB_MPOOL_FSTAT *); /* Trailing NULL */
57 - /* Allocate space */
58 - if ((ret = __os_umalloc(env, len, fspp)) != 0)
59 - return (ret);
60 + /* Allocate space */
61 + if ((ret = __os_umalloc(env, len, fspp)) != 0)
62 + return (ret);
64 - tfsp = *fspp;
65 - *tfsp = NULL;
67 - /*
68 - * Files may have been opened since we counted, don't walk
69 - * off the end of the allocated space.
70 - */
71 - if ((ret = __memp_walk_files(env,
72 - mp, __memp_get_files, &tfsp, &i, flags)) != 0)
73 - return (ret);
74 + tfsp = *fspp;
75 + *tfsp = NULL;
77 + /*
78 + * Files may have been opened since we counted, if we walk off
79 + * the end of the allocated space specified in fsp_len, retry.
80 + */
81 + if ((ret = __memp_walk_files(env,
82 + mp, __memp_get_files, &tfsp, fsp_len, flags)) != 0) {
83 + if (ret == DB_BUFFER_SMALL) {
84 + __os_ufree(env, *fspp);
85 + *fspp = NULL;
86 + tfsp = NULL;
87 + } else
88 + return (ret);
89 + }
90 + }
91 *++tfsp = NULL;
94 @@ -286,28 +314,35 @@
95 * for the text file names.
97 static int
98 -__memp_get_files(env, mfp, argp, countp, flags)
99 +__memp_get_files(env, mfp, argp, fsp_len, flags)
100 ENV *env;
101 MPOOLFILE *mfp;
102 void *argp;
103 - u_int32_t *countp;
104 + u_int32_t fsp_len[];
105 u_int32_t flags;
107 DB_MPOOL *dbmp;
108 DB_MPOOL_FSTAT **tfsp, *tstruct;
109 char *name, *tname;
110 - size_t nlen;
111 + size_t nlen, tlen;
113 - if (*countp == 0)
114 - return (0);
115 + /* We walked through more files than argp was allocated for. */
116 + if (fsp_len[0] == 0)
117 + return DB_BUFFER_SMALL;
119 dbmp = env->mp_handle;
120 tfsp = *(DB_MPOOL_FSTAT ***)argp;
122 if (*tfsp == NULL) {
123 - /* Add 1 to count because we need to skip over the NULL. */
124 - tstruct = (DB_MPOOL_FSTAT *)(tfsp + *countp + 1);
125 - tname = (char *)(tstruct + *countp);
126 + /*
127 + * Add 1 to count because to skip over the NULL end marker.
128 + * Align it further for DB_MPOOL_STAT's most restrictive field
129 + * because uintmax_t might require stricter alignment than
130 + * pointers; e.g., IP32 LL64 SPARC. [#23150]
131 + */
132 + tstruct = (DB_MPOOL_FSTAT *)&tfsp[fsp_len[0] + 1];
133 + tstruct = ALIGNP_INC(tstruct, sizeof(uintmax_t));
134 + tname = (char *)&tstruct[fsp_len[0]];
135 *tfsp = tstruct;
136 } else {
137 tstruct = *tfsp + 1;
138 @@ -317,6 +352,15 @@
140 name = __memp_fns(dbmp, mfp);
141 nlen = strlen(name) + 1;
143 + /* The space required for file names is larger than argp was allocated for. */
144 + tlen = sizeof(DB_MPOOL_FSTAT *) + sizeof(DB_MPOOL_FSTAT) + nlen;
145 + if (fsp_len[1] < tlen)
146 + return DB_BUFFER_SMALL;
147 + else
148 + /* Count down the number of bytes left in argp. */
149 + fsp_len[1] -= tlen;
151 memcpy(tname, name, nlen);
152 memcpy(tstruct, &mfp->stat, sizeof(mfp->stat));
153 tstruct->file_name = tname;
154 @@ -325,7 +369,9 @@
155 tstruct->st_pagesize = mfp->pagesize;
157 *(DB_MPOOL_FSTAT ***)argp = tfsp;
158 - (*countp)--;
160 + /* Count down the number of entries left in argp. */
161 + fsp_len[0]--;
163 if (LF_ISSET(DB_STAT_CLEAR))
164 memset(&mfp->stat, 0, sizeof(mfp->stat));
165 diff -r -u db-5.3.21_orig/src/mp/mp_sync.c db-5.3.21/src/mp/mp_sync.c
166 --- db-5.3.21_orig/src/mp/mp_sync.c 2012-05-12 01:57:53.000000000 +0800
167 +++ db-5.3.21/src/mp/mp_sync.c 2015-05-19 15:08:05.000000000 +0800
168 @@ -57,11 +57,13 @@
169 if ((t_ret = func(env,
170 mfp, arg, countp, flags)) != 0 && ret == 0)
171 ret = t_ret;
172 - if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
173 + if (ret != 0 &&
174 + (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == DB_BUFFER_SMALL))
175 break;
177 MUTEX_UNLOCK(env, hp->mtx_hash);
178 - if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
179 + if (ret != 0 &&
180 + (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == DB_BUFFER_SMALL))
181 break;
183 return (ret);