PostgreSQL Source Code  git master
be-fsstubs.c File Reference
#include "postgres.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "libpq/be-fsstubs.h"
#include "libpq/libpq-fs.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "storage/large_object.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
Include dependency graph for be-fsstubs.c:

Go to the source code of this file.

Macros

#define BUFSIZE   8192
 
#define CreateFSContext()
 

Functions

static int newLOfd (LargeObjectDesc *lobjCookie)
 
static void deleteLOfd (int fd)
 
static Oid lo_import_internal (text *filename, Oid lobjOid)
 
Datum be_lo_open (PG_FUNCTION_ARGS)
 
Datum be_lo_close (PG_FUNCTION_ARGS)
 
int lo_read (int fd, char *buf, int len)
 
int lo_write (int fd, const char *buf, int len)
 
Datum be_lo_lseek (PG_FUNCTION_ARGS)
 
Datum be_lo_lseek64 (PG_FUNCTION_ARGS)
 
Datum be_lo_creat (PG_FUNCTION_ARGS)
 
Datum be_lo_create (PG_FUNCTION_ARGS)
 
Datum be_lo_tell (PG_FUNCTION_ARGS)
 
Datum be_lo_tell64 (PG_FUNCTION_ARGS)
 
Datum be_lo_unlink (PG_FUNCTION_ARGS)
 
Datum be_loread (PG_FUNCTION_ARGS)
 
Datum be_lowrite (PG_FUNCTION_ARGS)
 
Datum be_lo_import (PG_FUNCTION_ARGS)
 
Datum be_lo_import_with_oid (PG_FUNCTION_ARGS)
 
Datum be_lo_export (PG_FUNCTION_ARGS)
 
static void lo_truncate_internal (int32 fd, int64 len)
 
Datum be_lo_truncate (PG_FUNCTION_ARGS)
 
Datum be_lo_truncate64 (PG_FUNCTION_ARGS)
 
void AtEOXact_LargeObject (bool isCommit)
 
