diff options
author | Zhang Qiang <qiang.z.zhang@intel.com> | 2012-05-29 11:25:24 +0800 |
---|---|---|
committer | Zhang Qiang <qiang.z.zhang@intel.com> | 2012-05-29 11:25:24 +0800 |
commit | e776056ea09ba0b6d9505ced6913c9190a12d632 (patch) | |
tree | 092838f2a86042abc586aa5576e36ae6cb47e256 /qam/qam_files.c | |
parent | 2e082c838d2ca750f5daac6dcdabecc22dfd4e46 (diff) | |
download | db4-e776056ea09ba0b6d9505ced6913c9190a12d632.tar.gz db4-e776056ea09ba0b6d9505ced6913c9190a12d632.tar.bz2 db4-e776056ea09ba0b6d9505ced6913c9190a12d632.zip |
updated with Tizen:Base source codes
Diffstat (limited to 'qam/qam_files.c')
-rw-r--r-- | qam/qam_files.c | 894 |
1 files changed, 0 insertions, 894 deletions
diff --git a/qam/qam_files.c b/qam/qam_files.c deleted file mode 100644 index 928fdfd..0000000 --- a/qam/qam_files.c +++ /dev/null @@ -1,894 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2009 Oracle. All rights reserved. - * - * $Id$ - */ - -#include "db_config.h" - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" -#include "dbinc/fop.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" - -#define QAM_EXNAME(Q, I, B, L) \ - snprintf((B), (L), \ - QUEUE_EXTENT, (Q)->dir, PATH_SEPARATOR[0], (Q)->name, (I)) - -/* - * __qam_fprobe -- calculate and open extent - * - * Calculate which extent the page is in, open and create if necessary. - * - * PUBLIC: int __qam_fprobe __P((DBC *, db_pgno_t, - * PUBLIC: void *, qam_probe_mode, DB_CACHE_PRIORITY, u_int32_t)); - */ -int -__qam_fprobe(dbc, pgno, addrp, mode, priority, flags) - DBC *dbc; - db_pgno_t pgno; - void *addrp; - qam_probe_mode mode; - DB_CACHE_PRIORITY priority; - u_int32_t flags; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - ENV *env; - MPFARRAY *array; - QUEUE *qp; - u_int8_t fid[DB_FILE_ID_LEN]; - u_int32_t i, extid, maxext, numext, lflags, offset, oldext, openflags; - char buf[DB_MAXPATHLEN]; - int ftype, less, ret, t_ret; - - dbp = dbc->dbp; - env = dbp->env; - qp = (QUEUE *)dbp->q_internal; - ret = 0; - - if (qp->page_ext == 0) { - mpf = dbp->mpf; - switch (mode) { - case QAM_PROBE_GET: - return (__memp_fget(mpf, &pgno, - dbc->thread_info, dbc->txn, flags, addrp)); - case QAM_PROBE_PUT: - return (__memp_fput(mpf, - dbc->thread_info, addrp, priority)); - case QAM_PROBE_DIRTY: - return (__memp_dirty(mpf, addrp, - dbc->thread_info, dbc->txn, priority, flags)); - case QAM_PROBE_MPF: - *(DB_MPOOLFILE **)addrp = mpf; - return (0); - } - } - - mpf = NULL; - - /* - * Need to lock long enough to find the mpf or create the file. - * The file cannot go away because we must have a record locked - * in that file. - */ - MUTEX_LOCK(env, dbp->mutex); - extid = QAM_PAGE_EXTENT(dbp, pgno); - - /* Array1 will always be in use if array2 is in use. */ - array = &qp->array1; - if (array->n_extent == 0) { - /* Start with 4 extents */ - array->n_extent = 4; - array->low_extent = extid; - numext = offset = oldext = 0; - less = 0; - goto alloc; - } - -retry: - if (extid < array->low_extent) { - less = 1; - offset = array->low_extent - extid; - } else { - less = 0; - offset = extid - array->low_extent; - } - if (qp->array2.n_extent != 0 && - (extid >= qp->array2.low_extent ? - offset > extid - qp->array2.low_extent : - offset > qp->array2.low_extent - extid)) { - array = &qp->array2; - if (extid < array->low_extent) { - less = 1; - offset = array->low_extent - extid; - } else { - less = 0; - offset = extid - array->low_extent; - } - } - - /* - * Check to see if the requested extent is outside the range of - * extents in the array. This is true by default if there are - * no extents here yet. - */ - if (less == 1 || offset >= array->n_extent) { - oldext = array->n_extent; - numext = (array->hi_extent - array->low_extent) + 1; - if (less == 1 && offset + numext <= array->n_extent) { - /* - * If we can fit this one into the existing array by - * shifting the existing entries then we do not have - * to allocate. - */ - memmove(&array->mpfarray[offset], - array->mpfarray, numext - * sizeof(array->mpfarray[0])); - memset(array->mpfarray, 0, offset - * sizeof(array->mpfarray[0])); - offset = 0; - } else if (less == 0 && offset == array->n_extent && - (mode == QAM_PROBE_GET || mode == QAM_PROBE_PUT) && - array->mpfarray[0].pinref == 0) { - /* - * If this is at the end of the array and the file at - * the beginning has a zero pin count we can close - * the bottom extent and put this one at the end. - */ - mpf = array->mpfarray[0].mpf; - if (mpf != NULL && (ret = __memp_fclose(mpf, 0)) != 0) - goto err; - memmove(&array->mpfarray[0], &array->mpfarray[1], - (array->n_extent - 1) * sizeof(array->mpfarray[0])); - array->low_extent++; - array->hi_extent++; - offset--; - array->mpfarray[offset].mpf = NULL; - array->mpfarray[offset].pinref = 0; - } else { - /* - * See if we have wrapped around the queue. - * If it has then allocate the second array. - * Otherwise just expand the one we are using. - */ - maxext = (u_int32_t) UINT32_MAX - / (qp->page_ext * qp->rec_page); - if (offset >= maxext/2) { - array = &qp->array2; - DB_ASSERT(env, array->n_extent == 0); - oldext = 0; - array->n_extent = 4; - array->low_extent = extid; - offset = 0; - numext = 0; - } else if (array->mpfarray[0].pinref == 0) { - /* - * Check to see if there are extents marked - * for deletion at the beginning of the cache. - * If so close them so they will go away. - */ - for (i = 0; i < array->n_extent; i++) { - if (array->mpfarray[i].pinref != 0) - break; - mpf = array->mpfarray[i].mpf; - if (mpf == NULL) - continue; - (void)__memp_get_flags(mpf, &lflags); - if (!FLD_ISSET(lflags, DB_MPOOL_UNLINK)) - break; - - array->mpfarray[i].mpf = NULL; - if ((ret = __memp_fclose(mpf, 0)) != 0) - goto err; - } - if (i == 0) - goto increase; - memmove(&array->mpfarray[0], - &array->mpfarray[i], - (array->n_extent - i) * - sizeof(array->mpfarray[0])); - memset(&array->mpfarray[array->n_extent - i], - '\0', i * sizeof(array->mpfarray[0])); - array->low_extent += i; - array->hi_extent += i; - goto retry; - } else { - /* - * Increase the size to at least include - * the new one and double it. - */ -increase: array->n_extent += offset; - array->n_extent <<= 2; - } -alloc: if ((ret = __os_realloc(env, - array->n_extent * sizeof(struct __qmpf), - &array->mpfarray)) != 0) - goto err; - - if (less == 1) { - /* - * Move the array up and put the new one - * in the first slot. - */ - memmove(&array->mpfarray[offset], - array->mpfarray, - numext * sizeof(array->mpfarray[0])); - memset(array->mpfarray, 0, - offset * sizeof(array->mpfarray[0])); - memset(&array->mpfarray[numext + offset], 0, - (array->n_extent - (numext + offset)) - * sizeof(array->mpfarray[0])); - offset = 0; - } - else - /* Clear the new part of the array. */ - memset(&array->mpfarray[oldext], 0, - (array->n_extent - oldext) * - sizeof(array->mpfarray[0])); - } - } - - /* Update the low and hi range of saved extents. */ - if (extid < array->low_extent) - array->low_extent = extid; - if (extid > array->hi_extent) - array->hi_extent = extid; - - /* If the extent file is not yet open, open it. */ - if (array->mpfarray[offset].mpf == NULL) { - QAM_EXNAME(qp, extid, buf, sizeof(buf)); - if ((ret = __memp_fcreate( - env, &array->mpfarray[offset].mpf)) != 0) - goto err; - mpf = array->mpfarray[offset].mpf; - (void)__memp_set_lsn_offset(mpf, 0); - (void)__memp_set_pgcookie(mpf, &qp->pgcookie); - (void)__memp_get_ftype(dbp->mpf, &ftype); - (void)__memp_set_ftype(mpf, ftype); - (void)__memp_set_clear_len(mpf, dbp->pgsize); - - /* Set up the fileid for this extent. */ - __qam_exid(dbp, fid, extid); - (void)__memp_set_fileid(mpf, fid); - openflags = DB_EXTENT; - if (LF_ISSET(DB_MPOOL_CREATE)) - openflags |= DB_CREATE; - if (F_ISSET(dbp, DB_AM_RDONLY)) - openflags |= DB_RDONLY; - if (F_ISSET(env->dbenv, DB_ENV_DIRECT_DB)) - openflags |= DB_DIRECT; - if ((ret = __memp_fopen(mpf, NULL, - buf, NULL, openflags, qp->mode, dbp->pgsize)) != 0) { - array->mpfarray[offset].mpf = NULL; - (void)__memp_fclose(mpf, 0); - goto err; - } - } - - /* - * We have found the right file. Update its ref count - * before dropping the dbp mutex so it does not go away. - */ - mpf = array->mpfarray[offset].mpf; - if (mode == QAM_PROBE_GET) - array->mpfarray[offset].pinref++; - - /* - * If we may create the page, then we are writing, - * the file may nolonger be empty after this operation - * so we clear the UNLINK flag. - */ - if (LF_ISSET(DB_MPOOL_CREATE)) - (void)__memp_set_flags(mpf, DB_MPOOL_UNLINK, 0); - -err: - MUTEX_UNLOCK(env, dbp->mutex); - - if (ret == 0) { - pgno--; - pgno %= qp->page_ext; - switch (mode) { - case QAM_PROBE_GET: - ret = __memp_fget(mpf, &pgno, - dbc->thread_info, dbc->txn, flags, addrp); - if (ret == 0) - return (0); - break; - case QAM_PROBE_PUT: - ret = __memp_fput(mpf, - dbc->thread_info, addrp, dbp->priority); - break; - case QAM_PROBE_DIRTY: - return (__memp_dirty(mpf, addrp, - dbc->thread_info, dbc->txn, dbp->priority, flags)); - case QAM_PROBE_MPF: - *(DB_MPOOLFILE **)addrp = mpf; - return (0); - } - - MUTEX_LOCK(env, dbp->mutex); - /* Recalculate because we dropped the lock. */ - offset = extid - array->low_extent; - DB_ASSERT(env, array->mpfarray[offset].pinref > 0); - if (--array->mpfarray[offset].pinref == 0 && - (mode == QAM_PROBE_GET || ret == 0)) { - /* Check to see if this file will be unlinked. */ - (void)__memp_get_flags(mpf, &flags); - if (LF_ISSET(DB_MPOOL_UNLINK)) { - array->mpfarray[offset].mpf = NULL; - if ((t_ret = - __memp_fclose(mpf, 0)) != 0 && ret == 0) - ret = t_ret; - } - } - MUTEX_UNLOCK(env, dbp->mutex); - } - return (ret); -} - -/* - * __qam_fclose -- close an extent. - * - * Calculate which extent the page is in and close it. - * We assume the mpf entry is present. - * - * PUBLIC: int __qam_fclose __P((DB *, db_pgno_t)); - */ -int -__qam_fclose(dbp, pgnoaddr) - DB *dbp; - db_pgno_t pgnoaddr; -{ - DB_MPOOLFILE *mpf; - ENV *env; - MPFARRAY *array; - QUEUE *qp; - u_int32_t extid, offset; - int ret; - - ret = 0; - env = dbp->env; - qp = (QUEUE *)dbp->q_internal; - - MUTEX_LOCK(env, dbp->mutex); - - extid = QAM_PAGE_EXTENT(dbp, pgnoaddr); - array = &qp->array1; - if (array->low_extent > extid || array->hi_extent < extid) - array = &qp->array2; - offset = extid - array->low_extent; - - DB_ASSERT(env, - extid >= array->low_extent && offset < array->n_extent); - - /* If other threads are still using this file, leave it. */ - if (array->mpfarray[offset].pinref != 0) - goto done; - - mpf = array->mpfarray[offset].mpf; - array->mpfarray[offset].mpf = NULL; - ret = __memp_fclose(mpf, 0); - -done: - MUTEX_UNLOCK(env, dbp->mutex); - return (ret); -} - -/* - * __qam_fremove -- remove an extent. - * - * Calculate which extent the page is in and remove it. There is no way - * to remove an extent without probing it first and seeing that is is empty - * so we assume the mpf entry is present. - * - * PUBLIC: int __qam_fremove __P((DB *, db_pgno_t)); - */ -int -__qam_fremove(dbp, pgnoaddr) - DB *dbp; - db_pgno_t pgnoaddr; -{ - DB_MPOOLFILE *mpf; - ENV *env; - MPFARRAY *array; - QUEUE *qp; - u_int32_t extid, offset; - int ret; - - qp = (QUEUE *)dbp->q_internal; - env = dbp->env; - ret = 0; - - MUTEX_LOCK(env, dbp->mutex); - - extid = QAM_PAGE_EXTENT(dbp, pgnoaddr); - array = &qp->array1; - if (array->low_extent > extid || array->hi_extent < extid) - array = &qp->array2; - offset = extid - array->low_extent; - - DB_ASSERT(env, - extid >= array->low_extent && offset < array->n_extent); - - mpf = array->mpfarray[offset].mpf; - /* This extent my already be marked for delete and closed. */ - if (mpf == NULL) - goto err; - - /* - * The log must be flushed before the file is deleted. We depend on - * the log record of the last delete to recreate the file if we crash. - */ - if (LOGGING_ON(env) && (ret = __log_flush(env, NULL)) != 0) - goto err; - - (void)__memp_set_flags(mpf, DB_MPOOL_UNLINK, 1); - /* Someone could be real slow, let them close it down. */ - if (array->mpfarray[offset].pinref != 0) - goto err; - array->mpfarray[offset].mpf = NULL; - if ((ret = __memp_fclose(mpf, 0)) != 0) - goto err; - - /* - * If the file is at the bottom of the array - * shift things down and adjust the end points. - */ - if (offset == 0) { - memmove(array->mpfarray, &array->mpfarray[1], - (array->hi_extent - array->low_extent) - * sizeof(array->mpfarray[0])); - array->mpfarray[ - array->hi_extent - array->low_extent].mpf = NULL; - if (array->low_extent != array->hi_extent) - array->low_extent++; - } else { - if (extid == array->hi_extent) - array->hi_extent--; - } - -err: MUTEX_UNLOCK(env, dbp->mutex); - - return (ret); -} - -/* - * __qam_sync -- - * Flush the database cache. - * - * PUBLIC: int __qam_sync __P((DB *)); - */ -int -__qam_sync(dbp) - DB *dbp; -{ - int ret; - /* - * We can't easily identify the extent files associated with a specific - * Queue file, so flush all Queue extent files. - */ - if ((ret = __memp_fsync(dbp->mpf)) != 0) - return (ret); - if (((QUEUE *)dbp->q_internal)->page_ext != 0) - return (__memp_sync_int( - dbp->env, NULL, 0, DB_SYNC_QUEUE_EXTENT, NULL, NULL)); - return (0); -} - -/* - * __qam_gen_filelist -- generate a list of extent files. - * Another thread may close the handle so this should only - * be used single threaded or with care. - * - * PUBLIC: int __qam_gen_filelist __P((DB *, - * PUBLIC: DB_THREAD_INFO *, QUEUE_FILELIST **)); - */ -int -__qam_gen_filelist(dbp, ip, filelistp) - DB *dbp; - DB_THREAD_INFO *ip; - QUEUE_FILELIST **filelistp; -{ - DBC *dbc; - DB_MPOOLFILE *mpf; - ENV *env; - QMETA *meta; - QUEUE *qp; - size_t extent_cnt; - db_recno_t i, current, first, stop, rec_extent; - QUEUE_FILELIST *fp; - int ret; - - env = dbp->env; - mpf = dbp->mpf; - qp = (QUEUE *)dbp->q_internal; - *filelistp = NULL; - - if (qp->page_ext == 0) - return (0); - - /* This may happen during metapage recovery. */ - if (qp->name == NULL) - return (0); - - /* Find out the first and last record numbers in the database. */ - i = PGNO_BASE_MD; - if ((ret = __memp_fget(mpf, &i, ip, NULL, 0, &meta)) != 0) - return (ret); - - current = meta->cur_recno; - first = meta->first_recno; - - if ((ret = __memp_fput(mpf, ip, meta, dbp->priority)) != 0) - return (ret); - - /* - * Allocate the extent array. Calculate the worst case number of - * pages and convert that to a count of extents. The count of - * extents has 3 or 4 extra slots: - * roundoff at first (e.g., current record in extent); - * roundoff at current (e.g., first record in extent); - * NULL termination; and - * UINT32_MAX wraparound (the last extent can be small). - */ - rec_extent = qp->rec_page * qp->page_ext; - if (current >= first) - extent_cnt = (current - first) / rec_extent + 3; - else - extent_cnt = - (current + (UINT32_MAX - first)) / rec_extent + 4; - - if (extent_cnt == 0) - return (0); - if ((ret = __os_calloc(env, - extent_cnt, sizeof(QUEUE_FILELIST), filelistp)) != 0) - return (ret); - fp = *filelistp; - if ((ret = __db_cursor(dbp, ip, NULL, &dbc, 0)) != 0) - return (ret); - -again: - if (current >= first) - stop = current; - else - stop = UINT32_MAX; - - /* - * Make sure that first is at the same offset in the extent as stop. - * This guarantees that the stop will be reached in the loop below, - * even if it is the only record in its extent. This calculation is - * safe because first won't move out of its extent. - */ - first -= first % rec_extent; - first += stop % rec_extent; - - for (i = first; i >= first && i <= stop; i += rec_extent) { - if ((ret = __qam_fprobe(dbc, QAM_RECNO_PAGE(dbp, i), - &fp->mpf, QAM_PROBE_MPF, dbp->priority, 0)) != 0) { - if (ret == ENOENT) - continue; - goto err; - } - fp->id = QAM_RECNO_EXTENT(dbp, i); - fp++; - DB_ASSERT(env, (size_t)(fp - *filelistp) < extent_cnt); - } - - if (current < first) { - first = 1; - goto again; - } - -err: (void)__dbc_close(dbc); - return (ret); -} - -/* - * __qam_extent_names -- generate a list of extent files names. - * - * PUBLIC: int __qam_extent_names __P((ENV *, char *, char ***)); - */ -int -__qam_extent_names(env, name, namelistp) - ENV *env; - char *name; - char ***namelistp; -{ - DB *dbp; - DB_THREAD_INFO *ip; - QUEUE *qp; - QUEUE_FILELIST *filelist, *fp; - size_t len; - int cnt, ret, t_ret; - char buf[DB_MAXPATHLEN], **cp, *freep; - - *namelistp = NULL; - filelist = NULL; - ENV_GET_THREAD_INFO(env, ip); - if ((ret = __db_create_internal(&dbp, env, 0)) != 0) - return (ret); - if ((ret = __db_open(dbp, ip, - NULL, name, NULL, DB_QUEUE, DB_RDONLY, 0, PGNO_BASE_MD)) != 0) - goto done; - qp = dbp->q_internal; - if (qp->page_ext == 0) - goto done; - - if ((ret = __qam_gen_filelist(dbp, ip, &filelist)) != 0) - goto done; - - if (filelist == NULL) - goto done; - - cnt = 0; - for (fp = filelist; fp->mpf != NULL; fp++) - cnt++; - - /* QUEUE_EXTENT contains extra chars, but add 6 anyway for the int. */ - len = (size_t)cnt * (sizeof(**namelistp) + - strlen(QUEUE_EXTENT) + strlen(qp->dir) + strlen(qp->name) + 6); - - if ((ret = __os_malloc(dbp->env, len, namelistp)) != 0) - goto done; - cp = *namelistp; - freep = (char *)(cp + cnt + 1); - for (fp = filelist; fp->mpf != NULL; fp++) { - QAM_EXNAME(qp, fp->id, buf, sizeof(buf)); - len = strlen(buf); - *cp++ = freep; - (void)strcpy(freep, buf); - freep += len + 1; - } - *cp = NULL; - -done: - if (filelist != NULL) - __os_free(dbp->env, filelist); - if ((t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __qam_exid -- - * Generate a fileid for an extent based on the fileid of the main - * file. Since we do not log schema creates/deletes explicitly, the log - * never captures the fileid of an extent file. In order that masters and - * replicas have the same fileids (so they can explicitly delete them), we - * use computed fileids for the extent files of Queue files. - * - * An extent file id retains the low order 12 bytes of the file id and - * overwrites the dev/inode fields, placing a 0 in the inode field, and - * the extent number in the dev field. - * - * PUBLIC: void __qam_exid __P((DB *, u_int8_t *, u_int32_t)); - */ -void -__qam_exid(dbp, fidp, exnum) - DB *dbp; - u_int8_t *fidp; - u_int32_t exnum; -{ - int i; - u_int8_t *p; - - /* Copy the fileid from the master. */ - memcpy(fidp, dbp->fileid, DB_FILE_ID_LEN); - - /* The first four bytes are the inode or the FileIndexLow; 0 it. */ - for (i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = 0; - - /* The next four bytes are the dev/FileIndexHigh; insert the exnum . */ - for (p = (u_int8_t *)&exnum, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; -} - -/* - * __qam_nameop -- - * Remove or rename extent files associated with a particular file. - * This is to remove or rename (both in mpool and the file system) any - * extent files associated with the given dbp. - * This is either called from the QUEUE remove or rename methods or - * when undoing a transaction that created the database. - * - * PUBLIC: int __qam_nameop __P((DB *, DB_TXN *, const char *, qam_name_op)); - */ -int -__qam_nameop(dbp, txn, newname, op) - DB *dbp; - DB_TXN *txn; - const char *newname; - qam_name_op op; -{ - ENV *env; - QUEUE *qp; - size_t exlen, fulllen, len; - u_int8_t fid[DB_FILE_ID_LEN]; - u_int32_t exid; - int cnt, i, ret, t_ret; - char buf[DB_MAXPATHLEN], nbuf[DB_MAXPATHLEN], sepsave; - char *endname, *endpath, *exname, *fullname, **names; - char *ndir, *namep, *new, *cp; - - env = dbp->env; - qp = (QUEUE *)dbp->q_internal; - cnt = ret = t_ret = 0; - namep = exname = fullname = NULL; - names = NULL; - - /* If this isn't a queue with extents, we're done. */ - if (qp->page_ext == 0) - return (0); - - /* - * Generate the list of all queue extents for this file (from the - * file system) and then cycle through removing them and evicting - * from mpool. We have two modes of operation here. If we are - * undoing log operations, then do not write log records and try - * to keep going even if we encounter failures in nameop. If we - * are in mainline code, then return as soon as we have a problem. - * Memory allocation errors (__db_appname, __os_malloc) are always - * considered failure. - * - * Set buf to : dir/__dbq.NAME.0 and fullname to HOME/dir/__dbq.NAME.0 - * or, in the case of an absolute path: /dir/__dbq.NAME.0 - */ - QAM_EXNAME(qp, 0, buf, sizeof(buf)); - if ((ret = __db_appname(env, - DB_APP_DATA, buf, &dbp->dirname, &fullname)) != 0) - return (ret); - - /* We should always have a path separator here. */ - if ((endpath = __db_rpath(fullname)) == NULL) { - ret = EINVAL; - goto err; - } - sepsave = *endpath; - *endpath = '\0'; - - /* - * Get the list of all names in the directory and restore the - * path separator. - */ - if ((ret = __os_dirlist(env, fullname, 0, &names, &cnt)) != 0) - goto err; - *endpath = sepsave; - - /* If there aren't any names, don't allocate any space. */ - if (cnt == 0) - goto err; - - /* - * Now, make endpath reference the queue extent names upon which - * we can match. Then we set the end of the path to be the - * beginning of the extent number, and we can compare the bytes - * between endpath and endname (__dbq.NAME.). - */ - endpath++; - endname = strrchr(endpath, '.'); - if (endname == NULL) { - ret = EINVAL; - goto err; - } - ++endname; - *endname = '\0'; - len = strlen(endpath); - fulllen = strlen(fullname); - - /* Allocate space for a full extent name. */ - exlen = fulllen + 20; - if ((ret = __os_malloc(env, exlen, &exname)) != 0) - goto err; - - ndir = new = NULL; - if (newname != NULL) { - if ((ret = __os_strdup(env, newname, &namep)) != 0) - goto err; - ndir = namep; - if ((new = __db_rpath(namep)) != NULL) - *new++ = '\0'; - else { - new = namep; - ndir = PATH_DOT; - } - } - for (i = 0; i < cnt; i++) { - /* Check if this is a queue extent file. */ - if (strncmp(names[i], endpath, len) != 0) - continue; - /* Make sure we have all numbers. foo.db vs. foo.db.0. */ - for (cp = &names[i][len]; *cp != '\0'; cp++) - if (!isdigit((int)*cp)) - break; - if (*cp != '\0') - continue; - - /* - * We have a queue extent file. We need to generate its - * name and its fileid. - */ - exid = (u_int32_t)strtoul(names[i] + len, NULL, 10); - __qam_exid(dbp, fid, exid); - - switch (op) { - case QAM_NAME_DISCARD: - snprintf(exname, exlen, - "%s%s", fullname, names[i] + len); - if ((t_ret = __memp_nameop(dbp->env, - fid, NULL, exname, NULL, - F_ISSET(dbp, DB_AM_INMEM))) != 0 && ret == 0) - ret = t_ret; - break; - - case QAM_NAME_RENAME: - snprintf(nbuf, sizeof(nbuf), QUEUE_EXTENT, - ndir, PATH_SEPARATOR[0], new, exid); - QAM_EXNAME(qp, exid, buf, sizeof(buf)); - if ((ret = __fop_rename(env, - txn, buf, nbuf, &dbp->dirname, fid, DB_APP_DATA, 1, - F_ISSET(dbp, DB_AM_NOT_DURABLE) ? - DB_LOG_NOT_DURABLE : 0)) != 0) - goto err; - break; - - case QAM_NAME_REMOVE: - QAM_EXNAME(qp, exid, buf, sizeof(buf)); - if ((ret = __fop_remove(env, txn, fid, - buf, &dbp->dirname, - DB_APP_DATA, F_ISSET(dbp, DB_AM_NOT_DURABLE) ? - DB_LOG_NOT_DURABLE : 0)) != 0) - goto err; - break; - } - } - -err: if (fullname != NULL) - __os_free(env, fullname); - if (exname != NULL) - __os_free(env, exname); - if (namep != NULL) - __os_free(env, namep); - if (names != NULL) - __os_dirfree(env, names, cnt); - return (ret); -} - -/* - * __qam_lsn_reset -- reset the lsns for extents. - * - * PUBLIC: int __qam_lsn_reset __P((DB *, DB_THREAD_INFO *)); - */ -int -__qam_lsn_reset(dbp, ip) - DB *dbp; - DB_THREAD_INFO *ip; -{ - QUEUE *qp; - QUEUE_FILELIST *filelist, *fp; - int ret; - - qp = dbp->q_internal; - if (qp->page_ext == 0) - return (0); - - if ((ret = __qam_gen_filelist(dbp, ip, &filelist)) != 0) - return (ret); - - if (filelist == NULL) - return (ret); - - for (fp = filelist; fp->mpf != NULL; fp++) - if ((ret = __db_lsn_reset(fp->mpf, ip)) != 0) - break; - - __os_free(dbp->env, filelist); - return (ret); -} |