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 ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:170
MemoryContext TopMemoryContext
Definition: mcxt.c:43
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:342
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 624 of file be-fsstubs.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

626 {
627  int i;
628 
629  if (fscxt == NULL) /* no LO operations in this xact */
630  return;
631 
632  for (i = 0; i < cookies_size; i++)
633  {
634  LargeObjectDesc *lo = cookies[i];
635 
636  if (lo != NULL && lo->subid == mySubid)
637  {
638  if (isCommit)
639  lo->subid = parentSubid;
640  else
641  {
642  /*
643  * Make sure we do not call inv_close twice if it errors out
644  * for some reason. Better a leak than a crash.
645  */
646  deleteLOfd(i);
647  inv_close(lo);
648  }
649  }
650  }
651 }
static void deleteLOfd(int fd)
Definition: be-fsstubs.c:701
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 583 of file be-fsstubs.c.

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

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

584 {
585  int i;
586 
587  if (fscxt == NULL)
588  return; /* no LO operations in this xact */
589 
590  /*
591  * Close LO fds and clear cookies array so that LO fds are no longer good.
592  * On abort we skip the close step.
593  */
594  for (i = 0; i < cookies_size; i++)
595  {
596  if (cookies[i] != NULL)
597  {
598  if (isCommit)
599  inv_close(cookies[i]);
600  deleteLOfd(i);
601  }
602  }
603 
604  /* Needn't actually pfree since we're about to zap context */
605  cookies = NULL;
606  cookies_size = 0;
607 
608  /* Release the LO memory context to prevent permanent memory leaks. */
610  fscxt = NULL;
611 
612  /* Give inv_api.c a chance to clean up, too */
613  close_lo_relation(isCommit);
614 }
static void deleteLOfd(int fd)
Definition: be-fsstubs.c:701
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
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 #if 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:701
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:575
#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:284
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
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:320

◆ 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:240
#define PG_RETURN_OID(x)
Definition: fmgr.h:320

◆ be_lo_export()

Datum be_lo_export ( PG_FUNCTION_ARGS  )

Definition at line 468 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_CATCH, PG_END_TRY, PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_RE_THROW, PG_RETURN_INT32, PG_TRY, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, text_to_cstring_buffer(), and write.

469 {
470  Oid lobjId = PG_GETARG_OID(0);
472  int fd;
473  int nbytes,
474  tmp;
475  char buf[BUFSIZE];
476  char fnamebuf[MAXPGPATH];
477  LargeObjectDesc *lobj;
478  mode_t oumask;
479 
480  CreateFSContext();
481 
482  /*
483  * open the inversion object (no need to test for failure)
484  */
485  lobj = inv_open(lobjId, INV_READ, fscxt);
486 
487  /*
488  * open the file to be written to
489  *
490  * Note: we reduce backend's normal 077 umask to the slightly friendlier
491  * 022. This code used to drop it all the way to 0, but creating
492  * world-writable export files doesn't seem wise.
493  */
494  text_to_cstring_buffer(filename, fnamebuf, sizeof(fnamebuf));
495  oumask = umask(S_IWGRP | S_IWOTH);
496  PG_TRY();
497  {
498  fd = OpenTransientFilePerm(fnamebuf, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY,
500  }
501  PG_CATCH();
502  {
503  umask(oumask);
504  PG_RE_THROW();
505  }
506  PG_END_TRY();
507  umask(oumask);
508  if (fd < 0)
509  ereport(ERROR,
511  errmsg("could not create server file \"%s\": %m",
512  fnamebuf)));
513 
514  /*
515  * read in from the inversion file and write to the filesystem
516  */
517  while ((nbytes = inv_read(lobj, buf, BUFSIZE)) > 0)
518  {
519  tmp = write(fd, buf, nbytes);
520  if (tmp != nbytes)
521  ereport(ERROR,
523  errmsg("could not write server file \"%s\": %m",
524  fnamebuf)));
525  }
526 
527  CloseTransientFile(fd);
528  inv_close(lobj);
529 
530  PG_RETURN_INT32(1);
531 }
#define S_IRGRP
Definition: win32_port.h:283
#define BUFSIZE
Definition: be-fsstubs.c:57
#define write(a, b, c)
Definition: win32.h:14
#define S_IWOTH
Definition: win32_port.h:298
int OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:2401
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
#define S_IROTH
Definition: win32_port.h:295
#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:214
#define PG_BINARY
Definition: c.h:1025
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define INV_READ
Definition: libpq-fs.h:22
#define S_IWUSR
Definition: win32_port.h:274
#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:240
int errcode_for_file_access(void)
Definition: elog.c:598
#define S_IWGRP
Definition: win32_port.h:286
#define ereport(elevel, rest)
Definition: elog.h:122
int CloseTransientFile(int fd)
Definition: fd.c:2562
#define PG_CATCH()
Definition: elog.h:293
#define PG_RE_THROW()
Definition: elog.h:314
#define S_IRUSR
Definition: win32_port.h:271
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:797
static MemoryContext fscxt
Definition: be-fsstubs.c:70
Definition: c.h:487
#define PG_TRY()
Definition: elog.h:284
int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
Definition: inv_api.c:494
#define PG_END_TRY()
Definition: elog.h:300

