Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

mp_fmethod.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: mp_fmethod.c,v 12.7 2005/10/07 20:21:32 ubell Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 
00015 #include <string.h>
00016 #endif
00017 
00018 #include "db_int.h"
00019 #include "dbinc/db_shash.h"
00020 #include "dbinc/log.h"
00021 #include "dbinc/mp.h"
00022 
00023 static int __memp_get_clear_len __P((DB_MPOOLFILE *, u_int32_t *));
00024 static int __memp_get_lsn_offset __P((DB_MPOOLFILE *, int32_t *));
00025 static int __memp_get_maxsize __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t *));
00026 static int __memp_set_maxsize __P((DB_MPOOLFILE *, u_int32_t, u_int32_t));
00027 static int __memp_get_pgcookie __P((DB_MPOOLFILE *, DBT *));
00028 static int __memp_get_priority __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *));
00029 static int __memp_set_priority __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY));
00030 
00031 /*
00032  * __memp_fcreate_pp --
00033  *      DB_ENV->memp_fcreate pre/post processing.
00034  *
00035  * PUBLIC: int __memp_fcreate_pp __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t));
00036  */
00037 int
00038 __memp_fcreate_pp(dbenv, retp, flags)
00039         DB_ENV *dbenv;
00040         DB_MPOOLFILE **retp;
00041         u_int32_t flags;
00042 {
00043         DB_THREAD_INFO *ip;
00044         int ret;
00045 
00046         PANIC_CHECK(dbenv);
00047 
00048         /* Validate arguments. */
00049         if ((ret = __db_fchk(dbenv, "DB_ENV->memp_fcreate", flags, 0)) != 0)
00050                 return (ret);
00051 
00052         ENV_ENTER(dbenv, ip);
00053         REPLICATION_WRAP(dbenv, (__memp_fcreate(dbenv, retp)), ret);
00054         ENV_LEAVE(dbenv, ip);
00055         return (ret);
00056 }
00057 
00058 /*
00059  * __memp_fcreate --
00060  *      DB_ENV->memp_fcreate.
00061  *
00062  * PUBLIC: int __memp_fcreate __P((DB_ENV *, DB_MPOOLFILE **));
00063  */
00064 int
00065 __memp_fcreate(dbenv, retp)
00066         DB_ENV *dbenv;
00067         DB_MPOOLFILE **retp;
00068 {
00069         DB_MPOOLFILE *dbmfp;
00070         int ret;
00071 
00072         /* Allocate and initialize the per-process structure. */
00073         if ((ret = __os_calloc(dbenv, 1, sizeof(DB_MPOOLFILE), &dbmfp)) != 0)
00074                 return (ret);
00075 
00076         dbmfp->ref = 1;
00077         dbmfp->lsn_offset = -1;
00078         dbmfp->dbenv = dbenv;
00079         dbmfp->mfp = INVALID_ROFF;
00080 
00081         dbmfp->close = __memp_fclose_pp;
00082         dbmfp->get = __memp_fget_pp;
00083         dbmfp->get_clear_len = __memp_get_clear_len;
00084         dbmfp->get_fileid = __memp_get_fileid;
00085         dbmfp->get_flags = __memp_get_flags;
00086         dbmfp->get_ftype = __memp_get_ftype;
00087         dbmfp->get_lsn_offset = __memp_get_lsn_offset;
00088         dbmfp->get_maxsize = __memp_get_maxsize;
00089         dbmfp->get_pgcookie = __memp_get_pgcookie;
00090         dbmfp->get_priority = __memp_get_priority;
00091         dbmfp->open = __memp_fopen_pp;
00092         dbmfp->put = __memp_fput_pp;
00093         dbmfp->set = __memp_fset_pp;
00094         dbmfp->set_clear_len = __memp_set_clear_len;
00095         dbmfp->set_fileid = __memp_set_fileid;
00096         dbmfp->set_flags = __memp_set_flags;
00097         dbmfp->set_ftype = __memp_set_ftype;
00098         dbmfp->set_lsn_offset = __memp_set_lsn_offset;
00099         dbmfp->set_maxsize = __memp_set_maxsize;
00100         dbmfp->set_pgcookie = __memp_set_pgcookie;
00101         dbmfp->set_priority = __memp_set_priority;
00102         dbmfp->sync = __memp_fsync_pp;
00103 
00104         *retp = dbmfp;
00105         return (0);
00106 }
00107 
00108 /*
00109  * __memp_get_clear_len --
00110  *      Get the clear length.
00111  */
00112 static int
00113 __memp_get_clear_len(dbmfp, clear_lenp)
00114         DB_MPOOLFILE *dbmfp;
00115         u_int32_t *clear_lenp;
00116 {
00117         *clear_lenp = dbmfp->clear_len;
00118         return (0);
00119 }
00120 
00121 /*
00122  * __memp_set_clear_len --
00123  *      DB_MPOOLFILE->set_clear_len.
00124  *
00125  * PUBLIC: int __memp_set_clear_len __P((DB_MPOOLFILE *, u_int32_t));
00126  */
00127 int
00128 __memp_set_clear_len(dbmfp, clear_len)
00129         DB_MPOOLFILE *dbmfp;
00130         u_int32_t clear_len;
00131 {
00132         MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_clear_len");
00133 
00134         dbmfp->clear_len = clear_len;
00135         return (0);
00136 }
00137 
00138 /*
00139  * __memp_get_fileid --
00140  *      DB_MPOOLFILE->get_fileid.
00141  *
00142  * PUBLIC: int __memp_get_fileid __P((DB_MPOOLFILE *, u_int8_t *));
00143  */
00144 int
00145 __memp_get_fileid(dbmfp, fileid)
00146         DB_MPOOLFILE *dbmfp;
00147         u_int8_t *fileid;
00148 {
00149         if (!F_ISSET(dbmfp, MP_FILEID_SET)) {
00150                 __db_err(dbmfp->dbenv, "get_fileid: file ID not set");
00151                 return (EINVAL);
00152         }
00153 
00154         memcpy(fileid, dbmfp->fileid, DB_FILE_ID_LEN);
00155         return (0);
00156 }
00157 
00158 /*
00159  * __memp_set_fileid --
00160  *      DB_MPOOLFILE->set_fileid.
00161  *
00162  * PUBLIC: int __memp_set_fileid __P((DB_MPOOLFILE *, u_int8_t *));
00163  */
00164 int
00165 __memp_set_fileid(dbmfp, fileid)
00166         DB_MPOOLFILE *dbmfp;
00167         u_int8_t *fileid;
00168 {
00169         MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_fileid");
00170 
00171         memcpy(dbmfp->fileid, fileid, DB_FILE_ID_LEN);
00172         F_SET(dbmfp, MP_FILEID_SET);
00173 
00174         return (0);
00175 }
00176 
00177 /*
00178  * __memp_get_flags --
00179  *      Get the DB_MPOOLFILE flags;
00180  *
00181  * PUBLIC: int __memp_get_flags __P((DB_MPOOLFILE *, u_int32_t *));
00182  */
00183 int
00184 __memp_get_flags(dbmfp, flagsp)
00185         DB_MPOOLFILE *dbmfp;
00186         u_int32_t *flagsp;
00187 {
00188         MPOOLFILE *mfp;
00189 
00190         mfp = dbmfp->mfp;
00191 
00192         *flagsp = 0;
00193 
00194         if (mfp == NULL)
00195                 *flagsp = FLD_ISSET(dbmfp->config_flags,
00196                      DB_MPOOL_NOFILE | DB_MPOOL_UNLINK);
00197         else {
00198                 if (mfp->no_backing_file)
00199                         FLD_SET(*flagsp, DB_MPOOL_NOFILE);
00200                 if (mfp->unlink_on_close)
00201                         FLD_SET(*flagsp, DB_MPOOL_UNLINK);
00202         }
00203         return (0);
00204 }
00205 
00206 /*
00207  * __memp_set_flags --
00208  *      Set the DB_MPOOLFILE flags;
00209  *
00210  * PUBLIC: int __memp_set_flags __P((DB_MPOOLFILE *, u_int32_t, int));
00211  */
00212 int
00213 __memp_set_flags(dbmfp, flags, onoff)
00214         DB_MPOOLFILE *dbmfp;
00215         u_int32_t flags;
00216         int onoff;
00217 {
00218         DB_ENV *dbenv;
00219         MPOOLFILE *mfp;
00220         int ret;
00221 
00222         dbenv = dbmfp->dbenv;
00223         mfp = dbmfp->mfp;
00224 
00225         switch (flags) {
00226         case DB_MPOOL_NOFILE:
00227                 if (mfp == NULL)
00228                         if (onoff)
00229                                 FLD_SET(dbmfp->config_flags, DB_MPOOL_NOFILE);
00230                         else
00231                                 FLD_CLR(dbmfp->config_flags, DB_MPOOL_NOFILE);
00232                 else
00233                         mfp->no_backing_file = onoff;
00234                 break;
00235         case DB_MPOOL_UNLINK:
00236                 if (mfp == NULL)
00237                         if (onoff)
00238                                 FLD_SET(dbmfp->config_flags, DB_MPOOL_UNLINK);
00239                         else
00240                                 FLD_CLR(dbmfp->config_flags, DB_MPOOL_UNLINK);
00241                 else
00242                         mfp->unlink_on_close = onoff;
00243                 break;
00244         default:
00245                 if ((ret = __db_fchk(dbenv, "DB_MPOOLFILE->set_flags",
00246                     flags, DB_MPOOL_NOFILE | DB_MPOOL_UNLINK)) != 0)
00247                         return (ret);
00248                 break;
00249         }
00250         return (0);
00251 }
00252 
00253 /*
00254  * __memp_get_ftype --
00255  *      Get the file type (as registered).
00256  *
00257  * PUBLIC: int __memp_get_ftype __P((DB_MPOOLFILE *, int *));
00258  */
00259 int
00260 __memp_get_ftype(dbmfp, ftypep)
00261         DB_MPOOLFILE *dbmfp;
00262         int *ftypep;
00263 {
00264         *ftypep = dbmfp->ftype;
00265         return (0);
00266 }
00267 
00268 /*
00269  * __memp_set_ftype --
00270  *      DB_MPOOLFILE->set_ftype.
00271  *
00272  * PUBLIC: int __memp_set_ftype __P((DB_MPOOLFILE *, int));
00273  */
00274 int
00275 __memp_set_ftype(dbmfp, ftype)
00276         DB_MPOOLFILE *dbmfp;
00277         int ftype;
00278 {
00279         MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_ftype");
00280 
00281         dbmfp->ftype = ftype;
00282         return (0);
00283 }
00284 
00285 /*
00286  * __memp_get_lsn_offset --
00287  *      Get the page's LSN offset.
00288  */
00289 static int
00290 __memp_get_lsn_offset(dbmfp, lsn_offsetp)
00291         DB_MPOOLFILE *dbmfp;
00292         int32_t *lsn_offsetp;
00293 {
00294         *lsn_offsetp = dbmfp->lsn_offset;
00295         return (0);
00296 }
00297 
00298 /*
00299  * __memp_set_lsn_offset --
00300  *      Set the page's LSN offset.
00301  *
00302  * PUBLIC: int __memp_set_lsn_offset __P((DB_MPOOLFILE *, int32_t));
00303  */
00304 int
00305 __memp_set_lsn_offset(dbmfp, lsn_offset)
00306         DB_MPOOLFILE *dbmfp;
00307         int32_t lsn_offset;
00308 {
00309         MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_lsn_offset");
00310 
00311         dbmfp->lsn_offset = lsn_offset;
00312         return (0);
00313 }
00314 
00315 /*
00316  * __memp_get_maxsize --
00317  *      Get the file's maximum size.
00318  */
00319 static int
00320 __memp_get_maxsize(dbmfp, gbytesp, bytesp)
00321         DB_MPOOLFILE *dbmfp;
00322         u_int32_t *gbytesp, *bytesp;
00323 {
00324         DB_ENV *dbenv;
00325         MPOOLFILE *mfp;
00326 
00327         if ((mfp = dbmfp->mfp) == NULL) {
00328                 *gbytesp = dbmfp->gbytes;
00329                 *bytesp = dbmfp->bytes;
00330         } else {
00331                 dbenv = dbmfp->dbenv;
00332 
00333                 MPOOL_SYSTEM_LOCK(dbenv);
00334                 *gbytesp = (u_int32_t)
00335                     (mfp->maxpgno / (GIGABYTE / mfp->stat.st_pagesize));
00336                 *bytesp = (u_int32_t)
00337                     ((mfp->maxpgno % (GIGABYTE / mfp->stat.st_pagesize)) *
00338                     mfp->stat.st_pagesize);
00339                 MPOOL_SYSTEM_UNLOCK(dbenv);
00340         }
00341 
00342         return (0);
00343 }
00344 
00345 /*
00346  * __memp_set_maxsize --
00347  *      Set the file's maximum size.
00348  */
00349 static int
00350 __memp_set_maxsize(dbmfp, gbytes, bytes)
00351         DB_MPOOLFILE *dbmfp;
00352         u_int32_t gbytes, bytes;
00353 {
00354         DB_ENV *dbenv;
00355         MPOOLFILE *mfp;
00356 
00357         if ((mfp = dbmfp->mfp) == NULL) {
00358                 dbmfp->gbytes = gbytes;
00359                 dbmfp->bytes = bytes;
00360         } else {
00361                 dbenv = dbmfp->dbenv;
00362 
00363                 MPOOL_SYSTEM_LOCK(dbenv);
00364                 mfp->maxpgno = (db_pgno_t)
00365                     (gbytes * (GIGABYTE / mfp->stat.st_pagesize));
00366                 mfp->maxpgno += (db_pgno_t)
00367                     ((bytes + mfp->stat.st_pagesize - 1) /
00368                     mfp->stat.st_pagesize);
00369                 MPOOL_SYSTEM_UNLOCK(dbenv);
00370         }
00371 
00372         return (0);
00373 }
00374 
00375 /*
00376  * __memp_get_pgcookie --
00377  *      Get the pgin/pgout cookie.
00378  */
00379 static int
00380 __memp_get_pgcookie(dbmfp, pgcookie)
00381         DB_MPOOLFILE *dbmfp;
00382         DBT *pgcookie;
00383 {
00384         if (dbmfp->pgcookie == NULL) {
00385                 pgcookie->size = 0;
00386                 pgcookie->data = "";
00387         } else
00388                 memcpy(pgcookie, dbmfp->pgcookie, sizeof(DBT));
00389         return (0);
00390 }
00391 
00392 /*
00393  * __memp_set_pgcookie --
00394  *      Set the pgin/pgout cookie.
00395  *
00396  * PUBLIC: int __memp_set_pgcookie __P((DB_MPOOLFILE *, DBT *));
00397  */
00398 int
00399 __memp_set_pgcookie(dbmfp, pgcookie)
00400         DB_MPOOLFILE *dbmfp;
00401         DBT *pgcookie;
00402 {
00403         DB_ENV *dbenv;
00404         DBT *cookie;
00405         int ret;
00406 
00407         MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_pgcookie");
00408         dbenv = dbmfp->dbenv;
00409 
00410         if ((ret = __os_calloc(dbenv, 1, sizeof(*cookie), &cookie)) != 0)
00411                 return (ret);
00412         if ((ret = __os_malloc(dbenv, pgcookie->size, &cookie->data)) != 0) {
00413                 __os_free(dbenv, cookie);
00414                 return (ret);
00415         }
00416 
00417         memcpy(cookie->data, pgcookie->data, pgcookie->size);
00418         cookie->size = pgcookie->size;
00419 
00420         dbmfp->pgcookie = cookie;
00421         return (0);
00422 }
00423 
00424 /*
00425  * __memp_get_priority --
00426  *      Set the cache priority for pages from this file.
00427  */
00428 static int
00429 __memp_get_priority(dbmfp, priorityp)
00430         DB_MPOOLFILE *dbmfp;
00431         DB_CACHE_PRIORITY *priorityp;
00432 {
00433         switch (dbmfp->priority) {
00434         case MPOOL_PRI_VERY_LOW:
00435                 *priorityp = DB_PRIORITY_VERY_LOW;
00436                 break;
00437         case MPOOL_PRI_LOW:
00438                 *priorityp = DB_PRIORITY_LOW;
00439                 break;
00440         case MPOOL_PRI_DEFAULT:
00441                 *priorityp = DB_PRIORITY_DEFAULT;
00442                 break;
00443         case MPOOL_PRI_HIGH:
00444                 *priorityp = DB_PRIORITY_HIGH;
00445                 break;
00446         case MPOOL_PRI_VERY_HIGH:
00447                 *priorityp = DB_PRIORITY_VERY_HIGH;
00448                 break;
00449         default:
00450                 __db_err(dbmfp->dbenv,
00451                     "DB_MPOOLFILE->get_priority: unknown priority value: %d",
00452                     dbmfp->priority);
00453                 return (EINVAL);
00454         }
00455 
00456         return (0);
00457 }
00458 
00459 /*
00460  * __memp_set_priority --
00461  *      Set the cache priority for pages from this file.
00462  */
00463 static int
00464 __memp_set_priority(dbmfp, priority)
00465         DB_MPOOLFILE *dbmfp;
00466         DB_CACHE_PRIORITY priority;
00467 {
00468         switch (priority) {
00469         case DB_PRIORITY_VERY_LOW:
00470                 dbmfp->priority = MPOOL_PRI_VERY_LOW;
00471                 break;
00472         case DB_PRIORITY_LOW:
00473                 dbmfp->priority = MPOOL_PRI_LOW;
00474                 break;
00475         case DB_PRIORITY_DEFAULT:
00476                 dbmfp->priority = MPOOL_PRI_DEFAULT;
00477                 break;
00478         case DB_PRIORITY_HIGH:
00479                 dbmfp->priority = MPOOL_PRI_HIGH;
00480                 break;
00481         case DB_PRIORITY_VERY_HIGH:
00482                 dbmfp->priority = MPOOL_PRI_VERY_HIGH;
00483                 break;
00484         default:
00485                 __db_err(dbmfp->dbenv,
00486                     "DB_MPOOLFILE->set_priority: unknown priority value: %d",
00487                     priority);
00488                 return (EINVAL);
00489         }
00490 
00491         /* Update the underlying file if we've already opened it. */
00492         if (dbmfp->mfp != NULL)
00493                 dbmfp->mfp->priority = dbmfp->priority;
00494 
00495         return (0);
00496 }
00497 
00498 /*
00499  * __memp_last_pgno --
00500  *      Return the page number of the last page in the file.
00501  *
00502  * !!!
00503  * Undocumented interface: DB private.
00504  *
00505  * PUBLIC: int __memp_last_pgno __P((DB_MPOOLFILE *, db_pgno_t *));
00506  */
00507 int
00508 __memp_last_pgno(dbmfp, pgnoaddr)
00509         DB_MPOOLFILE *dbmfp;
00510         db_pgno_t *pgnoaddr;
00511 {
00512         DB_ENV *dbenv;
00513 
00514         dbenv = dbmfp->dbenv;
00515 
00516         MPOOL_SYSTEM_LOCK(dbenv);
00517         *pgnoaddr = dbmfp->mfp->last_pgno;
00518         MPOOL_SYSTEM_UNLOCK(dbenv);
00519 
00520         return (0);
00521 }
00522 
00523 /*
00524  * __memp_fn --
00525  *      On errors we print whatever is available as the file name.
00526  *
00527  * PUBLIC: char * __memp_fn __P((DB_MPOOLFILE *));
00528  */
00529 char *
00530 __memp_fn(dbmfp)
00531         DB_MPOOLFILE *dbmfp;
00532 {
00533         return (__memp_fns(dbmfp->dbenv->mp_handle, dbmfp->mfp));
00534 }
00535 
00536 /*
00537  * __memp_fns --
00538  *      On errors we print whatever is available as the file name.
00539  *
00540  * PUBLIC: char * __memp_fns __P((DB_MPOOL *, MPOOLFILE *));
00541  *
00542  */
00543 char *
00544 __memp_fns(dbmp, mfp)
00545         DB_MPOOL *dbmp;
00546         MPOOLFILE *mfp;
00547 {
00548         if (mfp->path_off == 0)
00549                 return ((char *)"temporary");
00550 
00551         return ((char *)R_ADDR(dbmp->reginfo, mfp->path_off));
00552 }

Generated on Sun Dec 25 12:14:41 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2