]> sourceware.org Git - glibc.git/blame - db2/mp/mp_fput.c
Update.
[glibc.git] / db2 / mp / mp_fput.c
CommitLineData
92f1da4d
UD
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1996, 1997
5 * Sleepycat Software. All rights reserved.
6 */
7#include "config.h"
8
9#ifndef lint
cc3fa755 10static const char sccsid[] = "@(#)mp_fput.c 10.14 (Sleepycat) 10/5/97";
92f1da4d
UD
11#endif /* not lint */
12
13#ifndef NO_SYSTEM_INCLUDES
14#include <sys/types.h>
15
16#include <errno.h>
17#include <stdlib.h>
18#endif
19
20#include "db_int.h"
21#include "shqueue.h"
22#include "db_shash.h"
23#include "mp.h"
24#include "common_ext.h"
25
26/*
27 * memp_fput --
28 * Mpool file put function.
29 */
30int
31memp_fput(dbmfp, pgaddr, flags)
32 DB_MPOOLFILE *dbmfp;
33 void *pgaddr;
a5a0310d 34 int flags;
92f1da4d
UD
35{
36 BH *bhp;
37 DB_MPOOL *dbmp;
cc3fa755 38 MPOOL *mp;
92f1da4d
UD
39 MPOOLFILE *mfp;
40 int wrote, ret;
41
42 dbmp = dbmfp->dbmp;
cc3fa755 43 mp = dbmp->mp;
92f1da4d
UD
44
45 /* Validate arguments. */
46 if (flags) {
47 if ((ret = __db_fchk(dbmp->dbenv, "memp_fput", flags,
48 DB_MPOOL_CLEAN | DB_MPOOL_DIRTY | DB_MPOOL_DISCARD)) != 0)
49 return (ret);
50 if ((ret = __db_fcchk(dbmp->dbenv, "memp_fput",
51 flags, DB_MPOOL_CLEAN, DB_MPOOL_DIRTY)) != 0)
52 return (ret);
53
54 if (LF_ISSET(DB_MPOOL_DIRTY) && F_ISSET(dbmfp, MP_READONLY)) {
55 __db_err(dbmp->dbenv,
56 "%s: dirty flag set for readonly file page",
57 dbmfp->path);
58 return (EACCES);
59 }
60 }
61
62 /* Decrement the pinned reference count. */
a5a0310d 63 LOCKHANDLE(dbmp, dbmfp->mutexp);
92f1da4d
UD
64 if (dbmfp->pinref == 0)
65 __db_err(dbmp->dbenv,
66 "%s: put: more blocks returned than retrieved",
67 dbmfp->path);
68 else
69 --dbmfp->pinref;
a5a0310d 70 UNLOCKHANDLE(dbmp, dbmfp->mutexp);
92f1da4d
UD
71
72 /*
73 * If we're mapping the file, there's nothing to do. Because we can
74 * quit mapping at any time, we have to check on each buffer to see
75 * if it's in the map region.
76 */
77 if (dbmfp->addr != NULL && pgaddr >= dbmfp->addr &&
78 (u_int8_t *)pgaddr <= (u_int8_t *)dbmfp->addr + dbmfp->len)
79 return (0);
80
81 /* Convert the page address to a buffer header. */
82 bhp = (BH *)((u_int8_t *)pgaddr - SSZA(BH, buf));
83
84 LOCKREGION(dbmp);
85
86 /* Set/clear the page bits. */
cc3fa755
UD
87 if (LF_ISSET(DB_MPOOL_CLEAN) && F_ISSET(bhp, BH_DIRTY)) {
88 ++mp->stat.st_page_clean;
89 --mp->stat.st_page_dirty;
92f1da4d 90 F_CLR(bhp, BH_DIRTY);
cc3fa755
UD
91 }
92 if (LF_ISSET(DB_MPOOL_DIRTY) && !F_ISSET(bhp, BH_DIRTY)) {
93 --mp->stat.st_page_clean;
94 ++mp->stat.st_page_dirty;
92f1da4d 95 F_SET(bhp, BH_DIRTY);
cc3fa755 96 }
92f1da4d
UD
97 if (LF_ISSET(DB_MPOOL_DISCARD))
98 F_SET(bhp, BH_DISCARD);
99
100 /*
101 * If more than one reference to the page, we're done. Ignore discard
102 * flags (for now) and leave it at its position in the LRU chain. The
103 * rest gets done at last reference close.
104 */
105#ifdef DEBUG
106 if (bhp->ref == 0) {
107 __db_err(dbmp->dbenv,
108 "Internal error: bhp->ref on page %lu went negative.",
109 (u_long)bhp->pgno);
110 abort();
111 }
112#endif
113 if (--bhp->ref > 0) {
114 UNLOCKREGION(dbmp);
115 return (0);
116 }
117
118 /* Move the buffer to the head/tail of the LRU chain. */
cc3fa755 119 SH_TAILQ_REMOVE(&mp->bhq, bhp, q, __bh);
92f1da4d 120 if (F_ISSET(bhp, BH_DISCARD))
cc3fa755 121 SH_TAILQ_INSERT_HEAD(&mp->bhq, bhp, q, __bh);
92f1da4d 122 else
cc3fa755 123 SH_TAILQ_INSERT_TAIL(&mp->bhq, bhp, q);
92f1da4d
UD
124
125 /*
126 * If this buffer is scheduled for writing because of a checkpoint,
127 * write it now. If we can't write it, set a flag so that the next
128 * time the memp_sync function is called we try writing it there,
129 * as the checkpoint application better be able to write all of the
130 * files.
131 */
132 if (F_ISSET(bhp, BH_WRITE))
133 if (F_ISSET(bhp, BH_DIRTY)) {
134 if (__memp_bhwrite(dbmp,
135 dbmfp->mfp, bhp, NULL, &wrote) != 0 || !wrote)
cc3fa755 136 F_SET(mp, MP_LSN_RETRY);
92f1da4d
UD
137 } else {
138 F_CLR(bhp, BH_WRITE);
139
cc3fa755 140 mfp = R_ADDR(dbmp, bhp->mf_offset);
92f1da4d
UD
141 --mfp->lsn_cnt;
142
cc3fa755 143 --mp->lsn_cnt;
92f1da4d
UD
144 }
145
146 UNLOCKREGION(dbmp);
147 return (0);
148}
This page took 0.047611 seconds and 5 git commands to generate.