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 634 of file be-fsstubs.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

636 {
637  int i;
638 
639  if (fscxt == NULL) /* no LO operations in this xact */
640  return;
641 
642  for (i = 0; i < cookies_size; i++)
643  {
644  LargeObjectDesc *lo = cookies[i];
645 
646  if (lo != NULL && lo->subid == mySubid)
647  {
648  if (isCommit)
649  lo->subid = parentSubid;
650  else
651  {
652  /*
653  * Make sure we do not call inv_close twice if it errors out
654  * for some reason. Better a leak than a crash.
655  */
656  deleteLOfd(i);
657  inv_close(lo);
658  }
659  }
660  }
661 }
static void deleteLOfd(int fd)
Definition: be-fsstubs.c:711
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 593 of file be-fsstubs.c.

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

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

594 {
595  int i;
596 
597  if (fscxt == NULL)
598  return; /* no LO operations in this xact */
599 
600  /*
601  * Close LO fds and clear cookies array so that LO fds are no longer good.
602  * On abort we skip the close step.
603  */
604  for (i = 0; i < cookies_size; i++)
605  {
606  if (cookies[i] != NULL)
607  {
608  if (isCommit)
609  inv_close(cookies[i]);
610  deleteLOfd(i);
611  }
612  }
613 
614  /* Needn't actually pfree since we're about to zap context */
615  cookies = NULL;
616  cookies_size = 0;
617 
618  /* Release the LO memory context to prevent permanent memory leaks. */
620  fscxt = NULL;
621 
622  /* Give inv_api.c a chance to clean up, too */
623  close_lo_relation(isCommit);
624 }
static void deleteLOfd(int fd)
Definition: be-fsstubs.c:711
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 #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:711
#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:570
#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:346
#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:784
#define elog(elevel,...)
Definition: elog.h:226
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_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.

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_CATCH();
507  {
508  umask(oumask);
509  PG_RE_THROW();
510  }
511  PG_END_TRY();
512  umask(oumask);
513  if (fd < 0)
514  ereport(ERROR,
516  errmsg("could not create server file \"%s\": %m",
517  fnamebuf)));
518 
519  /*
520  * read in from the inversion file and write to the filesystem
521  */
522  while ((nbytes = inv_read(lobj, buf, BUFSIZE)) > 0)
523  {
524  tmp = write(fd, buf, nbytes);
525  if (tmp != nbytes)
526  ereport(ERROR,
528  errmsg("could not write server file \"%s\": %m",
529  fnamebuf)));
530  }
531 
532  if (CloseTransientFile(fd) != 0)
533  ereport(ERROR,
535  errmsg("could not close file \"%s\": %m",
536  fnamebuf)));
537 
538  inv_close(lobj);
539 
540  PG_RETURN_INT32(1);
541 }
#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:2264
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:1191
#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:68
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
int errcode_for_file_access(void)
Definition: elog.c:593
#define S_IWGRP
Definition: win32_port.h:275
#define ereport(elevel, rest)
Definition: elog.h:141
int CloseTransientFile(int fd)
Definition: fd.c:2432
#define PG_CATCH()
Definition: elog.h:310
#define PG_RE_THROW()
Definition: elog.h:331
#define S_IRUSR
Definition: win32_port.h:260
static char * filename
Definition: pg_dumpall.c:91
LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt)
Definition: inv_api.c:252
int errmsg(const char *fmt,...)
Definition: elog.c:784
static MemoryContext fscxt
Definition: be-fsstubs.c:70
Definition: c.h:549
#define PG_TRY()
Definition: elog.h:301
int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
Definition: inv_api.c:494
#define PG_END_TRY()
Definition: elog.h:317

◆ be_lo_from_bytea()

Datum be_lo_from_bytea ( PG_FUNCTION_ARGS  )

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

