tmpfs の unlink(2) 時のコードを調べる2009年02月02日 01時14分51秒

ファイルが unlink(2) される時は src/sys/fs/tmpfs/tmpfs_vnops.c にある tmpfs_remove が呼ばれる。

static int
tmpfs_remove(struct vop_remove_args *v)
{
        struct vnode *dvp = v->a_dvp;
        struct vnode *vp = v->a_vp;

        int error;
        struct tmpfs_dirent *de;
        struct tmpfs_mount *tmp;
        struct tmpfs_node *dnode;
        struct tmpfs_node *node;

        MPASS(VOP_ISLOCKED(dvp));
        MPASS(VOP_ISLOCKED(vp));

        if (vp->v_type == VDIR) {
                error = EISDIR;
                goto out;
        }

        dnode = VP_TO_TMPFS_DIR(dvp);
        node = VP_TO_TMPFS_NODE(vp);
        tmp = VFS_TO_TMPFS(vp->v_mount);
        de = tmpfs_dir_search(dnode, node);
        MPASS(de != NULL);

        /* Files marked as immutable or append-only cannot be deleted. */
        if ((node->tn_flags & (IMMUTABLE | APPEND | NOUNLINK)) ||
            (dnode->tn_flags & APPEND)) {
                error = EPERM;
                goto out;
        }

        /* Remove the entry from the directory; as it is a file, we do not
         * have to change the number of hard links of the directory. */
        tmpfs_dir_detach(dvp, de);

        /* Free the directory entry we just deleted.  Note that the node
         * referred by it will not be removed until the vnode is really
         * reclaimed. */
        tmpfs_free_dirent(tmp, de, TRUE);

        if (node->tn_links > 0)
                node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \
            TMPFS_NODE_MODIFIED;

        error = 0;

out:

        return error;
}
この中で、ディレクトリ内を削除対象のファイルを tmpfs_dir_search で探すようになっている。

src/sys/fs/tmpfs/tmpfs_subr.c にある。


struct tmpfs_dirent *
tmpfs_dir_search(struct tmpfs_node *node, struct tmpfs_node *f)
{
	struct tmpfs_dirent *de;

	TMPFS_VALIDATE_DIR(node);
	node->tn_status |= TMPFS_NODE_ACCESSED;
	TAILQ_FOREACH(de, &node->tn_dir.tn_dirhead, td_entries) {
		if (de->td_node == f)
			return (de);
	}
	return (NULL);
}

これを見ると、ポインタのみの比較になっている。if (de->td_node == f) の部分がそれだ。ハードリンクがあると、削除するファイルの名前ではなく、一番最初に同じ i-node を指すファイルが見つかってしまう。

これが原因だ。

前回次回