void AtEOSubXact_LargeObject (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
static bytealo_get_fragment_internal (Oid loOid, int64 offset, int32 nbytes)
 
Datum be_lo_get (PG_FUNCTION_ARGS)
 
Datum be_lo_get_fragment (PG_FUNCTION_ARGS)
 
Datum be_lo_from_bytea (PG_FUNCTION_ARGS)
 
Datum be_lo_put (PG_FUNCTION_ARGS)
 

Variables

static LargeObjectDesc ** cookies = NULL
 
static int cookies_size = 0
 
static MemoryContext fscxt = NULL
 

Macro Definition Documentation

◆ BUFSIZE

#define BUFSIZE   8192

Definition at line 57 of file be-fsstubs.c.

Referenced by be_lo_export(), and lo_import_internal().

◆ CreateFSContext

#define CreateFSContext ( )
Value:
do { \
if (fscxt == NULL) \
"Filesystem", \
} while (0)
#define AllocSetContextCreate
Definition: memutils.h:170
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static MemoryContext fscxt
Definition: be-fsstubs.c:70

Definition at line 72 of file be-fsstubs.c.

Referenced by be_lo_creat(), be_lo_create(), be_lo_export(), be_lo_from_bytea(), be_lo_open(), be_lo_put(), lo_get_fragment_internal(), and lo_import_internal().

Function Documentation

◆ AtEOSubXact_LargeObject()

void AtEOSubXact_LargeObject ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

Definition at line 632 of file be-fsstubs.c.

References cookies_size, deleteLOfd(), i, inv_close(), and LargeObjectDesc::subid.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

634 {
635  int i;
636 
637  if (fscxt == NULL) /* no LO operations in this xact */
638  return;
639 
640  for (i = 0; i < cookies_size; i++)
641  {
642  LargeObjectDesc *lo = cookies[i];
643 
644  if (lo != NULL && lo->subid == mySubid)
645  {
646  if (isCommit)
647  lo->subid = parentSubid;
648  else
649  {
650  /*
651  * Make sure we do not call inv_close twice if it errors out
652  * for some reason. Better a leak than a crash.
653  */
654  deleteLOfd(i);
655  inv_close(lo);
656  }
657  }
658  }
659 }
static void deleteLOfd(int fd)
Definition: be-fsstubs.c:709
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
SubTransactionId subid
Definition: large_object.h:43
static int cookies_size
Definition: be-fsstubs.c:68
static MemoryContext fscxt
Definition: be-fsstubs.c:70
int i
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

◆ AtEOXact_LargeObject()

void AtEOXact_LargeObject ( bool  isCommit)

Definition at line 591 of file be-fsstubs.c.

References close_lo_relation(), cookies_size, deleteLOfd(), i, inv_close(), and MemoryContextDelete().

Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().

592 {
593  int i;
594 
595  if (fscxt == NULL)
596  return; /* no LO operations in this xact */
597 
598  /*
599  * Close LO fds and clear cookies array so that LO fds are no longer good.
600  * On abort we skip the close step.
601  */
602  for (i = 0; i < cookies_size; i++)
603  {
604  if (cookies[i] != NULL)
605  {
606  if (isCommit)
607  inv_close(cookies[i]);
608  deleteLOfd(i);
609  }
610  }
611 
612  /* Needn't actually pfree since we're about to zap context */
613  cookies = NULL;
614  cookies_size = 0;
615 
616  /* Release the LO memory context to prevent permanent memory leaks. */
618  fscxt = NULL;
619 
620  /* Give inv_api.c a chance to clean up, too */
621  close_lo_relation(isCommit);
622 }
static void deleteLOfd(int fd)
Definition: be-fsstubs.c:709
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
void close_lo_relation(bool isCommit)
Definition: inv_api.c:98
static int cookies_size
Definition: be-fsstubs.c:68
static MemoryContext fscxt
Definition: be-fsstubs.c:70
int i
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

◆ be_lo_close()

Datum be_lo_close ( PG_FUNCTION_ARGS  )

Definition at line 112 of file be-fsstubs.c.

References cookies_size, DEBUG4, deleteLOfd(), elog, ereport, errcode(), errmsg(), ERROR, fd(), inv_close(), PG_GETARG_INT32, and PG_RETURN_INT32.

113 {
114  int32 fd = PG_GETARG_INT32(0);
115 
116  if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
117  ereport(ERROR,
118  (errcode(ERRCODE_UNDEFINED_OBJECT),
119  errmsg("invalid large-object descriptor: %d", fd)));
120 
121 #ifdef FSDB
122  elog(DEBUG4, "lo_close(%d)", fd);
123 #endif
124 
125  inv_close(cookies[fd]);
126 
127  deleteLOfd(fd);
128 
129  PG_RETURN_INT32(0);
130 }
static void deleteLOfd(int fd)
Definition: be-fsstubs.c:709
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
int errcode(int sqlerrcode)
Definition: elog.c:608
#define DEBUG4
Definition: elog.h:22
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:347
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define elog(elevel,...)
Definition: elog.h:228
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

◆ be_lo_creat()

Datum be_lo_creat ( PG_FUNCTION_ARGS  )

Definition at line 237 of file be-fsstubs.c.

References CreateFSContext, inv_create(), InvalidOid, and PG_RETURN_OID.

238 {
239  Oid lobjId;
240 
241  /*
242  * We don't actually need to store into fscxt, but create it anyway to
243  * ensure that AtEOXact_LargeObject knows there is state to clean up
244  */
245  CreateFSContext();
246 
247  lobjId = inv_create(InvalidOid);
248 
249  PG_RETURN_OID(lobjId);
250 }
Oid inv_create(Oid lobjId)
Definition: inv_api.c:211
#define CreateFSContext()
Definition: be-fsstubs.c:72
unsigned int Oid
Definition: postgres_ext.h:31
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_RETURN_OID(x)
Definition: fmgr.h:350

◆ be_lo_create()

Datum be_lo_create ( PG_FUNCTION_ARGS  )

Definition at line 253 of file be-fsstubs.c.

References CreateFSContext, inv_create(), PG_GETARG_OID, and PG_RETURN_OID.

254 {
255  Oid lobjId = PG_GETARG_OID(0);
256 
257  /*
258  * We don't actually need to store into fscxt, but create it anyway to
259  * ensure that AtEOXact_LargeObject knows there is state to clean up
260  */
261  CreateFSContext();
262 
263  lobjId = inv_create(lobjId);
264 
265  PG_RETURN_OID(lobjId);
266 }
Oid inv_create(Oid lobjId)
Definition: inv_api.c:211
#define CreateFSContext()
Definition: be-fsstubs.c:72
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_OID(x)
Definition: fmgr.h:350

◆ be_lo_export()

Datum be_lo_export ( PG_FUNCTION_ARGS  )

Definition at line 473 of file be-fsstubs.c.

References buf, BUFSIZE, CloseTransientFile(), CreateFSContext, ereport, errcode_for_file_access(), errmsg(), ERROR, fd(), filename, inv_close(), inv_open(), INV_READ, inv_read(), MAXPGPATH, OpenTransientFilePerm(), PG_BINARY, PG_END_TRY, PG_FINALLY, PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_RETURN_INT32, PG_TRY, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, text_to_cstring_buffer(), and write.

474 {
475  Oid lobjId = PG_GETARG_OID(0);
477  int fd;
478  int nbytes,
479  tmp;
480  char buf[BUFSIZE];
481  char fnamebuf[MAXPGPATH];
482  LargeObjectDesc *lobj;
483  mode_t oumask;
484 
485  CreateFSContext();
486 
487  /*
488  * open the inversion object (no need to test for failure)
489  */
490  lobj = inv_open(lobjId, INV_READ, fscxt);
491 
492  /*
493  * open the file to be written to
494  *
495  * Note: we reduce backend's normal 077 umask to the slightly friendlier
496  * 022. This code used to drop it all the way to 0, but creating
497  * world-writable export files doesn't seem wise.
498  */
499  text_to_cstring_buffer(filename, fnamebuf, sizeof(fnamebuf));
500  oumask = umask(S_IWGRP | S_IWOTH);
501  PG_TRY();
502  {
503  fd = OpenTransientFilePerm(fnamebuf, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY,
505  }
506  PG_FINALLY();
507  {
508  umask(oumask);
509  }
510  PG_END_TRY();
511  if (fd < 0)
512  ereport(ERROR,
514  errmsg("could not create server file \"%s\": %m",
515  fnamebuf)));
516 
517  /*
518  * read in from the inversion file and write to the filesystem
519  */
520  while ((nbytes = inv_read(lobj, buf, BUFSIZE)) > 0)
521  {
522  tmp = write(fd, buf, nbytes);
523  if (tmp != nbytes)
524  ereport(ERROR,
526  errmsg("could not write server file \"%s\": %m",
527  fnamebuf)));
528  }
529 
530  if (CloseTransientFile(fd) != 0)
531  ereport(ERROR,
533  errmsg("could not close file \"%s\": %m",
534  fnamebuf)));
535 
536  inv_close(lobj);
537 
538  PG_RETURN_INT32(1);
539 }
#define S_IRGRP
Definition: win32_port.h:272
#define BUFSIZE
Definition: be-fsstubs.c:57
#define write(a, b, c)
Definition: win32.h:14
#define S_IWOTH
Definition: win32_port.h:287
int OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:2301
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define S_IROTH
Definition: win32_port.h:284
#define CreateFSContext()
Definition: be-fsstubs.c:72
unsigned int Oid
Definition: postgres_ext.h:31
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition: varlena.c:235
#define PG_BINARY
Definition: c.h:1222
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define INV_READ
Definition: libpq-fs.h:22
#define S_IWUSR
Definition: win32_port.h:263
#define ERROR
Definition: elog.h:43
#define MAXPGPATH
static char * buf
Definition: pg_test_fsync.c:67
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
int errcode_for_file_access(void)
Definition: elog.c:631
#define S_IWGRP
Definition: win32_port.h:275
#define ereport(elevel, rest)
Definition: elog.h:141
int CloseTransientFile(int fd)
Definition: fd.c:2469
#define PG_FINALLY()
Definition: elog.h:339
#define S_IRUSR
Definition: win32_port.h:260
static char * filename
Definition: pg_dumpall.c:90
LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt)
Definition: inv_api.c:252
int errmsg(const char *fmt,...)
Definition: elog.c:822
static MemoryContext fscxt
Definition: be-fsstubs.c:70
Definition: c.h:556
#define PG_TRY()
Definition: elog.h:322
int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
Definition: inv_api.c:494
#define PG_END_TRY()
Definition: elog.h:347

