xref: /minix3/sys/fs/v7fs/v7fs_io_kern.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: v7fs_io_kern.c,v 1.3 2015/03/28 19:24:05 maxv Exp $	*/
29f988b79SJean-Baptiste Boric 
39f988b79SJean-Baptiste Boric /*-
49f988b79SJean-Baptiste Boric  * Copyright (c) 2004, 2011 The NetBSD Foundation, Inc.
59f988b79SJean-Baptiste Boric  * All rights reserved.
69f988b79SJean-Baptiste Boric  *
79f988b79SJean-Baptiste Boric  * This code is derived from software contributed to The NetBSD Foundation
89f988b79SJean-Baptiste Boric  * by UCHIYAMA Yasushi.
99f988b79SJean-Baptiste Boric  *
109f988b79SJean-Baptiste Boric  * Redistribution and use in source and binary forms, with or without
119f988b79SJean-Baptiste Boric  * modification, are permitted provided that the following conditions
129f988b79SJean-Baptiste Boric  * are met:
139f988b79SJean-Baptiste Boric  * 1. Redistributions of source code must retain the above copyright
149f988b79SJean-Baptiste Boric  *    notice, this list of conditions and the following disclaimer.
159f988b79SJean-Baptiste Boric  * 2. Redistributions in binary form must reproduce the above copyright
169f988b79SJean-Baptiste Boric  *    notice, this list of conditions and the following disclaimer in the
179f988b79SJean-Baptiste Boric  *    documentation and/or other materials provided with the distribution.
189f988b79SJean-Baptiste Boric  *
199f988b79SJean-Baptiste Boric  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
209f988b79SJean-Baptiste Boric  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
219f988b79SJean-Baptiste Boric  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
229f988b79SJean-Baptiste Boric  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
239f988b79SJean-Baptiste Boric  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
249f988b79SJean-Baptiste Boric  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
259f988b79SJean-Baptiste Boric  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
269f988b79SJean-Baptiste Boric  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
279f988b79SJean-Baptiste Boric  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
289f988b79SJean-Baptiste Boric  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
299f988b79SJean-Baptiste Boric  * POSSIBILITY OF SUCH DAMAGE.
309f988b79SJean-Baptiste Boric  */
319f988b79SJean-Baptiste Boric 
329f988b79SJean-Baptiste Boric #include <sys/cdefs.h>
33*0a6a1f1dSLionel Sambuc __KERNEL_RCSID(0, "$NetBSD: v7fs_io_kern.c,v 1.3 2015/03/28 19:24:05 maxv Exp $");
349f988b79SJean-Baptiste Boric #if defined _KERNEL_OPT
359f988b79SJean-Baptiste Boric #include "opt_v7fs.h"
369f988b79SJean-Baptiste Boric #endif
379f988b79SJean-Baptiste Boric #include <sys/cdefs.h>
389f988b79SJean-Baptiste Boric 
39*0a6a1f1dSLionel Sambuc __KERNEL_RCSID(0, "$NetBSD: v7fs_io_kern.c,v 1.3 2015/03/28 19:24:05 maxv Exp $");
409f988b79SJean-Baptiste Boric 
419f988b79SJean-Baptiste Boric #include <sys/param.h>
429f988b79SJean-Baptiste Boric #include <sys/types.h>
439f988b79SJean-Baptiste Boric #include <sys/systm.h>
449f988b79SJean-Baptiste Boric #include <sys/buf.h>
459f988b79SJean-Baptiste Boric #include <sys/kmem.h>
469f988b79SJean-Baptiste Boric #include <sys/kauth.h>
479f988b79SJean-Baptiste Boric #include <sys/mutex.h>
489f988b79SJean-Baptiste Boric 
499f988b79SJean-Baptiste Boric #include <fs/v7fs/v7fs.h>
509f988b79SJean-Baptiste Boric #include "v7fs_endian.h"
519f988b79SJean-Baptiste Boric #include "v7fs_impl.h"
529f988b79SJean-Baptiste Boric 
539f988b79SJean-Baptiste Boric #ifdef V7FS_IO_DEBUG
549f988b79SJean-Baptiste Boric #define	DPRINTF(fmt, args...)	printf("%s: " fmt, __func__, ##args)
559f988b79SJean-Baptiste Boric #else
569f988b79SJean-Baptiste Boric #define	DPRINTF(fmt, args...)	((void)0)
579f988b79SJean-Baptiste Boric #endif
589f988b79SJean-Baptiste Boric 
599f988b79SJean-Baptiste Boric struct local_io {
609f988b79SJean-Baptiste Boric 	struct vnode *vp;
619f988b79SJean-Baptiste Boric 	kauth_cred_t cred;
629f988b79SJean-Baptiste Boric };
639f988b79SJean-Baptiste Boric 
649f988b79SJean-Baptiste Boric static bool v7fs_os_read_n(void *, uint8_t *, daddr_t, int);
659f988b79SJean-Baptiste Boric static bool v7fs_os_read(void *, uint8_t *, daddr_t);
669f988b79SJean-Baptiste Boric static bool v7fs_os_write_n(void *, uint8_t *, daddr_t, int);
679f988b79SJean-Baptiste Boric static bool v7fs_os_write(void *, uint8_t *, daddr_t);
689f988b79SJean-Baptiste Boric static void v7fs_os_lock(void *);
699f988b79SJean-Baptiste Boric static void v7fs_os_unlock(void *);
709f988b79SJean-Baptiste Boric static bool lock_init(struct lock_ops *);
719f988b79SJean-Baptiste Boric 
729f988b79SJean-Baptiste Boric int
v7fs_io_init(struct v7fs_self ** fs,const struct v7fs_mount_device * mount_device,size_t block_size)739f988b79SJean-Baptiste Boric v7fs_io_init(struct v7fs_self **fs,
749f988b79SJean-Baptiste Boric     const struct v7fs_mount_device *mount_device, size_t block_size)
759f988b79SJean-Baptiste Boric {
769f988b79SJean-Baptiste Boric 	struct vnode *vp = mount_device->device.vnode;
779f988b79SJean-Baptiste Boric 	struct v7fs_self *p;
789f988b79SJean-Baptiste Boric 	struct local_io *local;
799f988b79SJean-Baptiste Boric 	int error = 0;
809f988b79SJean-Baptiste Boric 
819f988b79SJean-Baptiste Boric 	if ((p = kmem_zalloc(sizeof(*p), KM_SLEEP)) == NULL)
829f988b79SJean-Baptiste Boric 		return ENOMEM;
839f988b79SJean-Baptiste Boric 
849f988b79SJean-Baptiste Boric 	p->scratch_free = -1;
859f988b79SJean-Baptiste Boric 	p->scratch_remain = V7FS_SELF_NSCRATCH;
869f988b79SJean-Baptiste Boric 
879f988b79SJean-Baptiste Boric 	/* Endian */
889f988b79SJean-Baptiste Boric 	p->endian = mount_device->endian;
899f988b79SJean-Baptiste Boric #ifdef V7FS_EI
909f988b79SJean-Baptiste Boric 	v7fs_endian_init(p);
919f988b79SJean-Baptiste Boric #endif
929f988b79SJean-Baptiste Boric 	/* IO */
939f988b79SJean-Baptiste Boric 	if ((local = kmem_zalloc(sizeof(*local), KM_SLEEP)) == NULL) {
949f988b79SJean-Baptiste Boric 		error = ENOMEM;
959f988b79SJean-Baptiste Boric 		goto errexit;
969f988b79SJean-Baptiste Boric 	}
979f988b79SJean-Baptiste Boric 	p->io.read = v7fs_os_read;
989f988b79SJean-Baptiste Boric 	p->io.read_n = v7fs_os_read_n;
999f988b79SJean-Baptiste Boric 	p->io.write = v7fs_os_write;
1009f988b79SJean-Baptiste Boric 	p->io.write_n = v7fs_os_write_n;
1019f988b79SJean-Baptiste Boric 	p->scratch_free = -1; /* free all scratch buffer */
1029f988b79SJean-Baptiste Boric 
1039f988b79SJean-Baptiste Boric 	p->io.cookie = local;
1049f988b79SJean-Baptiste Boric 	local->vp = vp;
1059f988b79SJean-Baptiste Boric 	local->cred = NOCRED;	/* upper layer check cred. */
1069f988b79SJean-Baptiste Boric 
1079f988b79SJean-Baptiste Boric 	/*LOCK */
1089f988b79SJean-Baptiste Boric 	error = ENOMEM;
1099f988b79SJean-Baptiste Boric 	if (!lock_init(&p->sb_lock))
1109f988b79SJean-Baptiste Boric 		goto errexit;
1119f988b79SJean-Baptiste Boric 	if (!lock_init(&p->ilist_lock))
1129f988b79SJean-Baptiste Boric 		goto errexit;
1139f988b79SJean-Baptiste Boric 	if (!lock_init(&p->mem_lock))
1149f988b79SJean-Baptiste Boric 		goto errexit;
1159f988b79SJean-Baptiste Boric 	error = 0;
1169f988b79SJean-Baptiste Boric 
1179f988b79SJean-Baptiste Boric 	*fs = p;
1189f988b79SJean-Baptiste Boric 	return 0;
1199f988b79SJean-Baptiste Boric 
1209f988b79SJean-Baptiste Boric errexit:
1219f988b79SJean-Baptiste Boric 	v7fs_io_fini(p);
1229f988b79SJean-Baptiste Boric 	return error;
1239f988b79SJean-Baptiste Boric }
1249f988b79SJean-Baptiste Boric 
1259f988b79SJean-Baptiste Boric static bool
lock_init(struct lock_ops * ops)1269f988b79SJean-Baptiste Boric lock_init(struct lock_ops *ops)
1279f988b79SJean-Baptiste Boric {
1289f988b79SJean-Baptiste Boric 	if ((ops->cookie = kmem_zalloc(sizeof(kmutex_t), KM_SLEEP)) == NULL) {
1299f988b79SJean-Baptiste Boric 		return false;
1309f988b79SJean-Baptiste Boric 	}
1319f988b79SJean-Baptiste Boric 	mutex_init(ops->cookie, MUTEX_DEFAULT, IPL_NONE);
1329f988b79SJean-Baptiste Boric 	ops->lock = v7fs_os_lock;
1339f988b79SJean-Baptiste Boric 	ops->unlock = v7fs_os_unlock;
1349f988b79SJean-Baptiste Boric 	return true;
1359f988b79SJean-Baptiste Boric }
1369f988b79SJean-Baptiste Boric 
1379f988b79SJean-Baptiste Boric void
v7fs_io_fini(struct v7fs_self * fs)1389f988b79SJean-Baptiste Boric v7fs_io_fini(struct v7fs_self *fs)
1399f988b79SJean-Baptiste Boric {
1409f988b79SJean-Baptiste Boric 	if (fs->io.cookie) {
1419f988b79SJean-Baptiste Boric 		kmem_free(fs->io.cookie, sizeof(struct local_io));
1429f988b79SJean-Baptiste Boric 	}
1439f988b79SJean-Baptiste Boric 	if (fs->sb_lock.cookie) {
1449f988b79SJean-Baptiste Boric 		mutex_destroy(fs->sb_lock.cookie);
1459f988b79SJean-Baptiste Boric 		kmem_free(fs->sb_lock.cookie, sizeof(kmutex_t));
1469f988b79SJean-Baptiste Boric 	}
1479f988b79SJean-Baptiste Boric 	if (fs->ilist_lock.cookie) {
1489f988b79SJean-Baptiste Boric 		mutex_destroy(fs->ilist_lock.cookie);
1499f988b79SJean-Baptiste Boric 		kmem_free(fs->ilist_lock.cookie, sizeof(kmutex_t));
1509f988b79SJean-Baptiste Boric 	}
1519f988b79SJean-Baptiste Boric 	if (fs->mem_lock.cookie) {
1529f988b79SJean-Baptiste Boric 		mutex_destroy(fs->mem_lock.cookie);
1539f988b79SJean-Baptiste Boric 		kmem_free(fs->mem_lock.cookie, sizeof(kmutex_t));
1549f988b79SJean-Baptiste Boric 	}
1559f988b79SJean-Baptiste Boric 	kmem_free(fs, sizeof(*fs));
1569f988b79SJean-Baptiste Boric }
1579f988b79SJean-Baptiste Boric 
1589f988b79SJean-Baptiste Boric static bool
v7fs_os_read_n(void * self,uint8_t * buf,daddr_t block,int count)1599f988b79SJean-Baptiste Boric v7fs_os_read_n(void *self, uint8_t *buf, daddr_t block, int count)
1609f988b79SJean-Baptiste Boric {
1619f988b79SJean-Baptiste Boric 	int i;
1629f988b79SJean-Baptiste Boric 
1639f988b79SJean-Baptiste Boric 	for (i = 0; i < count; i++) {
1649f988b79SJean-Baptiste Boric 		if (!v7fs_os_read(self, buf, block))
1659f988b79SJean-Baptiste Boric 			return false;
1669f988b79SJean-Baptiste Boric 		buf += DEV_BSIZE;
1679f988b79SJean-Baptiste Boric 		block++;
1689f988b79SJean-Baptiste Boric 	}
1699f988b79SJean-Baptiste Boric 
1709f988b79SJean-Baptiste Boric 	return true;
1719f988b79SJean-Baptiste Boric }
1729f988b79SJean-Baptiste Boric 
1739f988b79SJean-Baptiste Boric static bool
v7fs_os_read(void * self,uint8_t * buf,daddr_t block)1749f988b79SJean-Baptiste Boric v7fs_os_read(void *self, uint8_t *buf, daddr_t block)
1759f988b79SJean-Baptiste Boric {
1769f988b79SJean-Baptiste Boric 	struct local_io *bio = (struct local_io *)self;
1779f988b79SJean-Baptiste Boric 	struct buf *bp = NULL;
1789f988b79SJean-Baptiste Boric 
179*0a6a1f1dSLionel Sambuc 	if (bread(bio->vp, block, DEV_BSIZE, 0, &bp) != 0)
1809f988b79SJean-Baptiste Boric 		goto error_exit;
1819f988b79SJean-Baptiste Boric 	memcpy(buf, bp->b_data, DEV_BSIZE);
1829f988b79SJean-Baptiste Boric 	brelse(bp, 0);
1839f988b79SJean-Baptiste Boric 
1849f988b79SJean-Baptiste Boric 	return true;
1859f988b79SJean-Baptiste Boric error_exit:
1869f988b79SJean-Baptiste Boric 	DPRINTF("block %ld read failed.\n", (long)block);
1879f988b79SJean-Baptiste Boric 
1889f988b79SJean-Baptiste Boric 	if (bp != NULL)
1899f988b79SJean-Baptiste Boric 		brelse(bp, 0);
1909f988b79SJean-Baptiste Boric 	return false;
1919f988b79SJean-Baptiste Boric }
1929f988b79SJean-Baptiste Boric 
1939f988b79SJean-Baptiste Boric static bool
v7fs_os_write_n(void * self,uint8_t * buf,daddr_t block,int count)1949f988b79SJean-Baptiste Boric v7fs_os_write_n(void *self, uint8_t *buf, daddr_t block, int count)
1959f988b79SJean-Baptiste Boric {
1969f988b79SJean-Baptiste Boric 	int i;
1979f988b79SJean-Baptiste Boric 
1989f988b79SJean-Baptiste Boric 	for (i = 0; i < count; i++) {
1999f988b79SJean-Baptiste Boric 		if (!v7fs_os_write(self, buf, block))
2009f988b79SJean-Baptiste Boric 			return false;
2019f988b79SJean-Baptiste Boric 		buf += DEV_BSIZE;
2029f988b79SJean-Baptiste Boric 		block++;
2039f988b79SJean-Baptiste Boric 	}
2049f988b79SJean-Baptiste Boric 
2059f988b79SJean-Baptiste Boric 	return true;
2069f988b79SJean-Baptiste Boric }
2079f988b79SJean-Baptiste Boric 
2089f988b79SJean-Baptiste Boric static bool
v7fs_os_write(void * self,uint8_t * buf,daddr_t block)2099f988b79SJean-Baptiste Boric v7fs_os_write(void *self, uint8_t *buf, daddr_t block)
2109f988b79SJean-Baptiste Boric {
2119f988b79SJean-Baptiste Boric 	struct local_io *bio = (struct local_io *)self;
2129f988b79SJean-Baptiste Boric 	struct buf *bp;
2139f988b79SJean-Baptiste Boric 
2149f988b79SJean-Baptiste Boric 	if ((bp = getblk(bio->vp, block, DEV_BSIZE, 0, 0)) == 0) {
2159f988b79SJean-Baptiste Boric 		DPRINTF("getblk failed. block=%ld\n", (long)block);
2169f988b79SJean-Baptiste Boric 		return false;
2179f988b79SJean-Baptiste Boric 	}
2189f988b79SJean-Baptiste Boric 
2199f988b79SJean-Baptiste Boric 	memcpy(bp->b_data, buf, DEV_BSIZE);
2209f988b79SJean-Baptiste Boric 
2219f988b79SJean-Baptiste Boric 	if (bwrite(bp) != 0) {
2229f988b79SJean-Baptiste Boric 		DPRINTF("bwrite failed. block=%ld\n", (long)block);
2239f988b79SJean-Baptiste Boric 		return false;
2249f988b79SJean-Baptiste Boric 	}
2259f988b79SJean-Baptiste Boric 
2269f988b79SJean-Baptiste Boric 	return true;
2279f988b79SJean-Baptiste Boric }
2289f988b79SJean-Baptiste Boric 
2299f988b79SJean-Baptiste Boric static void
v7fs_os_lock(void * self)2309f988b79SJean-Baptiste Boric v7fs_os_lock(void *self)
2319f988b79SJean-Baptiste Boric {
2329f988b79SJean-Baptiste Boric 
2339f988b79SJean-Baptiste Boric 	mutex_enter((kmutex_t *)self);
2349f988b79SJean-Baptiste Boric }
2359f988b79SJean-Baptiste Boric 
2369f988b79SJean-Baptiste Boric static void
v7fs_os_unlock(void * self)2379f988b79SJean-Baptiste Boric v7fs_os_unlock(void *self)
2389f988b79SJean-Baptiste Boric {
2399f988b79SJean-Baptiste Boric 
2409f988b79SJean-Baptiste Boric 	mutex_exit((kmutex_t *)self);
2419f988b79SJean-Baptiste Boric }
242