00001
00002
00003
00004
00005
00006
00007 #include "config.h"
00008
00009 #ifndef lint
00010 static const char revid[] = "$Id: mp__fput_8c-source.html,v 1.1 2008/06/08 10:20:47 sebdiaz Exp $";
00011 #endif
00012
00013 #ifndef NO_SYSTEM_INCLUDES
00014 #include <sys/types.h>
00015
00016 #include <errno.h>
00017 #endif
00018
00019 #ifdef HAVE_RPC
00020 #include "db_server.h"
00021 #endif
00022
00023 #include "db_int.h"
00024 #include "db_shash.h"
00025 #include "mp.h"
00026
00027 #ifdef HAVE_RPC
00028 #include "gen_client_ext.h"
00029 #include "rpc_client_ext.h"
00030 #endif
00031
00032
00033
00034
00035
00036 int
00037 CDB_memp_fput(dbmfp, pgaddr, flags)
00038 DB_MPOOLFILE *dbmfp;
00039 void *pgaddr;
00040 u_int32_t flags;
00041 {
00042 BH *bhp;
00043 DB_ENV *dbenv;
00044 DB_MPOOL *dbmp;
00045 MPOOL *c_mp, *mp;
00046 int ret, wrote;
00047
00048 dbmp = dbmfp->dbmp;
00049 dbenv = dbmp->dbenv;
00050 mp = dbmp->reginfo[0].primary;
00051
00052 #ifdef HAVE_RPC
00053 if (F_ISSET(dbenv, DB_ENV_RPCCLIENT))
00054 return (__dbcl_memp_fput(dbmfp, pgaddr, flags));
00055 #endif
00056
00057 PANIC_CHECK(dbenv);
00058
00059
00060 if (flags) {
00061 if ((ret = CDB___db_fchk(dbenv, "CDB_memp_fput", flags,
00062 DB_MPOOL_CLEAN | DB_MPOOL_DIRTY | DB_MPOOL_DISCARD)) != 0)
00063 return (ret);
00064 if ((ret = CDB___db_fcchk(dbenv, "CDB_memp_fput",
00065 flags, DB_MPOOL_CLEAN, DB_MPOOL_DIRTY)) != 0)
00066 return (ret);
00067
00068 if (LF_ISSET(DB_MPOOL_DIRTY) && F_ISSET(dbmfp, MP_READONLY)) {
00069 CDB___db_err(dbenv,
00070 "%s: dirty flag set for readonly file page",
00071 CDB___memp_fn(dbmfp));
00072 return (EACCES);
00073 }
00074 }
00075
00076 R_LOCK(dbenv, dbmp->reginfo);
00077
00078
00079 if (dbmfp->pinref == 0) {
00080 CDB___db_err(dbenv,
00081 "%s: more pages returned than retrieved", CDB___memp_fn(dbmfp));
00082 R_UNLOCK(dbenv, dbmp->reginfo);
00083 return (EINVAL);
00084 } else
00085 --dbmfp->pinref;
00086
00087
00088
00089
00090
00091
00092
00093 if (dbmfp->addr != NULL && pgaddr >= dbmfp->addr &&
00094 (u_int8_t *)pgaddr <= (u_int8_t *)dbmfp->addr + dbmfp->len) {
00095 R_UNLOCK(dbenv, dbmp->reginfo);
00096 return (0);
00097 }
00098
00099
00100 bhp = (BH *)((u_int8_t *)pgaddr - SSZA(BH, buf));
00101
00102
00103 c_mp = BH_TO_CACHE(dbmp, bhp);
00104
00105
00106
00107
00108 if (LF_ISSET(DB_MPOOL_CLEAN) && F_ISSET(bhp, BH_DIRTY)) {
00109 ++c_mp->stat.st_page_clean;
00110 --c_mp->stat.st_page_dirty;
00111 F_CLR(bhp, BH_DIRTY);
00112 }
00113 if (LF_ISSET(DB_MPOOL_DIRTY) && !F_ISSET(bhp, BH_DIRTY)) {
00114 --c_mp->stat.st_page_clean;
00115 ++c_mp->stat.st_page_dirty;
00116 F_SET(bhp, BH_DIRTY);
00117 }
00118 if (LF_ISSET(DB_MPOOL_DISCARD))
00119 F_SET(bhp, BH_DISCARD);
00120
00121
00122
00123
00124
00125 if (bhp->ref == 0) {
00126 CDB___db_err(dbenv, "%s: page %lu: unpinned page returned",
00127 CDB___memp_fn(dbmfp), (u_long)bhp->pgno);
00128 R_UNLOCK(dbenv, dbmp->reginfo);
00129 return (EINVAL);
00130 }
00131
00132
00133
00134
00135
00136
00137 if (--bhp->ref > 0) {
00138 R_UNLOCK(dbenv, dbmp->reginfo);
00139 return (0);
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149 SH_TAILQ_REMOVE(&c_mp->bhq, bhp, q, __bh);
00150 if (F_ISSET(bhp, BH_DISCARD))
00151 SH_TAILQ_INSERT_HEAD(&c_mp->bhq, bhp, q, __bh);
00152 else
00153 SH_TAILQ_INSERT_TAIL(&c_mp->bhq, bhp, q);
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 if (F_ISSET(bhp, BH_WRITE)) {
00166 if (F_ISSET(bhp, BH_DIRTY)) {
00167 if (CDB___memp_bhwrite(dbmp,
00168 dbmfp->mfp, bhp, NULL, &wrote) != 0 || !wrote)
00169 F_SET(mp, MP_LSN_RETRY);
00170 } else {
00171 F_CLR(bhp, BH_WRITE);
00172
00173 --mp->lsn_cnt;
00174 --dbmfp->mfp->lsn_cnt;
00175 }
00176 }
00177
00178 R_UNLOCK(dbenv, dbmp->reginfo);
00179 return (0);
00180 }