◆ be_lo_from_bytea()

Datum be_lo_from_bytea ( PG_FUNCTION_ARGS  )

Definition at line 805 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.

806 {
807  Oid loOid = PG_GETARG_OID(0);
809  LargeObjectDesc *loDesc;
810  int written PG_USED_FOR_ASSERTS_ONLY;
811 
812  CreateFSContext();
813 
814  loOid = inv_create(loOid);
815  loDesc = inv_open(loOid, INV_WRITE, fscxt);
816  written = inv_write(loDesc, VARDATA_ANY(str), VARSIZE_ANY_EXHDR(str));
817  Assert(written == VARSIZE_ANY_EXHDR(str));
818  inv_close(loDesc);
819 
820  PG_RETURN_OID(loOid);
821 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
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:240
#define Assert(condition)
Definition: c.h:670
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#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:340
static MemoryContext fscxt
Definition: be-fsstubs.c:70
Definition: c.h:487
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:122
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
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 770 of file be-fsstubs.c.

References lo_get_fragment_internal(), PG_GETARG_OID, and PG_RETURN_BYTEA_P.

771 {
772  Oid loOid = PG_GETARG_OID(0);
773  bytea *result;
774 
775  result = lo_get_fragment_internal(loOid, 0, -1);
776 
777  PG_RETURN_BYTEA_P(result);
778 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
unsigned int Oid
Definition: postgres_ext.h:31
static bytea * lo_get_fragment_internal(Oid loOid, int64 offset, int32 nbytes)
Definition: be-fsstubs.c:714
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
Definition: c.h:487

◆ be_lo_get_fragment()

Datum be_lo_get_fragment ( PG_FUNCTION_ARGS  )

Definition at line 784 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.

785 {
786  Oid loOid = PG_GETARG_OID(0);
787  int64 offset = PG_GETARG_INT64(1);
788  int32 nbytes = PG_GETARG_INT32(2);
789  bytea *result;
790 
791  if (nbytes < 0)
792  ereport(ERROR,
793  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
794  errmsg("requested length cannot be negative")));
795 
796  result = lo_get_fragment_internal(loOid, offset, nbytes);
797 
798  PG_RETURN_BYTEA_P(result);
799 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:284
#define ERROR
Definition: elog.h:43
static bytea * lo_get_fragment_internal(Oid loOid, int64 offset, int32 nbytes)
Definition: be-fsstubs.c:714
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:487
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247

◆ 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:273
#define InvalidOid
Definition: postgres_ext.h:36
static char * filename
Definition: pg_dumpall.c:90
Definition: c.h:487
#define PG_RETURN_OID(x)
Definition: fmgr.h:320

◆ 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:273
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
static char * filename
Definition: pg_dumpall.c:90
Definition: c.h:487
#define PG_RETURN_OID(x)
Definition: fmgr.h:320

◆ 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:234
int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence)
Definition: inv_api.c:432
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:575
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:284
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:797
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225

◆ 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:234
int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence)
Definition: inv_api.c:432
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
int errcode(int sqlerrcode)
Definition: elog.c:575
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:284
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:797
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247

◆ 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(), newLOfd(), PG_GETARG_INT32, PG_GETARG_OID, and PG_RETURN_INT32.

92 {
93  Oid lobjId = PG_GETARG_OID(0);
94  int32 mode = PG_GETARG_INT32(1);
95  LargeObjectDesc *lobjDesc;
96  int fd;
97 
98 #if 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 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
#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:284
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt)
Definition: inv_api.c:252
static MemoryContext fscxt
Definition: be-fsstubs.c:70
#define elog
Definition: elog.h:219
static int newLOfd(LargeObjectDesc *lobjCookie)
Definition: be-fsstubs.c:658

◆ be_lo_put()

Datum be_lo_put ( PG_FUNCTION_ARGS  )

