xfs: use generic inode iterator in xfs_qm_dqrele_all_inodes

Use xfs_inode_ag_iterator instead of opencoding the inode walk in the
quota code. Mark xfs_inode_ag_iterator and xfs_sync_inode_valid non-static
to allow using them from the quota code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Reviewed-by: Eric Sandeen <sandeen@sandeen.net>

authored by

Christoph Hellwig and committed by
Christoph Hellwig
fe588ed3 75f3cb13

+39 -83
+2 -2
fs/xfs/linux-2.6/xfs_sync.c
··· 141 141 return last_error; 142 142 } 143 143 144 - STATIC int 144 + int 145 145 xfs_inode_ag_iterator( 146 146 struct xfs_mount *mp, 147 147 int (*execute)(struct xfs_inode *ip, ··· 167 167 } 168 168 169 169 /* must be called with pag_ici_lock held and releases it */ 170 - STATIC int 170 + int 171 171 xfs_sync_inode_valid( 172 172 struct xfs_inode *ip, 173 173 struct xfs_perag *pag)
+6
fs/xfs/linux-2.6/xfs_sync.h
··· 54 54 void xfs_inode_clear_reclaim_tag(struct xfs_inode *ip); 55 55 void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag, 56 56 struct xfs_inode *ip); 57 + 58 + int xfs_sync_inode_valid(struct xfs_inode *ip, struct xfs_perag *pag); 59 + int xfs_inode_ag_iterator(struct xfs_mount *mp, 60 + int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), 61 + int flags, int tag); 62 + 57 63 #endif
+31 -81
fs/xfs/quota/xfs_qm_syscalls.c
··· 847 847 } 848 848 849 849 850 - /* 851 - * Release all the dquots on the inodes in an AG. 852 - */ 853 - STATIC void 854 - xfs_qm_dqrele_inodes_ag( 855 - xfs_mount_t *mp, 856 - int ag, 857 - uint flags) 850 + STATIC int 851 + xfs_dqrele_inode( 852 + struct xfs_inode *ip, 853 + struct xfs_perag *pag, 854 + int flags) 858 855 { 859 - xfs_inode_t *ip = NULL; 860 - xfs_perag_t *pag = &mp->m_perag[ag]; 861 - int first_index = 0; 862 - int nr_found; 856 + int error; 863 857 864 - do { 865 - /* 866 - * use a gang lookup to find the next inode in the tree 867 - * as the tree is sparse and a gang lookup walks to find 868 - * the number of objects requested. 869 - */ 870 - read_lock(&pag->pag_ici_lock); 871 - nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, 872 - (void**)&ip, first_index, 1); 873 - 874 - if (!nr_found) { 875 - read_unlock(&pag->pag_ici_lock); 876 - break; 877 - } 878 - 879 - /* 880 - * Update the index for the next lookup. Catch overflows 881 - * into the next AG range which can occur if we have inodes 882 - * in the last block of the AG and we are currently 883 - * pointing to the last inode. 884 - */ 885 - first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1); 886 - if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino)) { 887 - read_unlock(&pag->pag_ici_lock); 888 - break; 889 - } 890 - 891 - /* skip quota inodes */ 892 - if (ip == XFS_QI_UQIP(mp) || ip == XFS_QI_GQIP(mp)) { 893 - ASSERT(ip->i_udquot == NULL); 894 - ASSERT(ip->i_gdquot == NULL); 895 - read_unlock(&pag->pag_ici_lock); 896 - continue; 897 - } 898 - 899 - /* 900 - * If we can't get a reference on the inode, it must be 901 - * in reclaim. Leave it for the reclaim code to flush. 902 - */ 903 - if (!igrab(VFS_I(ip))) { 904 - read_unlock(&pag->pag_ici_lock); 905 - continue; 906 - } 858 + /* skip quota inodes */ 859 + if (ip == XFS_QI_UQIP(ip->i_mount) || ip == XFS_QI_GQIP(ip->i_mount)) { 860 + ASSERT(ip->i_udquot == NULL); 861 + ASSERT(ip->i_gdquot == NULL); 907 862 read_unlock(&pag->pag_ici_lock); 863 + return 0; 864 + } 908 865 909 - /* avoid new inodes though we shouldn't find any here */ 910 - if (xfs_iflags_test(ip, XFS_INEW)) { 911 - IRELE(ip); 912 - continue; 913 - } 866 + error = xfs_sync_inode_valid(ip, pag); 867 + if (error) 868 + return error; 914 869 915 - xfs_ilock(ip, XFS_ILOCK_EXCL); 916 - if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { 917 - xfs_qm_dqrele(ip->i_udquot); 918 - ip->i_udquot = NULL; 919 - } 920 - if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && 921 - ip->i_gdquot) { 922 - xfs_qm_dqrele(ip->i_gdquot); 923 - ip->i_gdquot = NULL; 924 - } 925 - xfs_iput(ip, XFS_ILOCK_EXCL); 870 + xfs_ilock(ip, XFS_ILOCK_EXCL); 871 + if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { 872 + xfs_qm_dqrele(ip->i_udquot); 873 + ip->i_udquot = NULL; 874 + } 875 + if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) { 876 + xfs_qm_dqrele(ip->i_gdquot); 877 + ip->i_gdquot = NULL; 878 + } 879 + xfs_iput(ip, XFS_ILOCK_EXCL); 880 + IRELE(ip); 926 881 927 - } while (nr_found); 882 + return 0; 928 883 } 884 + 929 885 930 886 /* 931 887 * Go thru all the inodes in the file system, releasing their dquots. 888 + * 932 889 * Note that the mount structure gets modified to indicate that quotas are off 933 - * AFTER this, in the case of quotaoff. This also gets called from 934 - * xfs_rootumount. 890 + * AFTER this, in the case of quotaoff. 935 891 */ 936 892 void 937 893 xfs_qm_dqrele_all_inodes( 938 894 struct xfs_mount *mp, 939 895 uint flags) 940 896 { 941 - int i; 942 - 943 897 ASSERT(mp->m_quotainfo); 944 - for (i = 0; i < mp->m_sb.sb_agcount; i++) { 945 - if (!mp->m_perag[i].pag_ici_init) 946 - continue; 947 - xfs_qm_dqrele_inodes_ag(mp, i, flags); 948 - } 898 + xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG); 949 899 } 950 900 951 901 /*------------------------------------------------------------------------*/