◆ be_lo_from_bytea()

Datum be_lo_from_bytea ( PG_FUNCTION_ARGS  )

Definition at line 813 of file be-fsstubs.c.

References Assert, CreateFSContext, inv_close(), inv_create(), inv_open(), INV_WRITE, inv_write(), PG_GETARG_BYTEA_PP, PG_GETARG_OID, PG_RETURN_OID, PG_USED_FOR_ASSERTS_ONLY, generate_unaccent_rules::str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

814 {
815  Oid loOid = PG_GETARG_OID(0);
817  LargeObjectDesc *loDesc;
818  int written PG_USED_FOR_ASSERTS_ONLY;
819 
820  CreateFSContext();
821 
822  loOid = inv_create(loOid);
823  loDesc = inv_open(loOid, INV_WRITE, fscxt);
824  written = inv_write(loDesc, VARDATA_ANY(str), VARSIZE_ANY_EXHDR(str));
825  Assert(written == VARSIZE_ANY_EXHDR(str));
826  inv_close(loDesc);
827 
828  PG_RETURN_OID(loOid);
829 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
Oid inv_create(Oid lobjId)
Definition: inv_api.c:211
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
#define CreateFSContext()
Definition: be-fsstubs.c:72
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define Assert(condition)
Definition: c.h:739
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define INV_WRITE
Definition: libpq-fs.h:21
LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt)
Definition: inv_api.c:252
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
static MemoryContext fscxt
Definition: be-fsstubs.c:70
Definition: c.h:556
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:123
#define PG_RETURN_OID(x)
Definition: fmgr.h:350
int inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
Definition: inv_api.c:587

◆ be_lo_get()

Datum be_lo_get ( PG_FUNCTION_ARGS  )

Definition at line 778 of file be-fsstubs.c.

References lo_get_fragment_internal(), PG_GETARG_OID, and PG_RETURN_BYTEA_P.