Definition at line 827 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.

828 {
829  Oid loOid = PG_GETARG_OID(0);
830  int64 offset = PG_GETARG_INT64(1);
832  LargeObjectDesc *loDesc;
833  int written PG_USED_FOR_ASSERTS_ONLY;
834 
835  CreateFSContext();
836 
837  loDesc = inv_open(loOid, INV_WRITE, fscxt);
838 
839  /* Permission check */
840  if (!lo_compat_privileges &&
842  GetUserId(),
843  ACL_UPDATE,
844  loDesc->snapshot) != ACLCHECK_OK)
845  ereport(ERROR,
846  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
847  errmsg("permission denied for large object %u",
848  loDesc->id)));
849 
850  inv_seek(loDesc, offset, SEEK_SET);
851  written = inv_write(loDesc, VARDATA_ANY(str), VARSIZE_ANY_EXHDR(str));
852  Assert(written == VARSIZE_ANY_EXHDR(str));
853  inv_close(loDesc);
854 
855  PG_RETURN_VOID();
856 }
int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence)
Definition: inv_api.c:432
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
bool lo_compat_privileges
Definition: inv_api.c:57
Oid GetUserId(void)
Definition: miscinit.c:284
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
int errcode(int sqlerrcode)
Definition: elog.c:575
#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:240
#define ereport(elevel, rest)
Definition: elog.h:122
#define ACL_UPDATE
Definition: parsenodes.h:74
#define PG_RETURN_VOID()
Definition: fmgr.h:309
#define Assert(condition)
Definition: c.h:670
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#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:340
int errmsg(const char *fmt,...)
Definition: elog.c:797
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:4528
Definition: c.h:487
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:122
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247
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:234
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:575
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:284
int64 inv_tell(LargeObjectDesc *obj_desc)
Definition: inv_api.c:481
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:797
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:234
#define PG_RETURN_INT64(x)
Definition: fmgr.h:327
int errcode(int sqlerrcode)
Definition: elog.c:575
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:284
int64 inv_tell(LargeObjectDesc *obj_desc)
Definition: inv_api.c:481
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:797
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

◆ be_lo_truncate()

Datum be_lo_truncate ( PG_FUNCTION_ARGS  )

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

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

560 {
561  int32 fd = PG_GETARG_INT32(0);
562  int32 len = PG_GETARG_INT32(1);
563 
564  lo_truncate_internal(fd, len);
565  PG_RETURN_INT32(0);
566 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
static void lo_truncate_internal(int32 fd, int64 len)
Definition: be-fsstubs.c:538
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:284

◆ be_lo_truncate64()

Datum be_lo_truncate64 ( PG_FUNCTION_ARGS  )

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

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

570 {
571  int32 fd = PG_GETARG_INT32(0);
572  int64 len = PG_GETARG_INT64(1);
573 
574  lo_truncate_internal(fd, len);
575  PG_RETURN_INT32(0);
576 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
static void lo_truncate_internal(int32 fd, int64 len)
Definition: be-fsstubs.c:538
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:284
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247

◆ 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:701
bool lo_compat_privileges
Definition: inv_api.c:57
bool pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid)
Definition: aclchk.c:4737
Oid GetUserId(void)
Definition: miscinit.c:284
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:575
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:240
#define ereport(elevel, rest)
Definition: elog.h:122
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:797
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:234
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:493
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:284
int lo_read(int fd, char *buf, int len)
Definition: be-fsstubs.c:142
void * palloc(Size size)
Definition: mcxt.c:848
Definition: c.h:487
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328

◆ 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:234
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:284
int lo_write(int fd, const char *buf, int len)
Definition: be-fsstubs.c:170
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:487

◆ deleteLOfd()

static void deleteLOfd ( int  fd)
static

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

References fd().

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

702 {
703  cookies[fd] = NULL;
704 }
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 714 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().

715 {
716  LargeObjectDesc *loDesc;
717  int64 loSize;
718  int64 result_length;
719  int total_read PG_USED_FOR_ASSERTS_ONLY;
720  bytea *result = NULL;
721 
722  /*
723  * We don't actually need to store into fscxt, but create it anyway to
724  * ensure that AtEOXact_LargeObject knows there is state to clean up
725  */
726  CreateFSContext();
727 
728  loDesc = inv_open(loOid, INV_READ, fscxt);
729 
730  /*
731  * Compute number of bytes we'll actually read, accommodating nbytes == -1
732  * and reads beyond the end of the LO.
733  */
734  loSize = inv_seek(loDesc, 0, SEEK_END);
735  if (loSize > offset)
736  {
737  if (nbytes >= 0 && nbytes <= loSize - offset)
738  result_length = nbytes; /* request is wholly inside LO */
739  else
740  result_length = loSize - offset; /* adjust to end of LO */
741  }
742  else
743  result_length = 0; /* request is wholly outside LO */
744 
745  /*
746  * A result_length calculated from loSize may not fit in a size_t. Check
747  * that the size will satisfy this and subsequently-enforced size limits.
748  */
749  if (result_length > MaxAllocSize - VARHDRSZ)
750  ereport(ERROR,
751  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
752  errmsg("large object read request is too large")));
753 
754  result = (bytea *) palloc(VARHDRSZ + result_length);
755 
756  inv_seek(loDesc, offset, SEEK_SET);
757  total_read = inv_read(loDesc, VARDATA(result), result_length);
758  Assert(total_read == result_length);
759  SET_VARSIZE(result, result_length + VARHDRSZ);
760 
761  inv_close(loDesc);
762 
763  return result;
764 }
int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence)
Definition: inv_api.c:432
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:493
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
int errcode(int sqlerrcode)
Definition: elog.c:575
#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:122
#define MaxAllocSize
Definition: memutils.h:40
#define Assert(condition)
Definition: c.h:670
LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt)
Definition: inv_api.c:252
void * palloc(Size size)
Definition: mcxt.c:848
int errmsg(const char *fmt,...)
Definition: elog.c:797
static MemoryContext fscxt
Definition: be-fsstubs.c:70
Definition: c.h:487
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:122
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  CloseTransientFile(fd);
459 
460  return oid;
461 }
#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:214
#define PG_BINARY
Definition: c.h:1025
#define ERROR
Definition: elog.h:43
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2392
#define MAXPGPATH
static char * buf
Definition: pg_test_fsync.c:67
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
int CloseTransientFile(int fd)
Definition: fd.c:2562
#define Assert(condition)
Definition: c.h:670
#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:797
static MemoryContext fscxt
Definition: be-fsstubs.c:70
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:122
#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:575
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:122
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:797
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
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 538 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().

