xref: /onnv-gate/usr/src/lib/libast/common/sfio/sfsync.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #include	"sfhdr.h"
234887Schin 
244887Schin /*	Synchronize data in buffers with the file system.
254887Schin **	If f is nil, all streams are sync-ed
264887Schin **
274887Schin **	Written by Kiem-Phong Vo.
284887Schin */
294887Schin 
304887Schin #if __STD_C
_sfall(void)314887Schin static int _sfall(void)
324887Schin #else
334887Schin static int _sfall()
344887Schin #endif
354887Schin {
364887Schin 	reg Sfpool_t	*p, *next;
374887Schin 	reg Sfio_t*	f;
384887Schin 	reg int		n, rv;
394887Schin 	reg int		nsync, count, loop;
404887Schin #define MAXLOOP 3
414887Schin 
424887Schin 	for(loop = 0; loop < MAXLOOP; ++loop)
434887Schin 	{	rv = nsync = count = 0;
444887Schin 		for(p = &_Sfpool; p; p = next)
454887Schin 		{	/* find the next legitimate pool */
464887Schin 			for(next = p->next; next; next = next->next)
474887Schin 				if(next->n_sf > 0)
484887Schin 					break;
494887Schin 
504887Schin 			/* walk the streams for _Sfpool only */
514887Schin 			for(n = 0; n < ((p == &_Sfpool) ? p->n_sf : 1); ++n)
524887Schin 			{	count += 1;
534887Schin 				f = p->sf[n];
544887Schin 
554887Schin 				if(f->flags&SF_STRING )
564887Schin 					goto did_sync;
574887Schin 				if(SFFROZEN(f))
584887Schin 					continue;
594887Schin 				if((f->mode&SF_READ) && (f->mode&SF_SYNCED) )
604887Schin 					goto did_sync;
614887Schin 				if((f->mode&SF_READ) && !(f->bits&SF_MMAP) &&
624887Schin 				   f->next == f->endb)
634887Schin 					goto did_sync;
644887Schin 				if((f->mode&SF_WRITE) && !(f->bits&SF_HOLE) &&
654887Schin 				   f->next == f->data)
664887Schin 					goto did_sync;
674887Schin 
684887Schin 				if(sfsync(f) < 0)
694887Schin 					rv = -1;
704887Schin 
714887Schin 			did_sync:
724887Schin 				nsync += 1;
734887Schin 			}
744887Schin 		}
754887Schin 
764887Schin 		if(nsync == count)
774887Schin 			break;
784887Schin 	}
794887Schin 	return rv;
804887Schin }
814887Schin 
824887Schin #if __STD_C
sfsync(reg Sfio_t * f)834887Schin int sfsync(reg Sfio_t* f)
844887Schin #else
854887Schin int sfsync(f)
864887Schin reg Sfio_t*	f;	/* stream to be synchronized */
874887Schin #endif
884887Schin {
894887Schin 	int	local, rv, mode, lock;
904887Schin 	Sfio_t*	origf;
918462SApril.Chin@Sun.COM 	SFMTXDECL(f);
924887Schin 
934887Schin 	if(!(origf = f) )
944887Schin 		return _sfall();
954887Schin 
968462SApril.Chin@Sun.COM 	SFMTXENTER(origf,-1);
974887Schin 
984887Schin 	GETLOCAL(origf,local);
994887Schin 
1004887Schin 	if(origf->disc == _Sfudisc)	/* throw away ungetc */
1014887Schin 		(void)sfclose((*_Sfstack)(origf,NIL(Sfio_t*)));
1024887Schin 
1034887Schin 	rv = 0;
1044887Schin 
1054887Schin 	lock = origf->mode&SF_LOCK;
1064887Schin 	if(origf->mode == (SF_SYNCED|SF_READ) ) /* already synced */
1074887Schin 		goto done;
1084887Schin 
1094887Schin 	if((origf->mode&SF_RDWR) != SFMODE(origf,local) && _sfmode(origf,0,local) < 0)
1104887Schin 	{	rv = -1;
1114887Schin 		goto done;
1124887Schin 	}
1134887Schin 
1144887Schin 	for(; f; f = f->push)
1154887Schin 	{
1164887Schin 		if((f->flags&SF_IOCHECK) && f->disc && f->disc->exceptf)
1174887Schin 			(void)(*f->disc->exceptf)(f,SF_SYNC,(Void_t*)((int)1),f->disc);
1184887Schin 
1194887Schin 		SFLOCK(f,local);
1204887Schin 
1214887Schin 		/* pretend that this stream is not on a stack */
1224887Schin 		mode = f->mode&SF_PUSH;
1234887Schin 		f->mode &= ~SF_PUSH;
1244887Schin 
1254887Schin 		/* these streams do not need synchronization */
1264887Schin 		if((f->flags&SF_STRING) || (f->mode&SF_SYNCED))
1274887Schin 			goto next;
1284887Schin 
1294887Schin 		if((f->mode&SF_WRITE) && (f->next > f->data || (f->bits&SF_HOLE)) )
1304887Schin 		{	/* sync the buffer, make sure pool don't move */
1314887Schin 			reg int pool = f->mode&SF_POOL;
1324887Schin 			f->mode &= ~SF_POOL;
1334887Schin 			if(f->next > f->data && (SFWRALL(f), SFFLSBUF(f,-1)) < 0)
1344887Schin 				rv = -1;
1354887Schin 			if(!SFISNULL(f) && (f->bits&SF_HOLE) )
1364887Schin 			{	/* realize a previously created hole of 0's */
1374887Schin 				if(SFSK(f,(Sfoff_t)(-1),SEEK_CUR,f->disc) >= 0)
1384887Schin 					(void)SFWR(f,"",1,f->disc);
1394887Schin 				f->bits &= ~SF_HOLE;
1404887Schin 			}
1414887Schin 			f->mode |= pool;
1424887Schin 		}
1434887Schin 
1444887Schin 		if((f->mode&SF_READ) && f->extent >= 0 &&
1454887Schin 		   ((f->bits&SF_MMAP) || f->next < f->endb) )
1464887Schin 		{	/* make sure the file pointer is at the right place */
1474887Schin 			f->here -= (f->endb-f->next);
1484887Schin 			f->endr = f->endw = f->data;
1494887Schin 			f->mode = SF_READ|SF_SYNCED|lock;
1504887Schin 			(void)SFSK(f,f->here,SEEK_SET,f->disc);
1514887Schin 
1524887Schin 			if((f->flags&SF_SHARE) && !(f->flags&SF_PUBLIC) &&
1534887Schin 			   !(f->bits&SF_MMAP) )
1544887Schin 			{	f->endb = f->next = f->data;
1554887Schin 				f->mode &= ~SF_SYNCED;
1564887Schin 			}
1574887Schin 		}
1584887Schin 
1594887Schin 	next:
1604887Schin 		f->mode |= mode;
1614887Schin 		SFOPEN(f,local);
1624887Schin 
1634887Schin 		if((f->flags&SF_IOCHECK) && f->disc && f->disc->exceptf)
1644887Schin 			(void)(*f->disc->exceptf)(f,SF_SYNC,(Void_t*)((int)0),f->disc);
1654887Schin 	}
1664887Schin 
1674887Schin done:
1684887Schin 	if(!local && f && (f->mode&SF_POOL) && f->pool && f != f->pool->sf[0])
1694887Schin 		SFSYNC(f->pool->sf[0]);
1704887Schin 
1714887Schin 	SFMTXRETURN(origf, rv);
1724887Schin }
173