779 {
780  Oid loOid = PG_GETARG_OID(0);
781  bytea *result;
782 
783  result = lo_get_fragment_internal(loOid, 0, -1);
784 
785  PG_RETURN_BYTEA_P(result);
786 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
unsigned int Oid
Definition: postgres_ext.h:31
static bytea * lo_get_fragment_internal(Oid loOid, int64 offset, int32 nbytes)
Definition: be-fsstubs.c:722
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
Definition: c.h:556

◆ be_lo_get_fragment()

Datum be_lo_get_fragment ( PG_FUNCTION_ARGS  )

Definition at line 792 of file be-fsstubs.c.

References ereport, errcode(), errmsg(), ERROR, lo_get_fragment_internal(), PG_GETARG_INT32, PG_GETARG_INT64, PG_GETARG_OID, and PG_RETURN_BYTEA_P.

793 {
794  Oid loOid = PG_GETARG_OID(0);
795  int64 offset = PG_GETARG_INT64(1);
796  int32 nbytes = PG_GETARG_INT32(2);
797  bytea *result;
798 
799  if (nbytes < 0)
800  ereport(ERROR,
801  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
802  errmsg("requested length cannot be negative")));
803 
804  result = lo_get_fragment_internal(loOid, offset, nbytes);
805 
806  PG_RETURN_BYTEA_P(result);
807 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
int errcode(int sqlerrcode)
Definition: elog.c:608
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:347
#define ERROR
Definition: elog.h:43
static bytea * lo_get_fragment_internal(Oid loOid, int64 offset, int32 nbytes)
Definition: be-fsstubs.c:722
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: c.h:556
#define PG_GETARG_INT64(n)
Definition: fmgr.h:277

◆ be_lo_import()

Datum be_lo_import ( PG_FUNCTION_ARGS  )

Definition at line 391 of file be-fsstubs.c.

References filename, InvalidOid, lo_import_internal(), PG_GETARG_TEXT_PP, and PG_RETURN_OID.

392 {
394 
396 }
static Oid lo_import_internal(text *filename, Oid lobjOid)
Definition: be-fsstubs.c:412
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define InvalidOid
Definition: postgres_ext.h:36
static char * filename
Definition: pg_dumpall.c:90
Definition: c.h:556
#define PG_RETURN_OID(x)
Definition: fmgr.h:350

◆ be_lo_import_with_oid()

Datum be_lo_import_with_oid ( PG_FUNCTION_ARGS  )

Definition at line 403 of file be-fsstubs.c.

References filename, lo_import_internal(), PG_GETARG_OID, PG_GETARG_TEXT_PP, and PG_RETURN_OID.

404 {
406  Oid oid = PG_GETARG_OID(1);
407 
408  PG_RETURN_OID(lo_import_internal(filename, oid));
409 }
static Oid lo_import_internal(text *filename, Oid lobjOid)
Definition: be-fsstubs.c:412
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
static char * filename
Definition: pg_dumpall.c:90
Definition: c.h:556
#define PG_RETURN_OID(x)
Definition: fmgr.h:350

◆ be_lo_lseek()

Datum be_lo_lseek ( PG_FUNCTION_ARGS  )

Definition at line 194 of file be-fsstubs.c.

References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), inv_seek(), PG_GETARG_INT32, PG_RETURN_INT32, and status().

195 {
196  int32 fd = PG_GETARG_INT32(0);
197  int32 offset = PG_GETARG_INT32(1);
198  int32 whence = PG_GETARG_INT32(2);
199  int64 status;
200 
201  if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
202  ereport(ERROR,
203  (errcode(ERRCODE_UNDEFINED_OBJECT),
204  errmsg("invalid large-object descriptor: %d", fd)));
205 
206  status = inv_seek(cookies[fd], offset, whence);
207 
208  /* guard against result overflow */
209  if (status != (int32) status)
210  ereport(ERROR,
211  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
212  errmsg("lo_lseek result out of range for large-object descriptor %d",
213  fd)));
214 
215  PG_RETURN_INT32((int32) status);
216 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence)
Definition: inv_api.c:432
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
int errcode(int sqlerrcode)
Definition: elog.c:608
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:347
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:822
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226

◆ be_lo_lseek64()

Datum be_lo_lseek64 ( PG_FUNCTION_ARGS  )

Definition at line 219 of file be-fsstubs.c.

References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), inv_seek(), PG_GETARG_INT32, PG_GETARG_INT64, PG_RETURN_INT64, and status().

220 {
221  int32 fd = PG_GETARG_INT32(0);
222  int64 offset = PG_GETARG_INT64(1);
223  int32 whence = PG_GETARG_INT32(2);
224  int64 status;
225 
226  if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
227  ereport(ERROR,
228  (errcode(ERRCODE_UNDEFINED_OBJECT),
229  errmsg("invalid large-object descriptor: %d", fd)));
230 
231  status = inv_seek(cookies[fd], offset, whence);
232 
233  PG_RETURN_INT64(status);
234 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence)
Definition: inv_api.c:432
#define PG_RETURN_INT64(x)
Definition: fmgr.h:357
int errcode(int sqlerrcode)
Definition: elog.c:608
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:347
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:822
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226
#define PG_GETARG_INT64(n)
Definition: fmgr.h:277

◆ be_lo_open()

Datum be_lo_open ( PG_FUNCTION_ARGS  )

Definition at line 91 of file be-fsstubs.c.

References CreateFSContext, DEBUG4, elog, fd(), inv_open(), mode, newLOfd(), PG_GETARG_INT32, PG_GETARG_OID, and PG_RETURN_INT32.

92 {
93  Oid lobjId = PG_GETARG_OID(0);
95  LargeObjectDesc *lobjDesc;
96  int fd;
97 
98 #ifdef FSDB
99  elog(DEBUG4, "lo_open(%u,%d)", lobjId, mode);
100 #endif
101 
102  CreateFSContext();
103 
104  lobjDesc = inv_open(lobjId, mode, fscxt);
105 
106  fd = newLOfd(lobjDesc);
107 
108  PG_RETURN_INT32(fd);
109 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define CreateFSContext()
Definition: be-fsstubs.c:72
unsigned int Oid
Definition: postgres_ext.h:31
#define DEBUG4
Definition: elog.h:22
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:347
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt)
Definition: inv_api.c:252
static MemoryContext fscxt
Definition: be-fsstubs.c:70
#define elog(elevel,...)
Definition: elog.h:228
static int newLOfd(LargeObjectDesc *lobjCookie)
Definition: be-fsstubs.c:666

◆ be_lo_put()

Datum be_lo_put ( PG_FUNCTION_ARGS  )

Definition at line 835 of file be-fsstubs.c.

