*
* For the five existing metadata inodes (real time bitmap & summary; and the
* user, group, and quotas) we'll continue to maintain the in-core superblock
- * inodes for reads and only require xfs_imeta_create and xfs_imeta_unlink to
+ * inodes for reads and only require xfs_imeta_create to
* persist changes. New metadata inode types must only use the xfs_imeta_*
* functions.
*
return 0;
}
-/*
- * Clear the given inode pointer from the superblock and drop the link count
- * of the metadata inode.
- */
-STATIC int
-xfs_imeta_sb_unlink(
- struct xfs_imeta_update *upd)
-{
- struct xfs_mount *mp = upd->mp;
- xfs_ino_t *sb_inop;
-
- xfs_assert_ilocked(upd->ip, XFS_ILOCK_EXCL);
-
- sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
- if (!sb_inop)
- return -EINVAL;
-
- /* Reject if the sb doesn't point to the inode that was passed in. */
- if (*sb_inop != upd->ip->i_ino)
- return -ENOENT;
-
- trace_xfs_imeta_sb_unlink(upd);
-
- *sb_inop = NULLFSINO;
- xfs_imeta_log_sb(upd->tp);
- return xfs_droplink(upd->tp, upd->ip);
-}
-
/* Set the given inode pointer in the superblock. */
STATIC int
xfs_imeta_sb_link(
return 0;
}
-/*
- * Remove the given entry from the metadata directory and drop the link count
- * of the metadata inode.
- */
-STATIC int
-xfs_imeta_dir_unlink(
- struct xfs_imeta_update *upd)
-{
- struct xfs_name xname;
- struct xfs_dir_update du = {
- .dp = upd->dp,
- .name = &xname,
- .ip = upd->ip,
- .ppargs = upd->ppargs,
- };
- struct xfs_mount *mp = upd->mp;
- xfs_ino_t *sb_inop;
- xfs_ino_t ino;
- unsigned int resblks;
- int error;
-
- xfs_assert_ilocked(upd->dp, XFS_ILOCK_EXCL);
- xfs_assert_ilocked(upd->ip, XFS_ILOCK_EXCL);
-
- /* Metadata directory root cannot be unlinked. */
- if (xfs_imeta_path_compare(upd->path, &XFS_IMETA_METADIR)) {
- ASSERT(0);
- xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
- return -EFSCORRUPTED;
- }
-
- ASSERT(upd->path->im_depth > 0);
-
- /* Look up the name in the current directory. */
- xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
- xfs_mode_to_ftype(VFS_I(upd->ip)->i_mode));
- error = xfs_imeta_dir_lookup_component(upd->tp, upd->dp, &xname, &ino);
- switch (error) {
- case 0:
- if (ino != upd->ip->i_ino)
- error = -ENOENT;
- break;
- case -ENOENT:
- xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
- error = -EFSCORRUPTED;
- break;
- }
- if (error)
- return error;
-
- resblks = xfs_remove_space_res(mp, xname.len);
- error = xfs_dir_remove_child(upd->tp, resblks, &du);
- if (error)
- return error;
-
- trace_xfs_imeta_dir_unlink(upd);
-
- /* Update the in-core superblock value if there is one. */
- sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
- if (sb_inop)
- *sb_inop = NULLFSINO;
- return 0;
-}
-
/* Set the given path in the metadata directory to point to an inode. */
STATIC int
xfs_imeta_dir_link(
return error;
}
-/* Free a file from the metadata directory tree. */
-STATIC int
-xfs_imeta_ifree(
- struct xfs_trans *tp,
- struct xfs_inode *ip)
-{
- struct xfs_mount *mp = ip->i_mount;
- struct xfs_perag *pag;
- struct xfs_icluster xic = { 0 };
- int error;
-
- xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
- ASSERT(VFS_I(ip)->i_nlink == 0);
- ASSERT(ip->i_df.if_nextents == 0);
- ASSERT(ip->i_disk_size == 0 || !S_ISREG(VFS_I(ip)->i_mode));
- ASSERT(ip->i_nblocks == 0);
-
- pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
-
- error = xfs_inode_uninit(tp, pag, ip, &xic);
- if (error)
- goto out;
-
- /* Metadata files do not support ownership changes or DMAPI. */
-
- if (xic.deleted)
- error = xfs_ifree_cluster(tp, pag, ip, &xic);
-out:
- xfs_perag_put(pag);
- return error;
-}
-
-/*
- * Unlink a metadata inode @upd->ip from the metadata directory given by @path.
- * The path must already exist.
- */
-int
-xfs_imeta_unlink(
- struct xfs_imeta_update *upd)
-{
- int error;
-
- ASSERT(xfs_imeta_path_check(upd->path));
- ASSERT(xfs_imeta_verify(upd->mp, upd->ip->i_ino));
-
- if (xfs_has_metadir(upd->mp))
- error = xfs_imeta_dir_unlink(upd);
- else
- error = xfs_imeta_sb_unlink(upd);
- if (error)
- return error;
-
- /*
- * Metadata files require explicit resource cleanup. In other words,
- * the inactivation system will not touch these files, so we must free
- * the ondisk inode by ourselves if warranted.
- */
- if (VFS_I(upd->ip)->i_nlink > 0)
- return 0;
-
- return xfs_imeta_ifree(upd->tp, upd->ip);
-}
-
/*
* Link the metadata directory given by @path to the inode @upd->ip.
* The path (up to the final component) must already exist, but the final