diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 4 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.h | 6 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 112 |
3 files changed, 39 insertions, 83 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 9798643feb3b..a3d2e7713068 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -141,7 +141,7 @@ restart: | |||
141 | return last_error; | 141 | return last_error; |
142 | } | 142 | } |
143 | 143 | ||
144 | STATIC int | 144 | int |
145 | xfs_inode_ag_iterator( | 145 | xfs_inode_ag_iterator( |
146 | struct xfs_mount *mp, | 146 | struct xfs_mount *mp, |
147 | int (*execute)(struct xfs_inode *ip, | 147 | int (*execute)(struct xfs_inode *ip, |
@@ -167,7 +167,7 @@ xfs_inode_ag_iterator( | |||
167 | } | 167 | } |
168 | 168 | ||
169 | /* must be called with pag_ici_lock held and releases it */ | 169 | /* must be called with pag_ici_lock held and releases it */ |
170 | STATIC int | 170 | int |
171 | xfs_sync_inode_valid( | 171 | xfs_sync_inode_valid( |
172 | struct xfs_inode *ip, | 172 | struct xfs_inode *ip, |
173 | struct xfs_perag *pag) | 173 | struct xfs_perag *pag) |
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index d7b2b5f1c387..9bb1253a4023 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
@@ -54,4 +54,10 @@ void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); | |||
54 | void xfs_inode_clear_reclaim_tag(struct xfs_inode *ip); | 54 | void xfs_inode_clear_reclaim_tag(struct xfs_inode *ip); |
55 | void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag, | 55 | void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag, |
56 | struct xfs_inode *ip); | 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 | #endif | 63 | #endif |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index c7b66f6506ce..7126f855e14b 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -847,105 +847,55 @@ xfs_qm_export_flags( | |||
847 | } | 847 | } |
848 | 848 | ||
849 | 849 | ||
850 | /* | 850 | STATIC int |
851 | * Release all the dquots on the inodes in an AG. | 851 | xfs_dqrele_inode( |
852 | */ | 852 | struct xfs_inode *ip, |
853 | STATIC void | 853 | struct xfs_perag *pag, |
854 | xfs_qm_dqrele_inodes_ag( | 854 | int flags) |
855 | xfs_mount_t *mp, | ||
856 | int ag, | ||
857 | uint flags) | ||
858 | { | 855 | { |
859 | xfs_inode_t *ip = NULL; | 856 | int error; |
860 | xfs_perag_t *pag = &mp->m_perag[ag]; | ||
861 | int first_index = 0; | ||
862 | int nr_found; | ||
863 | |||
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 | 857 | ||
899 | /* | 858 | /* skip quota inodes */ |
900 | * If we can't get a reference on the inode, it must be | 859 | if (ip == XFS_QI_UQIP(ip->i_mount) || ip == XFS_QI_GQIP(ip->i_mount)) { |
901 | * in reclaim. Leave it for the reclaim code to flush. | 860 | ASSERT(ip->i_udquot == NULL); |
902 | */ | 861 | ASSERT(ip->i_gdquot == NULL); |
903 | if (!igrab(VFS_I(ip))) { | ||
904 | read_unlock(&pag->pag_ici_lock); | ||
905 | continue; | ||
906 | } | ||
907 | read_unlock(&pag->pag_ici_lock); | 862 | read_unlock(&pag->pag_ici_lock); |
863 | return 0; | ||
864 | } | ||
908 | 865 | ||
909 | /* avoid new inodes though we shouldn't find any here */ | 866 | error = xfs_sync_inode_valid(ip, pag); |
910 | if (xfs_iflags_test(ip, XFS_INEW)) { | 867 | if (error) |
911 | IRELE(ip); | 868 | return error; |
912 | continue; | ||
913 | } | ||
914 | 869 | ||
915 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 870 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
916 | if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { | 871 | if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { |
917 | xfs_qm_dqrele(ip->i_udquot); | 872 | xfs_qm_dqrele(ip->i_udquot); |
918 | ip->i_udquot = NULL; | 873 | ip->i_udquot = NULL; |
919 | } | 874 | } |
920 | if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && | 875 | if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) { |
921 | ip->i_gdquot) { | 876 | xfs_qm_dqrele(ip->i_gdquot); |
922 | xfs_qm_dqrele(ip->i_gdquot); | 877 | ip->i_gdquot = NULL; |
923 | ip->i_gdquot = NULL; | 878 | } |
924 | } | 879 | xfs_iput(ip, XFS_ILOCK_EXCL); |
925 | xfs_iput(ip, XFS_ILOCK_EXCL); | 880 | IRELE(ip); |
926 | 881 | ||
927 | } while (nr_found); | 882 | return 0; |
928 | } | 883 | } |
929 | 884 | ||
885 | |||
930 | /* | 886 | /* |
931 | * Go thru all the inodes in the file system, releasing their dquots. | 887 | * Go thru all the inodes in the file system, releasing their dquots. |
888 | * | ||
932 | * Note that the mount structure gets modified to indicate that quotas are off | 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 | 890 | * AFTER this, in the case of quotaoff. |
934 | * xfs_rootumount. | ||
935 | */ | 891 | */ |
936 | void | 892 | void |
937 | xfs_qm_dqrele_all_inodes( | 893 | xfs_qm_dqrele_all_inodes( |
938 | struct xfs_mount *mp, | 894 | struct xfs_mount *mp, |
939 | uint flags) | 895 | uint flags) |
940 | { | 896 | { |
941 | int i; | ||
942 | |||
943 | ASSERT(mp->m_quotainfo); | 897 | ASSERT(mp->m_quotainfo); |
944 | for (i = 0; i < mp->m_sb.sb_agcount; i++) { | 898 | xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG); |
945 | if (!mp->m_perag[i].pag_ici_init) | ||
946 | continue; | ||
947 | xfs_qm_dqrele_inodes_ag(mp, i, flags); | ||
948 | } | ||
949 | } | 899 | } |
950 | 900 | ||
951 | /*------------------------------------------------------------------------*/ | 901 | /*------------------------------------------------------------------------*/ |