References ACL_UPDATE, ACLCHECK_OK, Assert, CreateFSContext, ereport, errcode(), errmsg(), ERROR, GetUserId(), LargeObjectDesc::id, inv_close(), inv_open(), inv_seek(), INV_WRITE, inv_write(), lo_compat_privileges, PG_GETARG_BYTEA_PP, PG_GETARG_INT64, PG_GETARG_OID, pg_largeobject_aclcheck_snapshot(), PG_RETURN_VOID, PG_USED_FOR_ASSERTS_ONLY, LargeObjectDesc::snapshot, generate_unaccent_rules::str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

836 {
837  Oid loOid = PG_GETARG_OID(0);
838  int64 offset = PG_GETARG_INT64(1);
840  LargeObjectDesc *loDesc;
841  int written PG_USED_FOR_ASSERTS_ONLY;
842 
843  CreateFSContext();
844 
845  loDesc = inv_open(loOid, INV_WRITE, fscxt);
846 
847  /* Permission check */
848  if (!lo_compat_privileges &&
850  GetUserId(),
851  ACL_UPDATE,
852  loDesc->snapshot) != ACLCHECK_OK)
853  ereport(ERROR,
854  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
855  errmsg("permission denied for large object %u",
856  loDesc->id)));
857 
858  inv_seek(loDesc, offset, SEEK_SET);
859  written = inv_write(loDesc, VARDATA_ANY(str), VARSIZE_ANY_EXHDR(str));
860  Assert(written == VARSIZE_ANY_EXHDR(str));
861  inv_close(loDesc);
862 
863  PG_RETURN_VOID();
864 }
int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence)
Definition: inv_api.c:432
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
bool lo_compat_privileges
Definition: inv_api.c:57
Oid GetUserId(void)
Definition: miscinit.c:380
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
int errcode(int sqlerrcode)
Definition: elog.c:608
#define CreateFSContext()
Definition: be-fsstubs.c:72
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
Snapshot snapshot
Definition: large_object.h:42
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define ereport(elevel, rest)
Definition: elog.h:141
#define ACL_UPDATE
Definition: parsenodes.h:76
#define PG_RETURN_VOID()
Definition: fmgr.h:339
#define Assert(condition)
Definition: c.h:739
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define INV_WRITE
Definition: libpq-fs.h:21
LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt)
Definition: inv_api.c:252
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:822
static MemoryContext fscxt
Definition: be-fsstubs.c:70
AclResult pg_largeobject_aclcheck_snapshot(Oid lobj_oid, Oid roleid, AclMode mode, Snapshot snapshot)
Definition: aclchk.c:4677
Definition: c.h:556
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:123
#define PG_GETARG_INT64(n)
Definition: fmgr.h:277
int inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
Definition: inv_api.c:587

◆ be_lo_tell()

Datum be_lo_tell ( PG_FUNCTION_ARGS  )

Definition at line 269 of file be-fsstubs.c.

References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), inv_tell(), PG_GETARG_INT32, and PG_RETURN_INT32.

270 {
271  int32 fd = PG_GETARG_INT32(0);
272  int64 offset;
273 
274  if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
275  ereport(ERROR,
276  (errcode(ERRCODE_UNDEFINED_OBJECT),
277  errmsg("invalid large-object descriptor: %d", fd)));
278 
279  offset = inv_tell(cookies[fd]);
280 
281  /* guard against result overflow */
282  if (offset != (int32) offset)
283  ereport(ERROR,
284  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
285  errmsg("lo_tell result out of range for large-object descriptor %d",
286  fd)));
287 
288  PG_RETURN_INT32((int32) offset);
289 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
int errcode(int sqlerrcode)
Definition: elog.c:608
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:347
int64 inv_tell(LargeObjectDesc *obj_desc)
Definition: inv_api.c:481
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:822
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

◆ be_lo_tell64()

Datum be_lo_tell64 ( PG_FUNCTION_ARGS  )

Definition at line 292 of file be-fsstubs.c.

References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), inv_tell(), PG_GETARG_INT32, and PG_RETURN_INT64.

