diff options
Diffstat (limited to 'fs/xfs/quota/xfs_qm_syscalls.c')
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 144 |
1 files changed, 84 insertions, 60 deletions
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 92b002f1805f..45e5849df238 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -26,25 +26,15 @@ | |||
26 | #include "xfs_trans.h" | 26 | #include "xfs_trans.h" |
27 | #include "xfs_sb.h" | 27 | #include "xfs_sb.h" |
28 | #include "xfs_ag.h" | 28 | #include "xfs_ag.h" |
29 | #include "xfs_dir2.h" | ||
30 | #include "xfs_alloc.h" | 29 | #include "xfs_alloc.h" |
31 | #include "xfs_dmapi.h" | ||
32 | #include "xfs_quota.h" | 30 | #include "xfs_quota.h" |
33 | #include "xfs_mount.h" | 31 | #include "xfs_mount.h" |
34 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
35 | #include "xfs_alloc_btree.h" | ||
36 | #include "xfs_ialloc_btree.h" | ||
37 | #include "xfs_dir2_sf.h" | ||
38 | #include "xfs_attr_sf.h" | ||
39 | #include "xfs_dinode.h" | ||
40 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
41 | #include "xfs_ialloc.h" | ||
42 | #include "xfs_itable.h" | 34 | #include "xfs_itable.h" |
43 | #include "xfs_bmap.h" | 35 | #include "xfs_bmap.h" |
44 | #include "xfs_btree.h" | ||
45 | #include "xfs_rtalloc.h" | 36 | #include "xfs_rtalloc.h" |
46 | #include "xfs_error.h" | 37 | #include "xfs_error.h" |
47 | #include "xfs_rw.h" | ||
48 | #include "xfs_attr.h" | 38 | #include "xfs_attr.h" |
49 | #include "xfs_buf_item.h" | 39 | #include "xfs_buf_item.h" |
50 | #include "xfs_utils.h" | 40 | #include "xfs_utils.h" |
@@ -248,40 +238,74 @@ out_unlock: | |||
248 | return error; | 238 | return error; |
249 | } | 239 | } |
250 | 240 | ||
241 | STATIC int | ||
242 | xfs_qm_scall_trunc_qfile( | ||
243 | struct xfs_mount *mp, | ||
244 | xfs_ino_t ino) | ||
245 | { | ||
246 | struct xfs_inode *ip; | ||
247 | struct xfs_trans *tp; | ||
248 | int error; | ||
249 | |||
250 | if (ino == NULLFSINO) | ||
251 | return 0; | ||
252 | |||
253 | error = xfs_iget(mp, NULL, ino, 0, 0, &ip); | ||
254 | if (error) | ||
255 | return error; | ||
256 | |||
257 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
258 | |||
259 | tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE); | ||
260 | error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, | ||
261 | XFS_TRANS_PERM_LOG_RES, | ||
262 | XFS_ITRUNCATE_LOG_COUNT); | ||
263 | if (error) { | ||
264 | xfs_trans_cancel(tp, 0); | ||
265 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
266 | goto out_put; | ||
267 | } | ||
268 | |||
269 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
270 | xfs_trans_ijoin(tp, ip); | ||
271 | |||
272 | error = xfs_itruncate_finish(&tp, ip, 0, XFS_DATA_FORK, 1); | ||
273 | if (error) { | ||
274 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | | ||
275 | XFS_TRANS_ABORT); | ||
276 | goto out_unlock; | ||
277 | } | ||
278 | |||
279 | xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | ||
280 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
281 | |||
282 | out_unlock: | ||
283 | xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
284 | out_put: | ||
285 | IRELE(ip); | ||
286 | return error; | ||
287 | } | ||
288 | |||
251 | int | 289 | int |
252 | xfs_qm_scall_trunc_qfiles( | 290 | xfs_qm_scall_trunc_qfiles( |
253 | xfs_mount_t *mp, | 291 | xfs_mount_t *mp, |
254 | uint flags) | 292 | uint flags) |
255 | { | 293 | { |
256 | int error = 0, error2 = 0; | 294 | int error = 0, error2 = 0; |
257 | xfs_inode_t *qip; | ||
258 | 295 | ||
259 | if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { | 296 | if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { |
260 | qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags); | 297 | qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags); |
261 | return XFS_ERROR(EINVAL); | 298 | return XFS_ERROR(EINVAL); |
262 | } | 299 | } |
263 | 300 | ||
264 | if ((flags & XFS_DQ_USER) && mp->m_sb.sb_uquotino != NULLFSINO) { | 301 | if (flags & XFS_DQ_USER) |
265 | error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip, 0); | 302 | error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino); |
266 | if (!error) { | 303 | if (flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) |
267 | error = xfs_truncate_file(mp, qip); | 304 | error2 = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino); |
268 | IRELE(qip); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) && | ||
273 | mp->m_sb.sb_gquotino != NULLFSINO) { | ||
274 | error2 = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); | ||
275 | if (!error2) { | ||
276 | error2 = xfs_truncate_file(mp, qip); | ||
277 | IRELE(qip); | ||
278 | } | ||
279 | } | ||
280 | 305 | ||
281 | return error ? error : error2; | 306 | return error ? error : error2; |
282 | } | 307 | } |
283 | 308 | ||
284 | |||
285 | /* | 309 | /* |
286 | * Switch on (a given) quota enforcement for a filesystem. This takes | 310 | * Switch on (a given) quota enforcement for a filesystem. This takes |
287 | * effect immediately. | 311 | * effect immediately. |
@@ -417,12 +441,12 @@ xfs_qm_scall_getqstat( | |||
417 | } | 441 | } |
418 | if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) { | 442 | if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) { |
419 | if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, | 443 | if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, |
420 | 0, 0, &uip, 0) == 0) | 444 | 0, 0, &uip) == 0) |
421 | tempuqip = B_TRUE; | 445 | tempuqip = B_TRUE; |
422 | } | 446 | } |
423 | if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) { | 447 | if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) { |
424 | if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, | 448 | if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, |
425 | 0, 0, &gip, 0) == 0) | 449 | 0, 0, &gip) == 0) |
426 | tempgqip = B_TRUE; | 450 | tempgqip = B_TRUE; |
427 | } | 451 | } |
428 | if (uip) { | 452 | if (uip) { |
@@ -786,9 +810,9 @@ xfs_qm_export_dquot( | |||
786 | } | 810 | } |
787 | 811 | ||
788 | #ifdef DEBUG | 812 | #ifdef DEBUG |
789 | if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == XFS_USER_QUOTA) || | 813 | if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == FS_USER_QUOTA) || |
790 | (XFS_IS_OQUOTA_ENFORCED(mp) && | 814 | (XFS_IS_OQUOTA_ENFORCED(mp) && |
791 | (dst->d_flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)))) && | 815 | (dst->d_flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)))) && |
792 | dst->d_id != 0) { | 816 | dst->d_id != 0) { |
793 | if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) && | 817 | if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) && |
794 | (dst->d_blk_softlimit > 0)) { | 818 | (dst->d_blk_softlimit > 0)) { |
@@ -809,17 +833,17 @@ xfs_qm_export_qtype_flags( | |||
809 | /* | 833 | /* |
810 | * Can't be more than one, or none. | 834 | * Can't be more than one, or none. |
811 | */ | 835 | */ |
812 | ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) != | 836 | ASSERT((flags & (FS_PROJ_QUOTA | FS_USER_QUOTA)) != |
813 | (XFS_PROJ_QUOTA | XFS_USER_QUOTA)); | 837 | (FS_PROJ_QUOTA | FS_USER_QUOTA)); |
814 | ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) != | 838 | ASSERT((flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)) != |
815 | (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)); | 839 | (FS_PROJ_QUOTA | FS_GROUP_QUOTA)); |
816 | ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) != | 840 | ASSERT((flags & (FS_USER_QUOTA | FS_GROUP_QUOTA)) != |
817 | (XFS_USER_QUOTA | XFS_GROUP_QUOTA)); | 841 | (FS_USER_QUOTA | FS_GROUP_QUOTA)); |
818 | ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0); | 842 | ASSERT((flags & (FS_PROJ_QUOTA|FS_USER_QUOTA|FS_GROUP_QUOTA)) != 0); |
819 | 843 | ||
820 | return (flags & XFS_DQ_USER) ? | 844 | return (flags & XFS_DQ_USER) ? |
821 | XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ? | 845 | FS_USER_QUOTA : (flags & XFS_DQ_PROJ) ? |
822 | XFS_PROJ_QUOTA : XFS_GROUP_QUOTA; | 846 | FS_PROJ_QUOTA : FS_GROUP_QUOTA; |
823 | } | 847 | } |
824 | 848 | ||
825 | STATIC uint | 849 | STATIC uint |
@@ -830,16 +854,16 @@ xfs_qm_export_flags( | |||
830 | 854 | ||
831 | uflags = 0; | 855 | uflags = 0; |
832 | if (flags & XFS_UQUOTA_ACCT) | 856 | if (flags & XFS_UQUOTA_ACCT) |
833 | uflags |= XFS_QUOTA_UDQ_ACCT; | 857 | uflags |= FS_QUOTA_UDQ_ACCT; |
834 | if (flags & XFS_PQUOTA_ACCT) | 858 | if (flags & XFS_PQUOTA_ACCT) |
835 | uflags |= XFS_QUOTA_PDQ_ACCT; | 859 | uflags |= FS_QUOTA_PDQ_ACCT; |
836 | if (flags & XFS_GQUOTA_ACCT) | 860 | if (flags & XFS_GQUOTA_ACCT) |
837 | uflags |= XFS_QUOTA_GDQ_ACCT; | 861 | uflags |= FS_QUOTA_GDQ_ACCT; |
838 | if (flags & XFS_UQUOTA_ENFD) | 862 | if (flags & XFS_UQUOTA_ENFD) |
839 | uflags |= XFS_QUOTA_UDQ_ENFD; | 863 | uflags |= FS_QUOTA_UDQ_ENFD; |
840 | if (flags & (XFS_OQUOTA_ENFD)) { | 864 | if (flags & (XFS_OQUOTA_ENFD)) { |
841 | uflags |= (flags & XFS_GQUOTA_ACCT) ? | 865 | uflags |= (flags & XFS_GQUOTA_ACCT) ? |
842 | XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD; | 866 | FS_QUOTA_GDQ_ENFD : FS_QUOTA_PDQ_ENFD; |
843 | } | 867 | } |
844 | return (uflags); | 868 | return (uflags); |
845 | } | 869 | } |
@@ -875,8 +899,9 @@ xfs_dqrele_inode( | |||
875 | xfs_qm_dqrele(ip->i_gdquot); | 899 | xfs_qm_dqrele(ip->i_gdquot); |
876 | ip->i_gdquot = NULL; | 900 | ip->i_gdquot = NULL; |
877 | } | 901 | } |
878 | xfs_iput(ip, XFS_ILOCK_EXCL); | 902 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
879 | 903 | ||
904 | IRELE(ip); | ||
880 | return 0; | 905 | return 0; |
881 | } | 906 | } |
882 | 907 | ||
@@ -1109,10 +1134,7 @@ xfs_qm_internalqcheck_adjust( | |||
1109 | xfs_ino_t ino, /* inode number to get data for */ | 1134 | xfs_ino_t ino, /* inode number to get data for */ |
1110 | void __user *buffer, /* not used */ | 1135 | void __user *buffer, /* not used */ |
1111 | int ubsize, /* not used */ | 1136 | int ubsize, /* not used */ |
1112 | void *private_data, /* not used */ | ||
1113 | xfs_daddr_t bno, /* starting block of inode cluster */ | ||
1114 | int *ubused, /* not used */ | 1137 | int *ubused, /* not used */ |
1115 | void *dip, /* not used */ | ||
1116 | int *res) /* bulkstat result code */ | 1138 | int *res) /* bulkstat result code */ |
1117 | { | 1139 | { |
1118 | xfs_inode_t *ip; | 1140 | xfs_inode_t *ip; |
@@ -1134,7 +1156,7 @@ xfs_qm_internalqcheck_adjust( | |||
1134 | ipreleased = B_FALSE; | 1156 | ipreleased = B_FALSE; |
1135 | again: | 1157 | again: |
1136 | lock_flags = XFS_ILOCK_SHARED; | 1158 | lock_flags = XFS_ILOCK_SHARED; |
1137 | if ((error = xfs_iget(mp, NULL, ino, 0, lock_flags, &ip, bno))) { | 1159 | if ((error = xfs_iget(mp, NULL, ino, 0, lock_flags, &ip))) { |
1138 | *res = BULKSTAT_RV_NOTHING; | 1160 | *res = BULKSTAT_RV_NOTHING; |
1139 | return (error); | 1161 | return (error); |
1140 | } | 1162 | } |
@@ -1146,7 +1168,8 @@ xfs_qm_internalqcheck_adjust( | |||
1146 | * of those now. | 1168 | * of those now. |
1147 | */ | 1169 | */ |
1148 | if (! ipreleased) { | 1170 | if (! ipreleased) { |
1149 | xfs_iput(ip, lock_flags); | 1171 | xfs_iunlock(ip, lock_flags); |
1172 | IRELE(ip); | ||
1150 | ipreleased = B_TRUE; | 1173 | ipreleased = B_TRUE; |
1151 | goto again; | 1174 | goto again; |
1152 | } | 1175 | } |
@@ -1163,7 +1186,8 @@ xfs_qm_internalqcheck_adjust( | |||
1163 | ASSERT(gd); | 1186 | ASSERT(gd); |
1164 | xfs_qm_internalqcheck_dqadjust(ip, gd); | 1187 | xfs_qm_internalqcheck_dqadjust(ip, gd); |
1165 | } | 1188 | } |
1166 | xfs_iput(ip, lock_flags); | 1189 | xfs_iunlock(ip, lock_flags); |
1190 | IRELE(ip); | ||
1167 | *res = BULKSTAT_RV_DIDONE; | 1191 | *res = BULKSTAT_RV_DIDONE; |
1168 | return (0); | 1192 | return (0); |
1169 | } | 1193 | } |
@@ -1205,15 +1229,15 @@ xfs_qm_internalqcheck( | |||
1205 | * Iterate thru all the inodes in the file system, | 1229 | * Iterate thru all the inodes in the file system, |
1206 | * adjusting the corresponding dquot counters | 1230 | * adjusting the corresponding dquot counters |
1207 | */ | 1231 | */ |
1208 | if ((error = xfs_bulkstat(mp, &lastino, &count, | 1232 | error = xfs_bulkstat(mp, &lastino, &count, |
1209 | xfs_qm_internalqcheck_adjust, NULL, | 1233 | xfs_qm_internalqcheck_adjust, |
1210 | 0, NULL, BULKSTAT_FG_IGET, &done))) { | 1234 | 0, NULL, &done); |
1235 | if (error) { | ||
1236 | cmn_err(CE_DEBUG, "Bulkstat returned error 0x%x", error); | ||
1211 | break; | 1237 | break; |
1212 | } | 1238 | } |
1213 | } while (! done); | 1239 | } while (!done); |
1214 | if (error) { | 1240 | |
1215 | cmn_err(CE_DEBUG, "Bulkstat returned error 0x%x", error); | ||
1216 | } | ||
1217 | cmn_err(CE_DEBUG, "Checking results against system dquots"); | 1241 | cmn_err(CE_DEBUG, "Checking results against system dquots"); |
1218 | for (i = 0; i < qmtest_hashmask; i++) { | 1242 | for (i = 0; i < qmtest_hashmask; i++) { |
1219 | xfs_dqtest_t *d, *n; | 1243 | xfs_dqtest_t *d, *n; |