diff -crwbN pgsql.orig/src/backend/catalog/catalog.c pgsql.lo.old/src/backend/catalog/catalog.c
*** pgsql.orig/src/backend/catalog/catalog.c	Mon Jun 12 18:42:07 2000
--- pgsql.lo.old/src/backend/catalog/catalog.c	Mon Jun 12 18:34:24 2000
***************
*** 22,27 ****
--- 22,89 ----
  #include "miscadmin.h"
  #include "utils/syscache.h"
  
+ #define __JOIN3(a,b,c) a##b##c
+ #define __QUOTE(a) #a
+ #define __QUOTE2(a) __QUOTE(a)
+ #define LO_HASH_POWER_Q __QUOTE2(LO_HASH_POWER)
+ #define LO_HASH_SPRINTF_MASK __JOIN3("%0", LO_HASH_POWER_Q, "d%c")
+ 
+ static char *get_inv_path(const char *relname, const char *dbpath, Oid relid) {
+ 	char	*path;
+ 	Oid	oid;
+ 	size_t	bufsize;
+ 	int	pw	= 0;
+ 	size_t	dblen	= 0;
+ 	Oid s_oid;
+ 
+ 	if (strncmp(relname, "xin", 3) != 0)
+ 		return NULL;
+ 	if (strlen(relname) < 5)
+ 		return NULL;
+ 	if ((relname[3] != 'v') && (relname[3] != 'x'))
+ 		return NULL;
+ 	/* LO's are resided in Database dir */
+ 
+ 	if (dbpath == NULL) {
+ 		char *err;
+ 		oid = strtol(relname + 4, &err, 10);
+ 		if (*err != '\0')
+ 			return NULL;
+ 	} else
+ 		oid = relid;
+ 
+ 	s_oid = oid;
+ 	while (s_oid != 0) {
+ 		pw++;
+ 		s_oid /= LO_HASH_SIZE;
+ 	}
+ 	s_oid = oid / LO_HASH_SIZE;
+ 	if (dbpath != NULL) {
+ 		dblen = strlen(dbpath);
+ 		bufsize = dblen + strlen(relname) + pw * (LO_HASH_POWER + 1) + 5;
+ 	} else
+ 		bufsize = strlen(relname) + pw * (LO_HASH_POWER + 1) + 4;
+ 	path = (char *) palloc(sizeof(char) * bufsize);
+ 	if (dbpath != NULL) {
+ 		snprintf(path, dblen + 4, "%s%c%c%c", dbpath, SEP_CHAR, relname[3], SEP_CHAR);
+ 		pw = dblen + 3;
+ 	} else {
+ 		path[0] = relname[3];
+ 		path[1] = SEP_CHAR;
+ 		path[2] = 0;
+ 		pw = 2;
+ 	}
+ 	while (s_oid != 0) {
+ 		snprintf(path + pw, LO_HASH_POWER + 2, LO_HASH_SPRINTF_MASK,
+ 		  s_oid % LO_HASH_SIZE, SEP_CHAR);
+ 		pw += (LO_HASH_POWER + 1);
+ 		s_oid /= LO_HASH_SIZE;
+ 	}
+ 	snprintf(path + pw, bufsize - pw, "%s", relname);
+ fprintf(stderr, "path = '%s'\n", path);
+ 	return path;
+ }
+ 
  /*
   * relpath				- construct path to a relation's file
   *
***************
*** 45,50 ****
--- 107,114 ----
  		return path;
  	}
  
+ 	if ((path = get_inv_path(relname, NULL, 0)) != NULL)
+ 		return path;
  	/*
  	 * If it is in the current database, assume it is in current working
  	 * directory.  NB: this does not work during bootstrap!
***************
*** 77,82 ****
--- 141,148 ----
  	}
  	else if (dbid == MyDatabaseId)
  	{
+ 		if ((path = get_inv_path(relname, DatabasePath, relid)) != NULL)
+ 			return path;
  		/* XXX why is this inconsistent with relpath() ? */
  		path = (char *) palloc(strlen(DatabasePath) + sizeof(NameData) + 2);
  		sprintf(path, "%s%c%s", DatabasePath, SEP_CHAR, relname);
***************
*** 97,102 ****
--- 163,170 ----
  		if (dbpath == NULL)
  			elog(FATAL, "relpath_blind: can't expand path for db %s",
  				 dbname);