293 {
294  int32 fd = PG_GETARG_INT32(0);
295  int64 offset;
296 
297  if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
298  ereport(ERROR,
299  (errcode(ERRCODE_UNDEFINED_OBJECT),
300  errmsg("invalid large-object descriptor: %d", fd)));
301 
302  offset = inv_tell(cookies[fd]);
303 
304  PG_RETURN_INT64(offset);
305 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_RETURN_INT64(x)
Definition: fmgr.h:357
int errcode(int sqlerrcode)
Definition: elog.c:608
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:347
int64 inv_tell(LargeObjectDesc *obj_desc)
Definition: inv_api.c:481
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:822
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

◆ be_lo_truncate()

Datum be_lo_truncate ( PG_FUNCTION_ARGS  )

Definition at line 567 of file be-fsstubs.c.

References fd(), lo_truncate_internal(), PG_GETARG_INT32, and PG_RETURN_INT32.

568 {
569  int32 fd = PG_GETARG_INT32(0);
570  int32 len = PG_GETARG_INT32(1);
571 
572  lo_truncate_internal(fd, len);
573  PG_RETURN_INT32(0);
574 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
static void lo_truncate_internal(int32 fd, int64 len)
Definition: be-fsstubs.c:546
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:347

◆ be_lo_truncate64()

Datum be_lo_truncate64 ( PG_FUNCTION_ARGS  )

Definition at line 577 of file be-fsstubs.c.

References fd(), lo_truncate_internal(), PG_GETARG_INT32, PG_GETARG_INT64, and PG_RETURN_INT32.

578 {
579  int32 fd = PG_GETARG_INT32(0);
580  int64 len = PG_GETARG_INT64(1);
581 
582  lo_truncate_internal(fd, len);
583  PG_RETURN_INT32(0);
584 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
static void lo_truncate_internal(int32 fd, int64 len)
Definition: be-fsstubs.c:546
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:347
#define PG_GETARG_INT64(n)
Definition: fmgr.h:277

◆ be_lo_unlink()

Datum be_lo_unlink ( PG_FUNCTION_ARGS  )

Definition at line 308 of file be-fsstubs.c.

References cookies_size, deleteLOfd(), ereport, errcode(), errmsg(), ERROR, GetUserId(), i, inv_close(), inv_drop(), lo_compat_privileges, PG_GETARG_OID, pg_largeobject_ownercheck(), and PG_RETURN_INT32.

Referenced by lo_manage().

309 {
310  Oid lobjId = PG_GETARG_OID(0);
311 
312  /*
313  * Must be owner of the large object. It would be cleaner to check this
314  * in inv_drop(), but we want to throw the error before not after closing
315  * relevant FDs.
316  */
317  if (!lo_compat_privileges &&
319  ereport(ERROR,
320  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
321  errmsg("must be owner of large object %u", lobjId)));
322 
323  /*
324  * If there are any open LO FDs referencing that ID, close 'em.
325  */
326  if (fscxt != NULL)
327  {
328  int i;
329 
330  for (i = 0; i < cookies_size; i++)
331  {
332  if (cookies[i] != NULL && cookies[i]->id == lobjId)
333  {
334  inv_close(cookies[i]);
335  deleteLOfd(i);
336  }
337  }
338  }
339 
340  /*
341  * inv_drop does not create a need for end-of-transaction cleanup and
342  * hence we don't need to have created fscxt.
343  */
344  PG_RETURN_INT32(inv_drop(lobjId));
345 }
static void deleteLOfd(int fd)
Definition: be-fsstubs.c:709
bool lo_compat_privileges
Definition: inv_api.c:57
bool pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid)
Definition: aclchk.c:4886
Oid GetUserId(void)
Definition: miscinit.c:380
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
int errcode(int sqlerrcode)
Definition: elog.c:608
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
int inv_drop(Oid lobjId)
Definition: inv_api.c:355
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define ereport(elevel, rest)
Definition: elog.h:141
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:822
static MemoryContext fscxt
Definition: be-fsstubs.c:70
int i
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

◆ be_loread()

Datum be_loread ( PG_FUNCTION_ARGS  )

Definition at line 352 of file be-fsstubs.c.

References fd(), lo_read(), palloc(), PG_GETARG_INT32, PG_RETURN_BYTEA_P, SET_VARSIZE, VARDATA, and VARHDRSZ.

353 {
354  int32 fd = PG_GETARG_INT32(0);
355  int32 len = PG_GETARG_INT32(1);
356  bytea *retval;
357  int totalread;
358 
359  if (len < 0)
360  len = 0;
361 
362  retval = (bytea *) palloc(VARHDRSZ + len);
363  totalread = lo_read(fd, VARDATA(retval), len);
364  SET_VARSIZE(retval, totalread + VARHDRSZ);
365 
366  PG_RETURN_BYTEA_P(retval);
367 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:562
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:347
int lo_read(int fd, char *buf, int len)
Definition: be-fsstubs.c:142
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:556
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ be_lowrite()

Datum be_lowrite ( PG_FUNCTION_ARGS  )

Definition at line 370 of file be-fsstubs.c.

References fd(), lo_write(), PG_GETARG_BYTEA_PP, PG_GETARG_INT32, PG_RETURN_INT32, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

371 {
372  int32 fd = PG_GETARG_INT32(0);
373  bytea *wbuf = PG_GETARG_BYTEA_PP(1);
374  int bytestowrite;
375  int totalwritten;
376 
377  bytestowrite = VARSIZE_ANY_EXHDR(wbuf);
378  totalwritten = lo_write(fd, VARDATA_ANY(wbuf), bytestowrite);
379  PG_RETURN_INT32(totalwritten);
380 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:347
int lo_write(int fd, const char *buf, int len)
Definition: be-fsstubs.c:170
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:556

◆ deleteLOfd()

static void deleteLOfd ( int  fd)
static

Definition at line 709 of file be-fsstubs.c.

References fd().

Referenced by AtEOSubXact_LargeObject(), AtEOXact_LargeObject(), be_lo_close(), and be_lo_unlink().

710 {
711  cookies[fd] = NULL;
712 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

◆ lo_get_fragment_internal()

static bytea* lo_get_fragment_internal ( Oid  loOid,
int64  offset,
int32  nbytes 
)
static

Definition at line 722 of file be-fsstubs.c.

References Assert, CreateFSContext, ereport, errcode(), errmsg(), ERROR, inv_close(), inv_open(), INV_READ, inv_read(), inv_seek(), MaxAllocSize, palloc(), PG_USED_FOR_ASSERTS_ONLY, SET_VARSIZE, VARDATA, and VARHDRSZ.

Referenced by be_lo_get(), and be_lo_get_fragment().

723 {
724  LargeObjectDesc *loDesc;
725  int64 loSize;
726  int64 result_length;
727  int total_read PG_USED_FOR_ASSERTS_ONLY;
728  bytea *result = NULL;
729 
730  /*
731  * We don't actually need to store into fscxt, but create it anyway to
732  * ensure that AtEOXact_LargeObject knows there is state to clean up
733  */
734  CreateFSContext();
735 
736  loDesc = inv_open(loOid, INV_READ, fscxt);
737 
738  /*
739  * Compute number of bytes we'll actually read, accommodating nbytes == -1
740  * and reads beyond the end of the LO.
741  */
742  loSize = inv_seek(loDesc, 0, SEEK_END);
743  if (loSize > offset)
744  {
745  if (nbytes >= 0 && nbytes <= loSize - offset)
746  result_length = nbytes; /* request is wholly inside LO */
747  else
748  result_length = loSize - offset; /* adjust to end of LO */
749  }
750  else
751  result_length = 0; /* request is wholly outside LO */
752 
753  /*
754  * A result_length calculated from loSize may not fit in a size_t. Check
755  * that the size will satisfy this and subsequently-enforced size limits.
756  */
757  if (result_length > MaxAllocSize - VARHDRSZ)
758  ereport(ERROR,
759  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
760  errmsg("large object read request is too large")));
761 
762  result = (bytea *) palloc(VARHDRSZ + result_length);
763 
764  inv_seek(loDesc, offset, SEEK_SET);
765  total_read = inv_read(loDesc, VARDATA(result), result_length);
766  Assert(total_read == result_length);
767  SET_VARSIZE(result, result_length + VARHDRSZ);
768 
769  inv_close(loDesc);
770 
771  return result;
772 }
int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence)
Definition: inv_api.c:432
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:562
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
int errcode(int sqlerrcode)
Definition: elog.c:608
#define CreateFSContext()
Definition: be-fsstubs.c:72
#define INV_READ
Definition: libpq-fs.h:22
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define MaxAllocSize
Definition: memutils.h:40
#define Assert(condition)
Definition: c.h:739
LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt)
Definition: inv_api.c:252
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
static MemoryContext fscxt
Definition: be-fsstubs.c:70
Definition: c.h:556
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:123
int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
Definition: inv_api.c:494

◆ lo_import_internal()

static Oid lo_import_internal ( text filename,
Oid  lobjOid 
)
static

Definition at line 412 of file be-fsstubs.c.

References Assert, buf, BUFSIZE, CloseTransientFile(), CreateFSContext, ereport, errcode_for_file_access(), errmsg(), ERROR, fd(), inv_close(), inv_create(), inv_open(), INV_WRITE, inv_write(), MAXPGPATH, OpenTransientFile(), PG_BINARY, PG_USED_FOR_ASSERTS_ONLY, read, and text_to_cstring_buffer().

Referenced by be_lo_import(), and be_lo_import_with_oid().

413 {
414  int fd;
415  int nbytes,
417  char buf[BUFSIZE];
418  char fnamebuf[MAXPGPATH];
419  LargeObjectDesc *lobj;
420  Oid oid;
421 
422  CreateFSContext();
423 
424  /*
425  * open the file to be read in
426  */
427  text_to_cstring_buffer(filename, fnamebuf, sizeof(fnamebuf));
428  fd = OpenTransientFile(fnamebuf, O_RDONLY | PG_BINARY);
429  if (fd < 0)
430  ereport(ERROR,
432  errmsg("could not open server file \"%s\": %m",
433  fnamebuf)));
434 
435  /*
436  * create an inversion object
437  */
438  oid = inv_create(lobjOid);
439 
440  /*
441  * read in from the filesystem and write to the inversion object
442  */
443  lobj = inv_open(oid, INV_WRITE, fscxt);
444 
445  while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
446  {
447  tmp = inv_write(lobj, buf, nbytes);
448  Assert(tmp == nbytes);
449  }
450 
451  if (nbytes < 0)
452  ereport(ERROR,
454  errmsg("could not read server file \"%s\": %m",
455  fnamebuf)));
456 
457  inv_close(lobj);
458 
459  if (CloseTransientFile(fd) != 0)
460  ereport(ERROR,
462  errmsg("could not close file \"%s\": %m",
463  fnamebuf)));
464 
465  return oid;
466 }
#define BUFSIZE
Definition: be-fsstubs.c:57
Oid inv_create(Oid lobjId)
Definition: inv_api.c:211
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
#define CreateFSContext()
Definition: be-fsstubs.c:72
unsigned int Oid
Definition: postgres_ext.h:31
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition: varlena.c:235
#define PG_BINARY
Definition: c.h:1222
#define ERROR
Definition: elog.h:43
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2292
#define MAXPGPATH
static char * buf
Definition: pg_test_fsync.c:67
int errcode_for_file_access(void)
Definition: elog.c:631
#define ereport(elevel, rest)
Definition: elog.h:141
int CloseTransientFile(int fd)
Definition: fd.c:2469
#define Assert(condition)
Definition: c.h:739
#define INV_WRITE
Definition: libpq-fs.h:21
LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt)
Definition: inv_api.c:252
int errmsg(const char *fmt,...)
Definition: elog.c:822
static MemoryContext fscxt
Definition: be-fsstubs.c:70
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:123
#define read(a, b, c)
Definition: win32.h:13
int inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
Definition: inv_api.c:587

