[BACK]Return to v7fs_populate.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.sbin / makefs / v7fs

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>