summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2024-04-22 09:48:17 -0700
committerDarrick J. Wong <djwong@kernel.org>2024-04-23 16:55:15 -0700
commit7be3d20bbeda6602d6c5f67ec2b8f189a07ea0e3 (patch)
tree68e69ffeb83271236ec36e5f4b2402ac160a583d /fs
parenta26dc21309af68623b82b4e366cbbeb5a85ce65b (diff)
downloadlinux-stable-7be3d20bbeda6602d6c5f67ec2b8f189a07ea0e3.tar.gz
linux-stable-7be3d20bbeda6602d6c5f67ec2b8f189a07ea0e3.tar.bz2
linux-stable-7be3d20bbeda6602d6c5f67ec2b8f189a07ea0e3.zip
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/scrub/orphanage.c38
-rw-r--r--fs/xfs/scrub/orphanage.h3
-rw-r--r--fs/xfs/scrub/scrub.c2
3 files changed, 43 insertions, 0 deletions
diff --git a/fs/xfs/scrub/orphanage.c b/fs/xfs/scrub/orphanage.c
index 94bcc2799188..b2f905924d0d 100644
--- a/fs/xfs/scrub/orphanage.c
+++ b/fs/xfs/scrub/orphanage.c
@@ -19,6 +19,8 @@
#include "xfs_icache.h"
#include "xfs_bmap.h"
#include "xfs_bmap_btree.h"
+#include "xfs_parent.h"
+#include "xfs_attr_sf.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/repair.h"
@@ -330,6 +332,8 @@ xrep_adoption_trans_alloc(
if (S_ISDIR(VFS_I(sc->ip)->i_mode))
child_blkres = xfs_rename_space_res(mp, 0, false,
xfs_name_dotdot.len, false);
+ if (xfs_has_parent(mp))
+ child_blkres += XFS_ADDAFORK_SPACE_RES(mp);
adopt->child_blkres = child_blkres;
/*
@@ -504,6 +508,19 @@ xrep_adoption_zap_dcache(
}
/*
+ * 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.
*
* Returns with a dirty transaction so that the caller can handle any other
@@ -524,6 +541,19 @@ xrep_adoption_move(
if (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. */
error = xfs_dir_createname(sc->tp, sc->orphanage, adopt->xname,
sc->ip->i_ino, adopt->orphanage_blkres);
@@ -548,6 +578,14 @@ xrep_adoption_move(
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
* finish all the deferred work so that we know the adoption is fully
diff --git a/fs/xfs/scrub/orphanage.h b/fs/xfs/scrub/orphanage.h
index 319179ab788d..beb6b686784e 100644
--- a/fs/xfs/scrub/orphanage.h
+++ b/fs/xfs/scrub/orphanage.h
@@ -54,6 +54,9 @@ struct xrep_adoption {
/* Name used for the adoption. */
struct xfs_name *xname;
+ /* Parent pointer context tracking */
+ struct xfs_parent_args ppargs;
+
/* Block reservations for orphanage and child (if directory). */
unsigned int orphanage_blkres;
unsigned int child_blkres;
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index ebb06838c31b..7b1f1abdc7a9 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -19,6 +19,8 @@
#include "xfs_rmap.h"
#include "xfs_exchrange.h"
#include "xfs_exchmaps.h"
+#include "xfs_dir2.h"
+#include "xfs_parent.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"