◆ lo_read()

int lo_read ( int  fd,
char *  buf,
int  len 
)

Definition at line 142 of file be-fsstubs.c.

References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), LargeObjectDesc::flags, IFS_RDLOCK, inv_read(), and status().

Referenced by be_loread(), dumpBlobs(), exportFile(), and pickout().

143 {
144  int status;
145  LargeObjectDesc *lobj;
146 
147  if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
148  ereport(ERROR,
149  (errcode(ERRCODE_UNDEFINED_OBJECT),
150  errmsg("invalid large-object descriptor: %d", fd)));
151  lobj = cookies[fd];
152 
153  /*
154  * Check state. inv_read() would throw an error anyway, but we want the
155  * error to be about the FD's state not the underlying privilege; it might
156  * be that the privilege exists but user forgot to ask for read mode.
157  */
158  if ((lobj->flags & IFS_RDLOCK) == 0)
159  ereport(ERROR,
160  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
161  errmsg("large object descriptor %d was not opened for reading",
162  fd)));
163 
164  status = inv_read(lobj, buf, len);
165 
166  return status;
167 }
#define IFS_RDLOCK
Definition: large_object.h:48
int errcode(int sqlerrcode)
Definition: elog.c:608
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:67
#define ereport(elevel, rest)
Definition: elog.h:141
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:822
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226
int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
Definition: inv_api.c:494