+ 		if ((path = get_inv_path(relname, dbpath, relid)) != NULL)
+ 			return path;
  		path = (char *) palloc(strlen(dbpath) + sizeof(NameData) + 2);
  		sprintf(path, "%s%c%s", dbpath, SEP_CHAR, relname);
  		pfree(dbpath);
diff -crwbN pgsql.orig/src/backend/storage/large_object/inv_api.c pgsql.lo.old/src/backend/storage/large_object/inv_api.c
*** pgsql.orig/src/backend/storage/large_object/inv_api.c	Mon Jun 12 18:42:55 2000
--- pgsql.lo.old/src/backend/storage/large_object/inv_api.c	Mon Jun 12 18:34:37 2000
***************
*** 34,39 ****
--- 34,41 ----
  #include "utils/fmgroids.h"
  #include "utils/relcache.h"
  
+ #include <errno.h>
+ 
  /*
   *	Warning, Will Robinson...  In order to pack data into an inversion
   *	file as densely as possible, we violate the class abstraction here.
***************
*** 65,70 ****
--- 67,78 ----
  #define IMAXBLK			8092
  #define IMINBLK			512
  
+ #define __JOIN3(a,b,c) a##b##c
+ #define __QUOTE(a) #a
+ #define __QUOTE2(a) __QUOTE(a)
+ #define LO_HASH_POWER_Q __QUOTE2(LO_HASH_POWER)
+ #define LO_HASH_SPRINTF_MASK __JOIN3("%c%0", LO_HASH_POWER_Q, "d")
+ 
  /* non-export function prototypes */
  static HeapTuple inv_newtuple(LargeObjectDesc *obj_desc, Buffer buffer,
  			 Page page, char *dbuf, int nwrite);
***************
*** 96,101 ****
--- 104,112 ----
  	Oid		classObjectId[1];
  	char		objname[NAMEDATALEN];
  	char		indname[NAMEDATALEN];
+ 	Oid		s_oid;
+ 	int		pw	= 0;
+ 	size_t		dirsize;
  
  	/*
  	 * add one here since the pg_class tuple created will have the next
***************
*** 132,137 ****
--- 143,187 ----
  					   BYTEAOID,
  					   -1, 0, false);
  
+ 	s_oid = file_oid;
+ 	while (s_oid != 0) {
+ 	        pw++;
+ 		s_oid /= LO_HASH_SIZE;
+ 	}
+ 	dirsize = pw * (LO_HASH_POWER + 1) + 2;
+ 	
+ 	{
+ 		char		dirname[dirsize];
+ 		struct stat	st;
+ 		
+ 		dirname[1] = 0;
+ 		pw = 1;
+ 		s_oid = file_oid;
+ 		for(; ; ) {
+ 			dirname[0] = 'v';
+ 			if (stat(dirname, &st) == -1) {
+ 				if (errno == ENOENT) {
+ 					if (mkdir(dirname, S_IRWXU) != 0)
+ 				                elog(ERROR, "lo_create: unable to create large object directory '%s': %s", dirname, strerror(errno));
+ 				} else
+ 				        elog(ERROR, "lo_create: unable to stat large object directory '%s': %s", dirname, strerror(errno));
+ 			}
+ 			dirname[0] = 'x';
+ 			if (stat(dirname, &st) == -1) {
+ 				if (errno == ENOENT) {
+ 					if (mkdir(dirname, S_IRWXU) != 0)
+ 				                elog(ERROR, "lo_create: unable to create large object directory '%s': %s", dirname, strerror(errno));
+ 				} else
+ 				        elog(ERROR, "lo_create: unable to stat large object directory '%s': %s", dirname, strerror(errno));
+ 			}
+ 			s_oid /= LO_HASH_SIZE;
+ 			if (s_oid == 0)
+ 				break;
+ 			snprintf(dirname + pw, LO_HASH_POWER + 2,
+ 			  LO_HASH_SPRINTF_MASK, SEP_CHAR, s_oid % LO_HASH_SIZE);
+ 			pw += (LO_HASH_POWER + 1);
+ 		}
+ 	}
  	/*
  	 * First create the table to hold the inversion large object.  It will
  	 * be located on whatever storage manager the user requested.
