Annotation of src/usr.sbin/makefs/v7fs/v7fs_populate.c, Revision 1.1
1.1 ! uch 1: /* $NetBSD$ */
! 2:
! 3: /*-
! 4: * Copyright (c) 2011 The NetBSD Foundation, Inc.
! 5: * All rights reserved.
! 6: *
! 7: * This code is derived from software contributed to The NetBSD Foundation
! 8: * by UCHIYAMA Yasushi.
! 9: *
! 10: * Redistribution and use in source and binary forms, with or without
! 11: * modification, are permitted provided that the following conditions
! 12: * are met:
! 13: * 1. Redistributions of source code must retain the above copyright
! 14: * notice, this list of conditions and the following disclaimer.
! 15: * 2. Redistributions in binary form must reproduce the above copyright
! 16: * notice, this list of conditions and the following disclaimer in the
! 17: * documentation and/or other materials provided with the distribution.
! 18: *
! 19: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 20: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 21: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 22: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 23: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 24: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 25: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 26: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 27: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 28: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 29: * POSSIBILITY OF SUCH DAMAGE.
! 30: */
! 31:
! 32: #if HAVE_NBTOOL_CONFIG_H
! 33: #include "nbtool_config.h"
! 34: #endif
! 35:
! 36: #include <sys/cdefs.h>
! 37: #if defined(__RCSID) && !defined(__lint)
! 38: __RCSID("$NetBSD$");
! 39: #endif /* !__lint */
! 40:
! 41: #include <stdio.h>
! 42: #include <stdlib.h>
! 43: #include <string.h>
! 44: #include <unistd.h>
! 45: #include <fcntl.h>
! 46: #include <errno.h>
! 47: #include <err.h>
! 48:
! 49: #if !HAVE_NBTOOL_CONFIG_H
! 50: #include <sys/mount.h>
! 51: #endif
! 52:
! 53: #include "makefs.h"
! 54: #include "v7fs.h"
! 55: #include "v7fs_impl.h"
! 56: #include "v7fs_inode.h"
! 57: #include "v7fs_superblock.h"
! 58: #include "v7fs_datablock.h"
! 59: #include "v7fs_endian.h"
! 60: #include "v7fs_file.h"
! 61: #include "v7fs_makefs.h"
! 62: #include "newfs_v7fs.h"
! 63:
! 64: extern bool verbose;
! 65: #define VPRINTF(fmt, args...) { if (verbose) printf(fmt, ##args); }
! 66:
! 67: static void
! 68: attr_setup(fsnode *node, struct v7fs_fileattr *attr)
! 69: {
! 70: struct stat *st = &node->inode->st;
! 71:
! 72: attr->mode = node->type | st->st_mode;
! 73: attr->uid = st->st_uid;
! 74: attr->gid = st->st_gid;
! 75: attr->device = 0;
! 76: attr->ctime = st->st_ctime;
! 77: attr->atime = st->st_atime;
! 78: attr->mtime = st->st_mtime;
! 79: }
! 80:
! 81: static int
! 82: allocate(struct v7fs_self *fs, struct v7fs_inode *parent_inode, fsnode *node,
! 83: dev_t dev, struct v7fs_inode *inode)
! 84: {
! 85: int error;
! 86: v7fs_ino_t ino;
! 87: struct v7fs_fileattr attr;
! 88:
! 89: memset(inode, 0, sizeof(*inode));
! 90:
! 91: attr_setup(node, &attr);
! 92: attr.device = dev;
! 93: if ((error = v7fs_file_allocate(fs, parent_inode, node->name, &attr,
! 94: &ino))) {
! 95: errno = error;
! 96: warn("%s", node->name);
! 97: return error;
! 98: }
! 99: node->inode->ino = ino;
! 100: node->inode->flags |= FI_ALLOCATED;
! 101: if ((error = v7fs_inode_load(fs, inode, ino))) {
! 102: errno = error;
! 103: warn("%s", node->name);
! 104: return error;
! 105: }
! 106:
! 107: return 0;
! 108: }
! 109:
! 110: struct copy_arg {
! 111: int fd;
! 112: uint8_t buf[V7FS_BSIZE];
! 113: };
! 114:
! 115: static int
! 116: copy_subr(struct v7fs_self *fs, void *ctx, v7fs_daddr_t blk, size_t sz)
! 117: {
! 118: struct copy_arg *p = ctx;
! 119:
! 120: if ((sz = read(p->fd, p->buf, sz)) != sz) {
! 121: return V7FS_ITERATOR_ERROR;
! 122: }
! 123:
! 124: if (!fs->io.write(fs->io.cookie, p->buf, blk)) {
! 125: errno = EIO;
! 126: return V7FS_ITERATOR_ERROR;
! 127: }
! 128: progress(0);
! 129:
! 130: return 0;
! 131: }
! 132:
! 133: static int
! 134: file_copy(struct v7fs_self *fs, struct v7fs_inode *parent_inode, fsnode *node,
! 135: const char *filepath)
! 136: {
! 137: struct v7fs_inode inode;
! 138: const char *errmsg;
! 139: fsinode *fnode = node->inode;
! 140: int error = 0;
! 141: int fd;
! 142:
! 143: /* Check hard-link */
! 144: if ((fnode->nlink > 1) && (fnode->flags & FI_ALLOCATED)) {
! 145: if ((error = v7fs_inode_load(fs, &inode, fnode->ino))) {
! 146: errmsg = "inode load";
! 147: goto err_exit;
! 148: }
! 149: if ((error = v7fs_file_link(fs, parent_inode, &inode,
! 150: node->name))) {
! 151: errmsg = "hard link";
! 152: goto err_exit;
! 153: }
! 154: return 0;
! 155: }
! 156:
! 157: /* Allocate file */
! 158: if ((error = allocate(fs, parent_inode, node, 0, &inode))) {
! 159: errmsg = "file allocate";
! 160: goto err_exit;
! 161: }
! 162: if ((error = v7fs_datablock_expand(fs, &inode, fnode->st.st_size))) {
! 163: errmsg = "datablock expand";
! 164: goto err_exit;
! 165: }
! 166:
! 167: /* Data copy */
! 168: if ((fd = open(filepath, O_RDONLY)) == -1) {
! 169: error = errno;
! 170: errmsg = "source file";
! 171: goto err_exit;
! 172: }
! 173:
! 174: error = v7fs_datablock_foreach(fs, &inode, copy_subr,
! 175: &(struct copy_arg){ .fd = fd });
! 176: if (error != V7FS_ITERATOR_END) {
! 177: errmsg = "data copy";
! 178: close(fd);
! 179: goto err_exit;
! 180: } else {
! 181: error = 0;
! 182: }
! 183: close(fd);
! 184:
! 185: return error;
! 186:
! 187: err_exit:
! 188: errno = error;
! 189: warn("%s %s", node->name, errmsg);
! 190:
! 191: return error;
! 192: }
! 193:
! 194: static int
! 195: populate_walk(struct v7fs_self *fs, struct v7fs_inode *parent_inode,
! 196: fsnode *root, char *dir)
! 197: {
! 198: fsnode *cur;
! 199: char *mydir = dir + strlen(dir);
! 200: char srcpath[MAXPATHLEN + 1];
! 201: struct v7fs_inode inode;
! 202: int error = 0;
! 203: bool failed = false;
! 204:
! 205: for (cur = root; cur != NULL; cur = cur->next) {
! 206: switch (cur->type & S_IFMT) {
! 207: default:
! 208: VPRINTF("%x\n", cur->flags & S_IFMT);
! 209: break;
! 210: case S_IFCHR:
! 211: /*FALLTHROUGH*/
! 212: case S_IFBLK:
! 213: if ((error = allocate(fs, parent_inode, cur,
! 214: cur->inode->st.st_rdev, &inode))) {
! 215: errno = error;
! 216: warn("%s", cur->name);
! 217: }
! 218: break;
! 219: case S_IFDIR:
! 220: if (!cur->child) /*'.'*/
! 221: break;
! 222: /* Allocate this directory. */
! 223: if ((error = allocate(fs, parent_inode, cur, 0,
! 224: &inode))) {
! 225: errno = error;
! 226: warn("%s", cur->name);
! 227: } else {
! 228: /* Populate children. */
! 229: mydir[0] = '/';
! 230: strcpy(&mydir[1], cur->name);
! 231: error = populate_walk(fs, &inode, cur->child,
! 232: dir);
! 233: mydir[0] = '\0';
! 234: }
! 235: break;
! 236: case S_IFREG:
! 237: snprintf(srcpath, sizeof(srcpath), "%s/%s", dir,
! 238: cur->name);
! 239: error = file_copy(fs, parent_inode, cur, srcpath);
! 240: break;
! 241: case S_IFLNK:
! 242: if ((error = allocate(fs, parent_inode, cur, 0,
! 243: &inode))) {
! 244: errno = error;
! 245: warn("%s", cur->name);
! 246: } else {
! 247: v7fs_file_symlink(fs, &inode, cur->symlink);
! 248: }
! 249: break;
! 250: }
! 251: if (error)
! 252: failed = true;
! 253: }
! 254:
! 255: return failed ? 2 : 0;
! 256: }
! 257:
! 258: int
! 259: v7fs_populate(const char *dir, fsnode *root, fsinfo_t *fsopts,
! 260: const struct v7fs_mount_device *device)
! 261: {
! 262: v7fs_opt_t *v7fs_opts = fsopts->fs_specific;
! 263: static char path[MAXPATHLEN + 1];
! 264: struct v7fs_inode root_inode;
! 265: struct v7fs_self *fs;
! 266: int error;
! 267:
! 268: if ((error = v7fs_io_init(&fs, device, V7FS_BSIZE))) {
! 269: errno = error;
! 270: warn("I/O setup failed.");
! 271: return error;
! 272: }
! 273: fs->endian = device->endian;
! 274: v7fs_endian_init(fs);
! 275:
! 276: if ((error = v7fs_superblock_load(fs))) {
! 277: errno = error;
! 278: warn("Can't load superblock.");
! 279: return error;
! 280: }
! 281: fsopts->superblock = &fs->superblock; /* not used. */
! 282:
! 283: if ((error = v7fs_inode_load(fs, &root_inode, V7FS_ROOT_INODE))) {
! 284: errno = error;
! 285: warn("Can't load root inode.");
! 286: return error;
! 287: }
! 288:
! 289: progress(&(struct progress_arg){ .label = "populate", .tick =
! 290: v7fs_opts->npuredatablk / PROGRESS_BAR_GRANULE });
! 291:
! 292: strncpy(path, dir, sizeof(path));
! 293: error = populate_walk(fs, &root_inode, root, path);
! 294:
! 295: v7fs_inode_writeback(fs, &root_inode);
! 296: v7fs_superblock_writeback(fs);
! 297:
! 298: return error;
! 299: }
CVSweb <webmaster@jp.NetBSD.org>