xfs: adapt the orphanage code to handle parent pointers

Adapt the orphanage's adoption code to update the child file's parent
pointers as part of the reparenting process.  Also ensure that the child
has an attr fork to receive the parent pointer update, since the runtime
code assumes one exists.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Darrick J. Wong 2024-04-22 09:48:17 -07:00
parent a26dc21309
commit 7be3d20bbe
3 changed files with 43 additions and 0 deletions

View File

@ -19,6 +19,8 @@
#include "xfs_icache.h" #include "xfs_icache.h"
#include "xfs_bmap.h" #include "xfs_bmap.h"
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_parent.h"
#include "xfs_attr_sf.h"
#include "scrub/scrub.h" #include "scrub/scrub.h"
#include "scrub/common.h" #include "scrub/common.h"
#include "scrub/repair.h" #include "scrub/repair.h"
@ -330,6 +332,8 @@ xrep_adoption_trans_alloc(
if (S_ISDIR(VFS_I(sc->ip)->i_mode)) if (S_ISDIR(VFS_I(sc->ip)->i_mode))
child_blkres = xfs_rename_space_res(mp, 0, false, child_blkres = xfs_rename_space_res(mp, 0, false,
xfs_name_dotdot.len, false); xfs_name_dotdot.len, false);
if (xfs_has_parent(mp))
child_blkres += XFS_ADDAFORK_SPACE_RES(mp);
adopt->child_blkres = child_blkres; adopt->child_blkres = child_blkres;
/* /*
@ -503,6 +507,19 @@ xrep_adoption_zap_dcache(
dput(d_orphanage); dput(d_orphanage);
} }
/*
* If we have to add an attr fork ahead of a parent pointer update, how much
* space should we ask for?
*/
static inline int
xrep_adoption_attr_sizeof(
const struct xrep_adoption *adopt)
{
return sizeof(struct xfs_attr_sf_hdr) +
xfs_attr_sf_entsize_byname(sizeof(struct xfs_parent_rec),
adopt->xname->len);
}
/* /*
* Move the current file to the orphanage under the computed name. * Move the current file to the orphanage under the computed name.
* *
@ -524,6 +541,19 @@ xrep_adoption_move(
if (error) if (error)
return error; return error;
/*
* If this filesystem has parent pointers, ensure that the file being
* moved to the orphanage has an attribute fork. This is required
* because the parent pointer code does not itself add attr forks.
*/
if (!xfs_inode_has_attr_fork(sc->ip) && xfs_has_parent(sc->mp)) {
int sf_size = xrep_adoption_attr_sizeof(adopt);
error = xfs_bmap_add_attrfork(sc->tp, sc->ip, sf_size, true);
if (error)
return error;
}
/* Create the new name in the orphanage. */ /* Create the new name in the orphanage. */
error = xfs_dir_createname(sc->tp, sc->orphanage, adopt->xname, error = xfs_dir_createname(sc->tp, sc->orphanage, adopt->xname,
sc->ip->i_ino, adopt->orphanage_blkres); sc->ip->i_ino, adopt->orphanage_blkres);
@ -548,6 +578,14 @@ xrep_adoption_move(
return error; return error;
} }
/* Add a parent pointer from the file back to the lost+found. */
if (xfs_has_parent(sc->mp)) {
error = xfs_parent_addname(sc->tp, &adopt->ppargs,
sc->orphanage, adopt->xname, sc->ip);
if (error)
return error;
}
/* /*
* Notify dirent hooks that we moved the file to /lost+found, and * Notify dirent hooks that we moved the file to /lost+found, and
* finish all the deferred work so that we know the adoption is fully * finish all the deferred work so that we know the adoption is fully

View File

@ -54,6 +54,9 @@ struct xrep_adoption {
/* Name used for the adoption. */ /* Name used for the adoption. */
struct xfs_name *xname; struct xfs_name *xname;
/* Parent pointer context tracking */
struct xfs_parent_args ppargs;
/* Block reservations for orphanage and child (if directory). */ /* Block reservations for orphanage and child (if directory). */
unsigned int orphanage_blkres; unsigned int orphanage_blkres;
unsigned int child_blkres; unsigned int child_blkres;

View File

@ -19,6 +19,8 @@
#include "xfs_rmap.h" #include "xfs_rmap.h"
#include "xfs_exchrange.h" #include "xfs_exchrange.h"
#include "xfs_exchmaps.h" #include "xfs_exchmaps.h"
#include "xfs_dir2.h"
#include "xfs_parent.h"
#include "scrub/scrub.h" #include "scrub/scrub.h"
#include "scrub/common.h" #include "scrub/common.h"
#include "scrub/trace.h" #include "scrub/trace.h"