1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-07 19:06:32 +03:00

Remove unnecessary overhead in backend's large-object operations.

Do read/write permissions checks at most once per large object descriptor,
not once per lo_read or lo_write call as before.  The repeated tests were
quite useless in the read case since the snapshot-based tests were
guaranteed to produce the same answer every time.  In the write case,
the extra tests could in principle detect revocation of write privileges
after a series of writes has started --- but there's a race condition there
anyway, since we'd check privileges before performing and certainly before
committing the write.  So there's no real advantage to checking every
single time, and we might as well redefine it as "only check the first
time".

On the same reasoning, remove the LargeObjectExists checks in inv_write
and inv_truncate.  We already checked existence when the descriptor was
opened, and checking again doesn't provide any real increment of safety
that would justify the cost.
This commit is contained in:
Tom Lane
2012-10-09 16:38:00 -04:00
parent 2d8c81ac86
commit 7e0cce0265
3 changed files with 92 additions and 93 deletions

View File

@@ -420,8 +420,8 @@ inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence)
if (newoffset < 0 || newoffset > MAX_LARGE_OBJECT_SIZE)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg_internal("invalid large object seek target: " INT64_FORMAT,
newoffset)));
errmsg_internal("invalid large object seek target: " INT64_FORMAT,
newoffset)));
obj_desc->offset = newoffset;
return newoffset;
@@ -562,18 +562,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
Assert(buf != NULL);
/* enforce writability because snapshot is probably wrong otherwise */
if ((obj_desc->flags & IFS_WRLOCK) == 0)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("large object %u was not opened for writing",
obj_desc->id)));
/* check existence of the target largeobject */
if (!LargeObjectExists(obj_desc->id))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("large object %u was already dropped",
obj_desc->id)));
Assert(obj_desc->flags & IFS_WRLOCK);
if (nbytes <= 0)
return 0;
@@ -767,18 +756,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
Assert(PointerIsValid(obj_desc));
/* enforce writability because snapshot is probably wrong otherwise */
if ((obj_desc->flags & IFS_WRLOCK) == 0)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("large object %u was not opened for writing",
obj_desc->id)));
/* check existence of the target largeobject */
if (!LargeObjectExists(obj_desc->id))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("large object %u was already dropped",
obj_desc->id)));
Assert(obj_desc->flags & IFS_WRLOCK);
/*
* use errmsg_internal here because we don't want to expose INT64_FORMAT