816 {
817  Oid loOid = PG_GETARG_OID(0);
819  LargeObjectDesc *loDesc;
820  int written PG_USED_FOR_ASSERTS_ONLY;
821 
822  CreateFSContext();
823 
824  loOid = inv_create(loOid);
825  loDesc = inv_open(loOid, INV_WRITE, fscxt);
826  written = inv_write(loDesc, VARDATA_ANY(str), VARSIZE_ANY_EXHDR(str));
827  Assert(written == VARSIZE_ANY_EXHDR(str));
828  inv_close(loDesc);
829 
830  PG_RETURN_OID(loOid);
831 }
#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:732
#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:549
#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 780 of file be-fsstubs.c.

References lo_get_fragment_internal(), PG_GETARG_OID, and PG_RETURN_BYTEA_P.

781 {
782  Oid loOid = PG_GETARG_OID(0);
783  bytea *result;
784 
785  result = lo_get_fragment_internal(loOid, 0, -1);
786 
787  PG_RETURN_BYTEA_P(result);
788 }
#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:724
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
Definition: c.h:549

◆ be_lo_get_fragment()

Datum be_lo_get_fragment ( PG_FUNCTION_ARGS  )

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

795 {
796  Oid loOid = PG_GETARG_OID(0);
797  int64 offset = PG_GETARG_INT64(1);
798  int32 nbytes = PG_GETARG_INT32(2);
799  bytea *result;
800 
801  if (nbytes < 0)
802  ereport(ERROR,
803  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
804  errmsg("requested length cannot be negative")));
805 
806  result = lo_get_fragment_internal(loOid, offset, nbytes);
807 
808  PG_RETURN_BYTEA_P(result);
809 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
int errcode(int sqlerrcode)
Definition: elog.c:570
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:346
#define ERROR
Definition: elog.h:43
static bytea * lo_get_fragment_internal(Oid loOid, int64 offset, int32 nbytes)
Definition: be-fsstubs.c:724
#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:784
Definition: c.h:549
#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:91
Definition: c.h:549
#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:91
Definition: c.h:549
#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:570
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:346
#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:784
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227

◆ 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:570
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:346
#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:784
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227
#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 #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 }
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:346
#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:226
static int newLOfd(LargeObjectDesc *lobjCookie)
Definition: be-fsstubs.c:668

◆ be_lo_put()

Datum be_lo_put ( PG_FUNCTION_ARGS  )

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

838 {
839  Oid loOid = PG_GETARG_OID(0);
840  int64 offset = PG_GETARG_INT64(1);
842  LargeObjectDesc *loDesc;
843  int written PG_USED_FOR_ASSERTS_ONLY;
844 
845  CreateFSContext();
846 
847  loDesc = inv_open(loOid, INV_WRITE, fscxt);
848 
849  /* Permission check */
850  if (!lo_compat_privileges &&
852  GetUserId(),
853  ACL_UPDATE,
854  loDesc->snapshot) != ACLCHECK_OK)
855  ereport(ERROR,
856  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
857  errmsg("permission denied for large object %u",
858  loDesc->id)));
859 
860  inv_seek(loDesc, offset, SEEK_SET);
861  written = inv_write(loDesc, VARDATA_ANY(str), VARSIZE_ANY_EXHDR(str));
862  Assert(written == VARSIZE_ANY_EXHDR(str));
863  inv_close(loDesc);
864 
865  PG_RETURN_VOID();
866 }
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:570
#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:732
#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:784
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:4679
Definition: c.h:549
#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:570
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:346
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:784
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:570
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:346
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:784
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67

◆ be_lo_truncate()

Datum be_lo_truncate ( PG_FUNCTION_ARGS  )

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

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

570 {
571  int32 fd = PG_GETARG_INT32(0);
572  int32 len = PG_GETARG_INT32(1);
573 
574  lo_truncate_internal(fd, len);
575  PG_RETURN_INT32(0);
576 }
#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:548
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:346

◆ be_lo_truncate64()

Datum be_lo_truncate64 ( PG_FUNCTION_ARGS  )

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

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