◆ lo_truncate_internal()

static void lo_truncate_internal ( int32  fd,
int64  len 
)
static

Definition at line 546 of file be-fsstubs.c.

References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), LargeObjectDesc::flags, IFS_WRLOCK, and inv_truncate().

Referenced by be_lo_truncate(), and be_lo_truncate64().

547 {
548  LargeObjectDesc *lobj;
549 
550  if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
551  ereport(ERROR,
552  (errcode(ERRCODE_UNDEFINED_OBJECT),
553  errmsg("invalid large-object descriptor: %d", fd)));
554  lobj = cookies[fd];
555 
556  /* see comment in lo_read() */
557  if ((lobj->flags & IFS_WRLOCK) == 0)
558  ereport(ERROR,
559  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
560  errmsg("large object descriptor %d was not opened for writing",
561  fd)));
562 
563  inv_truncate(lobj, len);
564 }
void inv_truncate(LargeObjectDesc *obj_desc, int64 len)
Definition: inv_api.c:784
int errcode(int sqlerrcode)
Definition: elog.c:608
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define IFS_WRLOCK
Definition: large_object.h:49
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:822
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

◆ lo_write()

int lo_write ( int  fd,
const char *  buf,
int  len 
)

Definition at line 170 of file be-fsstubs.c.

References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), LargeObjectDesc::flags, IFS_WRLOCK, inv_write(), and status().

Referenced by be_lowrite(), dump_lo_buf(), importFile(), and overwrite().

171 {
172  int status;
173  LargeObjectDesc *lobj;
174 
175  if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
176  ereport(ERROR,
177  (errcode(ERRCODE_UNDEFINED_OBJECT),
178  errmsg("invalid large-object descriptor: %d", fd)));
179  lobj = cookies[fd];
180 
181  /* see comment in lo_read() */
182  if ((lobj->flags & IFS_WRLOCK) == 0)
183  ereport(ERROR,
184  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
185  errmsg("large object descriptor %d was not opened for writing",
186  fd)));
187 
188  status = inv_write(lobj, buf, len);
189 
190  return status;
191 }
int errcode(int sqlerrcode)
Definition: elog.c:608
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define IFS_WRLOCK
Definition: large_object.h:49
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:67
#define ereport(elevel, rest)
Definition: elog.h:141
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:822
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226
int inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
Definition: inv_api.c:587

◆ newLOfd()

static int newLOfd ( LargeObjectDesc lobjCookie)
static

Definition at line 666 of file be-fsstubs.c.

References Assert, cookies_size, i, MemoryContextAllocZero(), MemSet, and repalloc().

Referenced by be_lo_open().

667 {
668  int i,
669  newsize;
670 
671  /* Try to find a free slot */
672  for (i = 0; i < cookies_size; i++)
673  {
674  if (cookies[i] == NULL)
675  {
676  cookies[i] = lobjCookie;
677  return i;
678  }
679  }
680 
681  /* No free slot, so make the array bigger */
682  if (cookies_size <= 0)
683  {
684  /* First time through, arbitrarily make 64-element array */
685  i = 0;
686  newsize = 64;
687  cookies = (LargeObjectDesc **)
688  MemoryContextAllocZero(fscxt, newsize * sizeof(LargeObjectDesc *));
689  cookies_size = newsize;
690  }
691  else
692  {
693  /* Double size of array */
694  i = cookies_size;
695  newsize = cookies_size * 2;
696  cookies = (LargeObjectDesc **)
697  repalloc(cookies, newsize * sizeof(LargeObjectDesc *));
698  MemSet(cookies + cookies_size, 0,
699  (newsize - cookies_size) * sizeof(LargeObjectDesc *));
700  cookies_size = newsize;
701  }
702 
703  Assert(cookies[i] == NULL);
704  cookies[i] = lobjCookie;
705  return i;
706 }
#define MemSet(start, val, len)
Definition: c.h:962
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:839
#define Assert(condition)
Definition: c.h:739
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
static int cookies_size
Definition: be-fsstubs.c:68
static MemoryContext fscxt
Definition: be-fsstubs.c:70
int i
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

Variable Documentation

◆ cookies

LargeObjectDesc** cookies = NULL
static

Definition at line 67 of file be-fsstubs.c.

◆ cookies_size

◆ fscxt

MemoryContext fscxt = NULL
static

Definition at line 70 of file be-fsstubs.c.