From: Dave Chinner <dchinner@xxxxxxxxxx> [bfoster: rebase, use VFS inode generation] [achender: rebased, changed __unint32_t to xfs_dir2_dataptr_t implemented xfs_attr_remove_parent] Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> Signed-off-by: Allison Henderson <allison.henderson@xxxxxxxxxx> --- :100644 100644 b489efb... 75f22c0... M fs/xfs/libxfs/xfs_attr.c :100644 100644 0707336... ca695c4... M fs/xfs/libxfs/xfs_parent.c :100644 100644 07abcff... baaca90... M fs/xfs/xfs_attr.h :100644 100644 46a4d3b... 7718481... M fs/xfs/xfs_inode.c :100644 100644 010a13a... a047f0f... M fs/xfs/xfs_qm.c :100644 100644 2975a82... 9976369... M fs/xfs/xfs_qm.h fs/xfs/libxfs/xfs_attr.c | 15 +++++++++++++++ fs/xfs/libxfs/xfs_parent.c | 22 ++++++++++++++++++++++ fs/xfs/xfs_attr.h | 7 +++++++ fs/xfs/xfs_inode.c | 10 +++++++++- fs/xfs/xfs_qm.c | 2 +- fs/xfs/xfs_qm.h | 1 + 6 files changed, 55 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index b489efb..75f22c0 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -42,6 +42,7 @@ #include "xfs_quota.h" #include "xfs_trans_space.h" #include "xfs_trace.h" +#include "xfs_qm.h" /* * xfs_attr.c @@ -571,6 +572,20 @@ xfs_attr_set_defered( return 0; } +int +xfs_attr_remove_parent( + struct xfs_trans *tp, + struct xfs_inode *dp, + struct xfs_parent_name_rec *rec, + int reclen, + struct xfs_defer_ops *dfops, + xfs_fsblock_t *firstblock) +{ + int flags = ATTR_PARENT; + + return xfs_attr_remove_defered(dp, dfops, (char *) rec, reclen, flags); +} + /* * Generic handler routine to remove a name from an attribute list. * Transitions attribute list from Btree to shortform as necessary. diff --git a/fs/xfs/libxfs/xfs_parent.c b/fs/xfs/libxfs/xfs_parent.c index 0707336..ca695c4 100644 --- a/fs/xfs/libxfs/xfs_parent.c +++ b/fs/xfs/libxfs/xfs_parent.c @@ -139,3 +139,25 @@ xfs_parent_add( return xfs_parent_add_nrec(tp, child, &nrec, dfops, firstblock); } + +/* + * Remove a parent record from a child inode. + */ +int +xfs_parent_remove( + struct xfs_trans *tp, + struct xfs_inode *parent, + struct xfs_inode *child, + xfs_dir2_dataptr_t diroffset, + struct xfs_defer_ops *dfops, + xfs_fsblock_t *firstblock) +{ + struct xfs_parent_name_rec rec; + + rec.p_ino = cpu_to_be64(parent->i_ino); + rec.p_gen = cpu_to_be32(VFS_I(parent)->i_generation); + rec.p_diroffset = cpu_to_be32(diroffset); + + return xfs_attr_remove_parent(tp, child, &rec, sizeof(rec), + dfops, firstblock); +} diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index 07abcff..baaca90 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h @@ -208,4 +208,11 @@ int xfs_attr_set_parent(struct xfs_trans *tp, struct xfs_inode *ip, const char *value, int valuelen, struct xfs_defer_ops *dfops, xfs_fsblock_t *firstblock); +int xfs_parent_remove(struct xfs_trans *tp, struct xfs_inode *parent, + struct xfs_inode *child, xfs_dir2_dataptr_t diroffset, + struct xfs_defer_ops *dfops, xfs_fsblock_t *firstblock); +int xfs_attr_remove_parent(struct xfs_trans *tp, struct xfs_inode *ip, + struct xfs_parent_name_rec *rec, int reclen, + struct xfs_defer_ops *dfops, xfs_fsblock_t *firstblock); + #endif /* __XFS_ATTR_H__ */ diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 46a4d3b..7718481 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2612,6 +2612,7 @@ xfs_remove( struct xfs_defer_ops dfops; xfs_fsblock_t first_block; uint resblks; + uint32_t dir_offset; trace_xfs_remove(dp, name); @@ -2692,12 +2693,19 @@ xfs_remove( xfs_defer_init(&dfops, &first_block); error = xfs_dir_removename(tp, dp, name, ip->i_ino, &first_block, - &dfops, resblks, NULL); + &dfops, resblks, &dir_offset); if (error) { ASSERT(error != -ENOENT); goto out_bmap_cancel; } + if (xfs_sb_version_hasparent(&mp->m_sb)) { + error = xfs_parent_remove(tp, dp, ip, dir_offset, &dfops, + &first_block); + if (error) + goto out_bmap_cancel; + } + /* * If this is a synchronous mount, make sure that the * remove transaction goes to disk before returning to diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 010a13a..a047f0f 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -307,7 +307,7 @@ xfs_qm_dqattach_one( return 0; } -static bool +bool xfs_qm_need_dqattach( struct xfs_inode *ip) { diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 2975a82..9976369 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -176,6 +176,7 @@ extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint, struct qc_dqblk *); extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint); extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint); +extern bool xfs_qm_need_dqattach(struct xfs_inode *ip); static inline struct xfs_def_quota * xfs_get_defquota(struct xfs_dquot *dqp, struct xfs_quotainfo *qi) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html