539 {
540  LargeObjectDesc *lobj;
541 
542  if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
543  ereport(ERROR,
544  (errcode(ERRCODE_UNDEFINED_OBJECT),
545  errmsg("invalid large-object descriptor: %d", fd)));
546  lobj = cookies[fd];
547 
548  /* see comment in lo_read() */
549  if ((lobj->flags & IFS_WRLOCK) == 0)
550  ereport(ERROR,
551  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
552  errmsg("large object descriptor %d was not opened for writing",
553  fd)));
554 
555  inv_truncate(lobj, len);
556 }
void inv_truncate(LargeObjectDesc *obj_desc, int64 len)
Definition: inv_api.c:784
int errcode(int sqlerrcode)
Definition: elog.c:575
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:122
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:797
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:575
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:122
static int cookies_size
Definition: be-fsstubs.c:68
int errmsg(const char *fmt,...)
Definition: elog.c:797
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
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 658 of file be-fsstubs.c.

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

Referenced by be_lo_open().

659 {
660  int i,
661  newsize;
662 
663  /* Try to find a free slot */
664  for (i = 0; i < cookies_size; i++)
665  {
666  if (cookies[i] == NULL)
667  {
668  cookies[i] = lobjCookie;
669  return i;
670  }
671  }
672 
673  /* No free slot, so make the array bigger */
674  if (cookies_size <= 0)
675  {
676  /* First time through, arbitrarily make 64-element array */
677  i = 0;
678  newsize = 64;
679  cookies = (LargeObjectDesc **)
680  MemoryContextAllocZero(fscxt, newsize * sizeof(LargeObjectDesc *));
681  cookies_size = newsize;
682  }
683  else
684  {
685  /* Double size of array */
686  i = cookies_size;
687  newsize = cookies_size * 2;
688  cookies = (LargeObjectDesc **)
689  repalloc(cookies, newsize * sizeof(LargeObjectDesc *));
690  MemSet(cookies + cookies_size, 0,
691  (newsize - cookies_size) * sizeof(LargeObjectDesc *));
692  cookies_size = newsize;
693  }
694 
695  Assert(cookies[i] == NULL);
696  cookies[i] = lobjCookie;
697  return i;
698 }
#define MemSet(start, val, len)
Definition: c.h:853
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:741
#define Assert(condition)
Definition: c.h:670
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:962
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.