tmpfs の unlink(2) 時のコードを調べる ― 2009年02月02日 01時14分51秒
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 を指すファイルが見つかってしまう。
これが原因だ。
最近のコメント