Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Mar 2012 03:02:10 +0000 (UTC)
From:      Grzegorz Bernacki <gber@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r233071 - in projects/nand/lib: . libnandfs
Message-ID:  <201203170302.q2H32BJ1047232@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gber
Date: Sat Mar 17 03:02:10 2012
New Revision: 233071
URL: http://svn.freebsd.org/changeset/base/233071

Log:
  Add NANDFS library.
  
  Obtained from: Semihalf
  Supported by:  FreeBSD Foundation, Juniper Networks

Added:
  projects/nand/lib/libnandfs/
  projects/nand/lib/libnandfs/Makefile
  projects/nand/lib/libnandfs/libnandfs.h
  projects/nand/lib/libnandfs/nandfs.c
Modified:
  projects/nand/lib/Makefile

Modified: projects/nand/lib/Makefile
==============================================================================
--- projects/nand/lib/Makefile	Sat Mar 17 03:00:51 2012	(r233070)
+++ projects/nand/lib/Makefile	Sat Mar 17 03:02:10 2012	(r233071)
@@ -85,6 +85,7 @@ SUBDIR=	${SUBDIR_ORDERED} \
 	libmemstat \
 	${_libmilter} \
 	${_libmp} \
+	${_libnandfs} \
 	${_libncp} \
 	${_libngatm} \
 	libopie \
@@ -171,6 +172,10 @@ _libipx=	libipx
 _libthr=	libthr
 .endif
 
+.if ${MK_NAND} != "no"
+_libnandfs=	libnandfs
+.endif
+
 .if ${MK_NETGRAPH} != "no"
 _libnetgraph=	libnetgraph
 .endif

Added: projects/nand/lib/libnandfs/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/lib/libnandfs/Makefile	Sat Mar 17 03:02:10 2012	(r233071)
@@ -0,0 +1,7 @@
+LIB=	nandfs
+SRCS+=	nandfs.c
+INCS=	libnandfs.h
+
+CFLAGS += -I${.CURDIR}
+
+.include <bsd.lib.mk>

Added: projects/nand/lib/libnandfs/libnandfs.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/lib/libnandfs/libnandfs.h	Sat Mar 17 03:02:10 2012	(r233071)
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 2010-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef	_LIBNANDFS_NANDFS_H
+#define	_LIBNANDFS_NANDFS_H
+
+struct nandfs {
+	struct nandfs_fsdata		n_fsdata;
+	struct nandfs_super_block	n_sb;
+	char				n_ioc[MNAMELEN];
+	char				n_dev[MNAMELEN];
+	int				n_iocfd;
+	int				n_devfd;
+	int				n_flags;
+	char				n_errmsg[120];
+};
+
+int nandfs_iserror(struct nandfs *);
+const char *nandfs_errmsg(struct nandfs *);
+
+void nandfs_init(struct nandfs *, const char *);
+void nandfs_destroy(struct nandfs *);
+
+int nandfs_cleanerd_set(struct nandfs *);
+int nandfs_cleanerd_unset(struct nandfs *);
+
+const char *nandfs_dev(struct nandfs *);
+
+int nandfs_open(struct nandfs *);
+int nandfs_open_rw(struct nandfs *);
+int nandfs_open_dev(struct nandfs *);
+void nandfs_close(struct nandfs *);
+void nandfs_close_dev(struct nandfs *);
+
+int nandfs_lock(struct nandfs *, int write);
+int nandfs_unlock(struct nandfs *);
+
+ssize_t nandfs_get_cp(struct nandfs *, uint64_t,
+    struct nandfs_cpinfo *, size_t);
+
+ssize_t nandfs_get_snap(struct nandfs *, uint64_t,
+    struct nandfs_cpinfo *, size_t);
+
+int nandfs_make_snap(struct nandfs *, uint64_t *);
+int nandfs_delete_snap(struct nandfs *, uint64_t);
+
+#endif	/* _LIBNANDFS_NANDFS_H */

