Message ID | 20220922054458.40826-17-allison.henderson@oracle.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Parent Pointers | expand |
On Wed, Sep 21, 2022 at 10:44:48PM -0700, allison.henderson@oracle.com wrote: > From: Allison Henderson <allison.henderson@oracle.com> > > This patch modifies xfs_symlink to add a parent pointer to the inode. > > Signed-off-by: Allison Henderson <allison.henderson@oracle.com> Ooh, a new patch. > --- > fs/xfs/xfs_symlink.c | 31 +++++++++++++++++++++++++++---- > 1 file changed, 27 insertions(+), 4 deletions(-) > > diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c > index 27a7d7c57015..14079367335b 100644 > --- a/fs/xfs/xfs_symlink.c > +++ b/fs/xfs/xfs_symlink.c > @@ -23,6 +23,8 @@ > #include "xfs_trans.h" > #include "xfs_ialloc.h" > #include "xfs_error.h" > +#include "xfs_parent.h" > +#include "xfs_defer.h" > > /* ----- Kernel only functions below ----- */ > int > @@ -172,6 +174,8 @@ xfs_symlink( > struct xfs_dquot *pdqp = NULL; > uint resblks; > xfs_ino_t ino; > + xfs_dir2_dataptr_t diroffset; > + struct xfs_parent_defer *parent = NULL; > > *ipp = NULL; > > @@ -179,10 +183,10 @@ xfs_symlink( > > if (xfs_is_shutdown(mp)) > return -EIO; > - > /* > * Check component lengths of the target path name. > */ > + > pathlen = strlen(target_path); > if (pathlen >= XFS_SYMLINK_MAXLEN) /* total string too long */ > return -ENAMETOOLONG; > @@ -204,12 +208,18 @@ xfs_symlink( > * The symlink will fit into the inode data fork? > * There can't be any attributes so we get the whole variable part. > */ > - if (pathlen <= XFS_LITINO(mp)) > + if (pathlen <= XFS_LITINO(mp) && !xfs_has_parent(mp)) > fs_blocks = 0; > else > fs_blocks = xfs_symlink_blocks(mp, pathlen); > resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks); Same comment as the last two patches: Please update xfs_symlink_space_res to handle the free space that might be needed to expand the xattr structure ondisk: unsigned int xfs_symlink_space_res( struct xfs_mount *mp, unsigned int namelen, unsigned int fsblocks) { unsigned int ret; ret = XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp, namelen) + fsblocks; if (xfs_has_parent(mp)) ret += xfs_pptr_calc_space_res(mp, namelen); return ret; } Everything else in here otherwise looks good to me. --D > > + if (xfs_has_parent(mp)) { > + error = xfs_parent_init(mp, &parent); > + if (error) > + return error; > + } > + > error = xfs_trans_alloc_icreate(mp, &M_RES(mp)->tr_symlink, udqp, gdqp, > pdqp, resblks, &tp); > if (error) > @@ -233,7 +243,7 @@ xfs_symlink( > if (!error) > error = xfs_init_new_inode(mnt_userns, tp, dp, ino, > S_IFLNK | (mode & ~S_IFMT), 1, 0, prid, > - false, &ip); > + xfs_has_parent(mp), &ip); > if (error) > goto out_trans_cancel; > > @@ -315,12 +325,20 @@ xfs_symlink( > * Create the directory entry for the symlink. > */ > error = xfs_dir_createname(tp, dp, link_name, > - ip->i_ino, resblks, NULL); > + ip->i_ino, resblks, &diroffset); > if (error) > goto out_trans_cancel; > xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); > xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); > > + if (parent) { > + error = xfs_parent_defer_add(tp, parent, dp, link_name, > + diroffset, ip); > + if (error) > + goto out_trans_cancel; > + } > + > + > /* > * If this is a synchronous mount, make sure that the > * symlink transaction goes to disk before returning to > @@ -344,6 +362,8 @@ xfs_symlink( > out_trans_cancel: > xfs_trans_cancel(tp); > out_release_inode: > + xfs_defer_cancel(tp); > + > /* > * Wait until after the current transaction is aborted to finish the > * setup of the inode and release the inode. This prevents recursive > @@ -362,6 +382,9 @@ xfs_symlink( > xfs_iunlock(dp, XFS_ILOCK_EXCL); > if (ip) > xfs_iunlock(ip, XFS_ILOCK_EXCL); > + if (parent) > + xfs_parent_cancel(mp, parent); > + > return error; > } > > -- > 2.25.1 >
On Fri, 2022-09-23 at 14:16 -0700, Darrick J. Wong wrote: > On Wed, Sep 21, 2022 at 10:44:48PM -0700, > allison.henderson@oracle.com wrote: > > From: Allison Henderson <allison.henderson@oracle.com> > > > > This patch modifies xfs_symlink to add a parent pointer to the > > inode. > > > > Signed-off-by: Allison Henderson <allison.henderson@oracle.com> > > Ooh, a new patch. > > > --- > > fs/xfs/xfs_symlink.c | 31 +++++++++++++++++++++++++++---- > > 1 file changed, 27 insertions(+), 4 deletions(-) > > > > diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c > > index 27a7d7c57015..14079367335b 100644 > > --- a/fs/xfs/xfs_symlink.c > > +++ b/fs/xfs/xfs_symlink.c > > @@ -23,6 +23,8 @@ > > #include "xfs_trans.h" > > #include "xfs_ialloc.h" > > #include "xfs_error.h" > > +#include "xfs_parent.h" > > +#include "xfs_defer.h" > > > > /* ----- Kernel only functions below ----- */ > > int > > @@ -172,6 +174,8 @@ xfs_symlink( > > struct xfs_dquot *pdqp = NULL; > > uint resblks; > > xfs_ino_t ino; > > + xfs_dir2_dataptr_t diroffset; > > + struct xfs_parent_defer *parent = NULL; > > > > *ipp = NULL; > > > > @@ -179,10 +183,10 @@ xfs_symlink( > > > > if (xfs_is_shutdown(mp)) > > return -EIO; > > - > > /* > > * Check component lengths of the target path name. > > */ > > + > > pathlen = strlen(target_path); > > if (pathlen >= XFS_SYMLINK_MAXLEN) /* total string too > > long */ > > return -ENAMETOOLONG; > > @@ -204,12 +208,18 @@ xfs_symlink( > > * The symlink will fit into the inode data fork? > > * There can't be any attributes so we get the whole > > variable part. > > */ > > - if (pathlen <= XFS_LITINO(mp)) > > + if (pathlen <= XFS_LITINO(mp) && !xfs_has_parent(mp)) > > fs_blocks = 0; > > else > > fs_blocks = xfs_symlink_blocks(mp, pathlen); > > resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, > > fs_blocks); > > Same comment as the last two patches: Please update > xfs_symlink_space_res to handle the free space that might be needed > to > expand the xattr structure ondisk: > > unsigned int > xfs_symlink_space_res( > struct xfs_mount *mp, > unsigned int namelen, > unsigned int fsblocks) > { > unsigned int ret; > > ret = XFS_IALLOC_SPACE_RES(mp) + > XFS_DIRENTER_SPACE_RES(mp, namelen) + > fsblocks; > > if (xfs_has_parent(mp)) > ret += xfs_pptr_calc_space_res(mp, namelen); > > return ret; > } > > Everything else in here otherwise looks good to me. Alrighty, will add. Thanks! > > --D > > > > > + if (xfs_has_parent(mp)) { > > + error = xfs_parent_init(mp, &parent); > > + if (error) > > + return error; > > + } > > + > > error = xfs_trans_alloc_icreate(mp, &M_RES(mp)->tr_symlink, > > udqp, gdqp, > > pdqp, resblks, &tp); > > if (error) > > @@ -233,7 +243,7 @@ xfs_symlink( > > if (!error) > > error = xfs_init_new_inode(mnt_userns, tp, dp, ino, > > S_IFLNK | (mode & ~S_IFMT), 1, 0, > > prid, > > - false, &ip); > > + xfs_has_parent(mp), &ip); > > if (error) > > goto out_trans_cancel; > > > > @@ -315,12 +325,20 @@ xfs_symlink( > > * Create the directory entry for the symlink. > > */ > > error = xfs_dir_createname(tp, dp, link_name, > > - ip->i_ino, resblks, NULL); > > + ip->i_ino, resblks, &diroffset); > > if (error) > > goto out_trans_cancel; > > xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | > > XFS_ICHGTIME_CHG); > > xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); > > > > + if (parent) { > > + error = xfs_parent_defer_add(tp, parent, dp, > > link_name, > > + diroffset, ip); > > + if (error) > > + goto out_trans_cancel; > > + } > > + > > + > > /* > > * If this is a synchronous mount, make sure that the > > * symlink transaction goes to disk before returning to > > @@ -344,6 +362,8 @@ xfs_symlink( > > out_trans_cancel: > > xfs_trans_cancel(tp); > > out_release_inode: > > + xfs_defer_cancel(tp); > > + > > /* > > * Wait until after the current transaction is aborted to > > finish the > > * setup of the inode and release the inode. This prevents > > recursive > > @@ -362,6 +382,9 @@ xfs_symlink( > > xfs_iunlock(dp, XFS_ILOCK_EXCL); > > if (ip) > > xfs_iunlock(ip, XFS_ILOCK_EXCL); > > + if (parent) > > + xfs_parent_cancel(mp, parent); > > + > > return error; > > } > > > > -- > > 2.25.1 > >
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 27a7d7c57015..14079367335b 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -23,6 +23,8 @@ #include "xfs_trans.h" #include "xfs_ialloc.h" #include "xfs_error.h" +#include "xfs_parent.h" +#include "xfs_defer.h" /* ----- Kernel only functions below ----- */ int @@ -172,6 +174,8 @@ xfs_symlink( struct xfs_dquot *pdqp = NULL; uint resblks; xfs_ino_t ino; + xfs_dir2_dataptr_t diroffset; + struct xfs_parent_defer *parent = NULL; *ipp = NULL; @@ -179,10 +183,10 @@ xfs_symlink( if (xfs_is_shutdown(mp)) return -EIO; - /* * Check component lengths of the target path name. */ + pathlen = strlen(target_path); if (pathlen >= XFS_SYMLINK_MAXLEN) /* total string too long */ return -ENAMETOOLONG; @@ -204,12 +208,18 @@ xfs_symlink( * The symlink will fit into the inode data fork? * There can't be any attributes so we get the whole variable part. */ - if (pathlen <= XFS_LITINO(mp)) + if (pathlen <= XFS_LITINO(mp) && !xfs_has_parent(mp)) fs_blocks = 0; else fs_blocks = xfs_symlink_blocks(mp, pathlen); resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks); + if (xfs_has_parent(mp)) { + error = xfs_parent_init(mp, &parent); + if (error) + return error; + } + error = xfs_trans_alloc_icreate(mp, &M_RES(mp)->tr_symlink, udqp, gdqp, pdqp, resblks, &tp); if (error) @@ -233,7 +243,7 @@ xfs_symlink( if (!error) error = xfs_init_new_inode(mnt_userns, tp, dp, ino, S_IFLNK | (mode & ~S_IFMT), 1, 0, prid, - false, &ip); + xfs_has_parent(mp), &ip); if (error) goto out_trans_cancel; @@ -315,12 +325,20 @@ xfs_symlink( * Create the directory entry for the symlink. */ error = xfs_dir_createname(tp, dp, link_name, - ip->i_ino, resblks, NULL); + ip->i_ino, resblks, &diroffset); if (error) goto out_trans_cancel; xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); + if (parent) { + error = xfs_parent_defer_add(tp, parent, dp, link_name, + diroffset, ip); + if (error) + goto out_trans_cancel; + } + + /* * If this is a synchronous mount, make sure that the * symlink transaction goes to disk before returning to @@ -344,6 +362,8 @@ xfs_symlink( out_trans_cancel: xfs_trans_cancel(tp); out_release_inode: + xfs_defer_cancel(tp); + /* * Wait until after the current transaction is aborted to finish the * setup of the inode and release the inode. This prevents recursive @@ -362,6 +382,9 @@ xfs_symlink( xfs_iunlock(dp, XFS_ILOCK_EXCL); if (ip) xfs_iunlock(ip, XFS_ILOCK_EXCL); + if (parent) + xfs_parent_cancel(mp, parent); + return error; }