580 {
581  int32 fd = PG_GETARG_INT32(0);
582  int64 len = PG_GETARG_INT64(1);
583 
584  lo_truncate_internal(fd, len);
585  PG_RETURN_INT32(0);
586 }
#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:548
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:346
#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:711
bool lo_compat_privileges
Definition: inv_api.c:57
bool pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid)
Definition: aclchk.c:4888
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:570
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:784
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:555
#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:346
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:549
#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:346
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:549

◆ deleteLOfd()

static void deleteLOfd ( int  fd)
static

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

References fd().

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

712 {
713  cookies[fd] = NULL;
714 }
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 724 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().

725 {
726  LargeObjectDesc *loDesc;
727  int64 loSize;
728  int64 result_length;
729  int total_read PG_USED_FOR_ASSERTS_ONLY;
730  bytea *result = NULL;
731 
732  /*
733  * We don't actually need to store into fscxt, but create it anyway to
734  * ensure that AtEOXact_LargeObject knows there is state to clean up
735  */
736  CreateFSContext();
737 
738  loDesc = inv_open(loOid, INV_READ, fscxt);
739 
740  /*
741  * Compute number of bytes we'll actually read, accommodating nbytes == -1
742  * and reads beyond the end of the LO.
743  */
744  loSize = inv_seek(loDesc, 0, SEEK_END);
745  if (loSize > offset)
746  {
747  if (nbytes >= 0 && nbytes <= loSize - offset)
748  result_length = nbytes; /* request is wholly inside LO */
749  else
750  result_length = loSize - offset; /* adjust to end of LO */
751  }
752  else
753  result_length = 0; /* request is wholly outside LO */
754 
755  /*
756  * A result_length calculated from loSize may not fit in a size_t. Check
757  * that the size will satisfy this and subsequently-enforced size limits.
758  */
759  if (result_length > MaxAllocSize - VARHDRSZ)
760  ereport(ERROR,
761  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
762  errmsg("large object read request is too large")));
763 
764  result = (bytea *) palloc(VARHDRSZ + result_length);
765 
766  inv_seek(loDesc, offset, SEEK_SET);
767  total_read = inv_read(loDesc, VARDATA(result), result_length);
768  Assert(total_read == result_length);
769  SET_VARSIZE(result, result_length + VARHDRSZ);
770 
771  inv_close(loDesc);
772 
773  return result;
774 }
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:555
void inv_close(LargeObjectDesc *obj_desc)
Definition: inv_api.c:339
int errcode(int sqlerrcode)
Definition: elog.c:570
#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:732
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:784
static MemoryContext fscxt
Definition: be-fsstubs.c:70
Definition: c.h:549
#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:1191
#define ERROR
Definition: elog.h:43
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2255
#define MAXPGPATH
static char * buf
Definition: pg_test_fsync.c:68
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
int CloseTransientFile(int fd)
Definition: fd.c:2432
#define Assert(condition)
Definition: c.h:732
#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:784
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:570
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:68
#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:784
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227
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 548 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().

549 {
550  LargeObjectDesc *lobj;
551 
552  if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
553  ereport(ERROR,
554  (errcode(ERRCODE_UNDEFINED_OBJECT),
555  errmsg("invalid large-object descriptor: %d", fd)));
556  lobj = cookies[fd];
557 
558  /* see comment in lo_read() */
559  if ((lobj->flags & IFS_WRLOCK) == 0)
560  ereport(ERROR,
561  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
562  errmsg("large object descriptor %d was not opened for writing",
563  fd)));
564 
565  inv_truncate(lobj, len);
566 }
void inv_truncate(LargeObjectDesc *obj_desc, int64 len)
Definition: inv_api.c:784
int errcode(int sqlerrcode)
Definition: elog.c:570
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:784
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:570
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:68
#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:784
static LargeObjectDesc ** cookies
Definition: be-fsstubs.c:67
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227
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 668 of file be-fsstubs.c.

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

Referenced by be_lo_open().

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