Added: projects/nand/lib/libnandfs/nandfs.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/lib/libnandfs/nandfs.c	Sat Mar 17 03:02:10 2012	(r233071)
@@ -0,0 +1,379 @@
+/*-
+ * Copyright (c) 2010-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/stdint.h>
+#include <sys/ucred.h>
+#include <sys/disk.h>
+#include <sys/mount.h>
+
+#include <fs/nandfs/nandfs_fs.h>
+#include <libnandfs.h>
+
+#define	NANDFS_IS_VALID		0x1
+#define	NANDFS_IS_OPENED	0x2
+#define	NANDFS_IS_OPENED_DEV	0x4
+#define	NANDFS_IS_ERROR		0x8
+#define	NANDFS_IS_LOCKED	0x10
+#define	NANDFS_IS_READONLY	0x20
+
+#define DEBUG
+#undef DEBUG
+#ifdef DEBUG
+#define NANDFS_DEBUG(fmt, args...) do { \
+    printf("libnandfs:" fmt "\n", ##args); } while (0)
+#else
+#define NANDFS_DEBUG(fmt, args...)
+#endif
+
+#define	NANDFS_ASSERT_VALID(fs)		assert((fs)->n_flags & NANDFS_IS_VALID)
+#define	NANDFS_ASSERT_VALID_DEV(fs)	\
+	assert(((fs)->n_flags & (NANDFS_IS_VALID | NANDFS_IS_OPENED_DEV)) == \
+	    (NANDFS_IS_VALID | NANDFS_IS_OPENED_DEV))
+#define NANDFS_ASSERT_RDWR(fs)		\
+	assert(!((fs)->n_flags & NANDFS_IS_READONLY))
+#define NANDFS_ASSERT_LOCKED(fs)	\
+	assert((fs)->n_flags & NANDFS_IS_LOCKED)
+#define NANDFS_ASSERT_UNLOCKED(fs)	\
+	assert(!((fs)->n_flags & NANDFS_IS_LOCKED))
+
+int
+nandfs_iserror(struct nandfs *fs)
+{
+
+	NANDFS_ASSERT_VALID(fs);
+
+	return (fs->n_flags & NANDFS_IS_ERROR);
+}
+
+const char *
+nandfs_errmsg(struct nandfs *fs)
+{
+
+	NANDFS_ASSERT_VALID(fs);
+
+	assert(nandfs_iserror(fs));
+	assert(fs->n_errmsg);
+	return (fs->n_errmsg);
+}
+
+static void
+nandfs_seterr(struct nandfs *fs, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vsnprintf(fs->n_errmsg, sizeof(fs->n_errmsg), fmt, ap);
+	va_end(ap);
+	fs->n_flags |= NANDFS_IS_ERROR;
+}
+
+int
+nandfs_cleanerd_set(struct nandfs *fs)
+{
+
+	NANDFS_ASSERT_VALID_DEV(fs);
+
+	if (ioctl(fs->n_iocfd, NANDFS_IOCTL_CLEANERD_SET) == -1) {
+		nandfs_seterr(fs, "%s", strerror(errno));
+		return (-1);
+	}
+
+	return (0);
+}
+
+int
+nandfs_cleanerd_unset(struct nandfs *fs)
+{
+
+	NANDFS_ASSERT_VALID_DEV(fs);
+
+	if (ioctl(fs->n_iocfd, NANDFS_IOCTL_CLEANERD_UNSET) == -1) {
+		nandfs_seterr(fs, "%s", strerror(errno));
+		return (-1);
+	}
+
+	return (0);
+}
+
+int
+nandfs_lock(struct nandfs *fs, int rdwr)
+{
+	struct flock lck;
+	int error;
+
+	NANDFS_ASSERT_VALID(fs);
+	NANDFS_ASSERT_RDWR(fs);
+	NANDFS_ASSERT_UNLOCKED(fs);
+
+	lck.l_type = (rdwr ? F_WRLCK : F_RDLCK);
+	lck.l_start = 0;
+	lck.l_whence = SEEK_SET;
+	lck.l_len = 1;
+
+	error = fcntl(fs->n_iocfd, F_SETLKW, &lck);
+	if (error == -1) {
+		nandfs_seterr(fs, "couldn't lock %s: %s", fs->n_ioc,
+		    strerror(errno));
+		return (-1);
+	}
+
+	fs->n_flags |= NANDFS_IS_LOCKED;
+
+	return (0);
+}
+
+int
+nandfs_unlock(struct nandfs *fs)
+{
+	struct flock lck;
+	int error;
+
+	NANDFS_ASSERT_VALID(fs);
+	NANDFS_ASSERT_RDWR(fs);
+	NANDFS_ASSERT_LOCKED(fs);
+
+	lck.l_type = F_UNLCK;
+	lck.l_start = 0;
+	lck.l_whence = SEEK_SET;
+	lck.l_len = 1;
+
+	error = fcntl(fs->n_iocfd, F_SETLK, &lck);
+	if (error == -1) {
+		nandfs_seterr(fs, "couldn't unlock %s: %s", fs->n_ioc,
+		    strerror(errno));
+		return (-1);
+	}
+
+	fs->n_flags &= ~NANDFS_IS_LOCKED;
+
+	return (0);
+}
+
+const char *
+nandfs_dev(struct nandfs *fs)
+{
+
+	NANDFS_ASSERT_VALID(fs);
+	return (fs->n_dev);
+}
+
+void
+nandfs_init(struct nandfs *fs, const char *dir)
+{
+
+	snprintf(fs->n_ioc, sizeof(fs->n_ioc), "%s/%s", dir, ".nandfs");
+	fs->n_iocfd = -1;
+	fs->n_flags = NANDFS_IS_VALID;
+}
+
+void
+nandfs_destroy(struct nandfs *fs)
+{
+
+	assert(fs->n_iocfd == -1);
+	fs->n_flags &=
+	    ~(NANDFS_IS_ERROR | NANDFS_IS_VALID | NANDFS_IS_READONLY);
+	assert(fs->n_flags == 0);
+}
+
+static int
+_nandfs_open(struct nandfs *fs, int rdwr)
+{
+	struct nandfs_fsinfo fsinfo;
+	int flags;
+
+	fs->n_flags |= NANDFS_IS_OPENED;
+
+	if (rdwr)
+		flags = O_RDWR;
+	else {
+		fs->n_flags |= NANDFS_IS_READONLY;
+		flags = O_RDONLY;
+	}
+
+	fs->n_iocfd = open(fs->n_ioc, flags, S_IRUSR | S_IWUSR | S_IRGRP |
+	    S_IWGRP | S_IROTH | S_IWOTH);
+	if (fs->n_iocfd == -1) {
+		nandfs_seterr(fs, "couldn't open %s: %s", fs->n_ioc,
+		    strerror(errno));
+		return (-1);
+	}
+
+	if (ioctl(fs->n_iocfd, NANDFS_IOCTL_GET_FSINFO, &fsinfo) == -1) {
+		nandfs_seterr(fs, "couldn't fetch fsinfo: %s",
+		    strerror(errno));
+		return (-1);
+	}
+
+	memcpy(&fs->n_fsdata, &fsinfo.fs_fsdata, sizeof(fs->n_fsdata));
+	memcpy(&fs->n_sb, &fsinfo.fs_super, sizeof(fs->n_sb));
+	snprintf(fs->n_dev, sizeof(fs->n_dev), fsinfo.fs_dev);
+
+	return (0);
+}
+
+int
+nandfs_open(struct nandfs *fs)
+{
+
+	return (_nandfs_open(fs, 0));
+}
+
+int
+nandfs_open_rw(struct nandfs *fs)
+{
+
+	return (_nandfs_open(fs, 1));
+}
+
+int
+nandfs_open_dev(struct nandfs *fs)
+{
+
+	fs->n_flags |= NANDFS_IS_OPENED_DEV;
+
+	if (nandfs_open_rw(fs) == -1)
+		return (-1);
+
+	fs->n_devfd = open(fs->n_dev, O_RDONLY);
+	if (fs->n_devfd == -1) {
+		nandfs_seterr(fs, "couldn't open %s: %s", fs->n_dev,
+		    strerror(errno));
+		return (-1);
+	}
+
+	return (0);
+}
+
+void
+nandfs_close(struct nandfs *fs)
+{
+
+	NANDFS_ASSERT_VALID(fs);
+	assert(fs->n_flags & NANDFS_IS_OPENED);
+
+	close(fs->n_iocfd);
+	fs->n_iocfd = -1;
+	fs->n_flags &= ~NANDFS_IS_OPENED;
+}
+
+void
+nandfs_close_dev(struct nandfs *fs)
+{
+
+	assert(fs->n_flags & NANDFS_IS_OPENED_DEV);
+
+	close(fs->n_devfd);
+	fs->n_devfd = -1;
+	fs->n_flags &= ~NANDFS_IS_OPENED_DEV;
+	nandfs_close(fs);
+}
+
+static ssize_t
+nandfs_get_cpinfo(struct nandfs *fs, uint64_t cno, int mode,
+    struct nandfs_cpinfo *cpinfo, size_t nci)
+{
+	struct nandfs_argv args;
+
+	NANDFS_ASSERT_VALID(fs);
+
+	args.nv_base = (u_long)cpinfo;
+	args.nv_nmembs = nci;
+	args.nv_index = cno;
+	args.nv_flags = mode;
+
+	if (ioctl(fs->n_iocfd, NANDFS_IOCTL_GET_CPINFO, &args) == -1) {
+		nandfs_seterr(fs, "ioctl NANDFS_IOCTL_GET_CPINFO: %s",
+		    strerror(errno));
+		return (-1);
+	}
+
+	return (args.nv_nmembs);
+}
+
+ssize_t
+nandfs_get_cp(struct nandfs *fs, uint64_t cno, struct nandfs_cpinfo *cpinfo,
+    size_t nci)
+{
+
+	return (nandfs_get_cpinfo(fs, cno, NANDFS_CHECKPOINT, cpinfo, nci));
+}
+
+ssize_t
+nandfs_get_snap(struct nandfs *fs, uint64_t cno, struct nandfs_cpinfo *cpinfo,
+    size_t nci)
+{
+
+	return (nandfs_get_cpinfo(fs, cno, NANDFS_SNAPSHOT, cpinfo, nci));
+}
+
+int
+nandfs_make_snap(struct nandfs *fs, uint64_t *cno)
+{
+
+	NANDFS_ASSERT_VALID(fs);
+	NANDFS_ASSERT_RDWR(fs);
+	NANDFS_ASSERT_LOCKED(fs);
+
+	if (ioctl(fs->n_iocfd, NANDFS_IOCTL_MAKE_SNAP, cno) == -1) {
+		nandfs_seterr(fs, "ioctl NANDFS_IOCTL_MAKE_SNAP: %s",
+		    strerror(errno));
+		return (-1);
+	}
+
+	return (0);
+}
+
+int
+nandfs_delete_snap(struct nandfs *fs, uint64_t cno)
+{
+
+	NANDFS_ASSERT_VALID(fs);
+	NANDFS_ASSERT_RDWR(fs);
+	NANDFS_ASSERT_LOCKED(fs);
+
+	if (ioctl(fs->n_iocfd, NANDFS_IOCTL_DELETE_SNAP, &cno) == -1) {
+		nandfs_seterr(fs, "ioctl NANDFS_IOCTL_DELETE_SNAP: %s",
+		    strerror(errno));
+		return (-1);
+	}
+
+	return (0);
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203170302.q2H32BJ1047232>