From ff8686c23badd5602bfb997c4fe761c19fa66f9e Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Tue, 6 Nov 2018 06:51:22 +0000 Subject: [PATCH] Add hooks for diskquota extension. Add BufferExtendCheckPerms_hook to support quota enforcement Add SmgrStat_hook to detect active relfilenodes. Co-authored-by: Haozhou Wang Co-authored-by: Hubert Zhang Co-authored-by: Hao Wu --- src/backend/storage/buffer/bufmgr.c | 14 ++++++++++++++ src/backend/storage/smgr/smgr.c | 21 ++++++++++++++++++++- src/include/storage/bufmgr.h | 8 ++++++++ src/include/storage/smgr.h | 6 ++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 01eabe5..d977350 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -104,6 +104,13 @@ typedef struct CkptTsStatus int index; } CkptTsStatus; +/* + * Hook for plugins to check permissions when doing a buffer extend. + * One example is to check whether there is additional disk quota for + * the table to be inserted. + */ +BufferExtendCheckPerms_hook_type BufferExtendCheckPerms_hook = NULL; + /* GUC variables */ bool zero_damaged_pages = false; int bgwriter_lru_maxpages = 100; @@ -661,6 +668,13 @@ ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, * miss. */ pgstat_count_buffer_read(reln); + + /* check permissions when doing a buffer extend */ + if (blockNum == P_NEW && BufferExtendCheckPerms_hook) + { + (*BufferExtendCheckPerms_hook)(reln->rd_id, blockNum); + } + buf = ReadBuffer_common(reln->rd_smgr, reln->rd_rel->relpersistence, forkNum, blockNum, mode, strategy, &hit); if (hit) diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 189342e..c5b218e 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -90,7 +90,11 @@ static const f_smgr smgrsw[] = { static const int NSmgr = lengthof(smgrsw); - +/* + * Hook for plugins to collect statistics from smgr functions + * One example is to record the active relfilenode information. + */ +SmgrStat_hook_type SmgrStat_hook = NULL; /* * Each backend has a hashtable that stores all extant SMgrRelation objects. * In addition, "unowned" SMgrRelation objects are chained together in a list. @@ -411,6 +415,11 @@ smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) isRedo); smgrsw[reln->smgr_which].smgr_create(reln, forknum, isRedo); + + if (SmgrStat_hook) + { + (*SmgrStat_hook)(reln); + } } /* @@ -617,6 +626,11 @@ smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, { smgrsw[reln->smgr_which].smgr_extend(reln, forknum, blocknum, buffer, skipFsync); + + if (SmgrStat_hook) + { + (*SmgrStat_hook)(reln); + } } /* @@ -720,6 +734,11 @@ smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks) * Do the truncation. */ smgrsw[reln->smgr_which].smgr_truncate(reln, forknum, nblocks); + + if (SmgrStat_hook) + { + (*SmgrStat_hook)(reln); + } } /* diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index 3cce390..153a7d3 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -160,6 +160,14 @@ extern PGDLLIMPORT int32 *LocalRefCount; #define BufferGetPage(buffer) ((Page)BufferGetBlock(buffer)) /* + * Hook for plugins to check permissions when doing a buffer extend. + * One example is to check whether there is additional disk quota for + * the table to be inserted. + */ +typedef bool (*BufferExtendCheckPerms_hook_type) (Oid, BlockNumber); +extern PGDLLIMPORT BufferExtendCheckPerms_hook_type BufferExtendCheckPerms_hook; + +/* * prototypes for functions in bufmgr.c */ extern bool ComputeIoConcurrency(int io_concurrency, double *target); diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index c843bbc..918e590 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -144,5 +144,11 @@ extern void RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, extern void ForgetRelationFsyncRequests(RelFileNode rnode, ForkNumber forknum); extern void ForgetDatabaseFsyncRequests(Oid dbid); extern void DropRelationFiles(RelFileNode *delrels, int ndelrels, bool isRedo); +/* + * Hook for plugins to collect statistics from smgr functions + * One example is to record the active relfilenode information. + */ +typedef void (*SmgrStat_hook_type)(SMgrRelation sreln); +extern PGDLLIMPORT SmgrStat_hook_type SmgrStat_hook; #endif /* SMGR_H */ -- 1.8.3.1