diff options
Diffstat (limited to 'fs/quota')
-rw-r--r-- | fs/quota/dquot.c | 189 |
1 files changed, 113 insertions, 76 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 46741970371..439ab110f4d 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -1109,6 +1109,13 @@ static void dquot_decr_space(struct dquot *dquot, qsize_t number) | |||
1109 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 1109 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | struct dquot_warn { | ||
1113 | struct super_block *w_sb; | ||
1114 | qid_t w_dq_id; | ||
1115 | short w_dq_type; | ||
1116 | short w_type; | ||
1117 | }; | ||
1118 | |||
1112 | static int warning_issued(struct dquot *dquot, const int warntype) | 1119 | static int warning_issued(struct dquot *dquot, const int warntype) |
1113 | { | 1120 | { |
1114 | int flag = (warntype == QUOTA_NL_BHARDWARN || | 1121 | int flag = (warntype == QUOTA_NL_BHARDWARN || |
@@ -1124,41 +1131,42 @@ static int warning_issued(struct dquot *dquot, const int warntype) | |||
1124 | #ifdef CONFIG_PRINT_QUOTA_WARNING | 1131 | #ifdef CONFIG_PRINT_QUOTA_WARNING |
1125 | static int flag_print_warnings = 1; | 1132 | static int flag_print_warnings = 1; |
1126 | 1133 | ||
1127 | static int need_print_warning(struct dquot *dquot) | 1134 | static int need_print_warning(struct dquot_warn *warn) |
1128 | { | 1135 | { |
1129 | if (!flag_print_warnings) | 1136 | if (!flag_print_warnings) |
1130 | return 0; | 1137 | return 0; |
1131 | 1138 | ||
1132 | switch (dquot->dq_type) { | 1139 | switch (warn->w_dq_type) { |
1133 | case USRQUOTA: | 1140 | case USRQUOTA: |
1134 | return current_fsuid() == dquot->dq_id; | 1141 | return current_fsuid() == warn->w_dq_id; |
1135 | case GRPQUOTA: | 1142 | case GRPQUOTA: |
1136 | return in_group_p(dquot->dq_id); | 1143 | return in_group_p(warn->w_dq_id); |
1137 | } | 1144 | } |
1138 | return 0; | 1145 | return 0; |
1139 | } | 1146 | } |
1140 | 1147 | ||
1141 | /* Print warning to user which exceeded quota */ | 1148 | /* Print warning to user which exceeded quota */ |
1142 | static void print_warning(struct dquot *dquot, const int warntype) | 1149 | static void print_warning(struct dquot_warn *warn) |
1143 | { | 1150 | { |
1144 | char *msg = NULL; | 1151 | char *msg = NULL; |
1145 | struct tty_struct *tty; | 1152 | struct tty_struct *tty; |
1153 | int warntype = warn->w_type; | ||
1146 | 1154 | ||
1147 | if (warntype == QUOTA_NL_IHARDBELOW || | 1155 | if (warntype == QUOTA_NL_IHARDBELOW || |
1148 | warntype == QUOTA_NL_ISOFTBELOW || | 1156 | warntype == QUOTA_NL_ISOFTBELOW || |
1149 | warntype == QUOTA_NL_BHARDBELOW || | 1157 | warntype == QUOTA_NL_BHARDBELOW || |
1150 | warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot)) | 1158 | warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(warn)) |
1151 | return; | 1159 | return; |
1152 | 1160 | ||
1153 | tty = get_current_tty(); | 1161 | tty = get_current_tty(); |
1154 | if (!tty) | 1162 | if (!tty) |
1155 | return; | 1163 | return; |
1156 | tty_write_message(tty, dquot->dq_sb->s_id); | 1164 | tty_write_message(tty, warn->w_sb->s_id); |
1157 | if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN) | 1165 | if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN) |
1158 | tty_write_message(tty, ": warning, "); | 1166 | tty_write_message(tty, ": warning, "); |
1159 | else | 1167 | else |
1160 | tty_write_message(tty, ": write failed, "); | 1168 | tty_write_message(tty, ": write failed, "); |
1161 | tty_write_message(tty, quotatypes[dquot->dq_type]); | 1169 | tty_write_message(tty, quotatypes[warn->w_dq_type]); |
1162 | switch (warntype) { | 1170 | switch (warntype) { |
1163 | case QUOTA_NL_IHARDWARN: | 1171 | case QUOTA_NL_IHARDWARN: |
1164 | msg = " file limit reached.\r\n"; | 1172 | msg = " file limit reached.\r\n"; |
@@ -1184,26 +1192,34 @@ static void print_warning(struct dquot *dquot, const int warntype) | |||
1184 | } | 1192 | } |
1185 | #endif | 1193 | #endif |
1186 | 1194 | ||
1195 | static void prepare_warning(struct dquot_warn *warn, struct dquot *dquot, | ||
1196 | int warntype) | ||
1197 | { | ||
1198 | if (warning_issued(dquot, warntype)) | ||
1199 | return; | ||
1200 | warn->w_type = warntype; | ||
1201 | warn->w_sb = dquot->dq_sb; | ||
1202 | warn->w_dq_id = dquot->dq_id; | ||
1203 | warn->w_dq_type = dquot->dq_type; | ||
1204 | } | ||
1205 | |||
1187 | /* | 1206 | /* |
1188 | * Write warnings to the console and send warning messages over netlink. | 1207 | * Write warnings to the console and send warning messages over netlink. |
1189 | * | 1208 | * |
1190 | * Note that this function can sleep. | 1209 | * Note that this function can call into tty and networking code. |
1191 | */ | 1210 | */ |
1192 | static void flush_warnings(struct dquot *const *dquots, char *warntype) | 1211 | static void flush_warnings(struct dquot_warn *warn) |
1193 | { | 1212 | { |
1194 | struct dquot *dq; | ||
1195 | int i; | 1213 | int i; |
1196 | 1214 | ||
1197 | for (i = 0; i < MAXQUOTAS; i++) { | 1215 | for (i = 0; i < MAXQUOTAS; i++) { |
1198 | dq = dquots[i]; | 1216 | if (warn[i].w_type == QUOTA_NL_NOWARN) |
1199 | if (dq && warntype[i] != QUOTA_NL_NOWARN && | 1217 | continue; |
1200 | !warning_issued(dq, warntype[i])) { | ||
1201 | #ifdef CONFIG_PRINT_QUOTA_WARNING | 1218 | #ifdef CONFIG_PRINT_QUOTA_WARNING |
1202 | print_warning(dq, warntype[i]); | 1219 | print_warning(&warn[i]); |
1203 | #endif | 1220 | #endif |
1204 | quota_send_warning(dq->dq_type, dq->dq_id, | 1221 | quota_send_warning(warn[i].w_dq_type, warn[i].w_dq_id, |
1205 | dq->dq_sb->s_dev, warntype[i]); | 1222 | warn[i].w_sb->s_dev, warn[i].w_type); |
1206 | } | ||
1207 | } | 1223 | } |
1208 | } | 1224 | } |
1209 | 1225 | ||
@@ -1217,11 +1233,11 @@ static int ignore_hardlimit(struct dquot *dquot) | |||
1217 | } | 1233 | } |
1218 | 1234 | ||
1219 | /* needs dq_data_lock */ | 1235 | /* needs dq_data_lock */ |
1220 | static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) | 1236 | static int check_idq(struct dquot *dquot, qsize_t inodes, |
1237 | struct dquot_warn *warn) | ||
1221 | { | 1238 | { |
1222 | qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; | 1239 | qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; |
1223 | 1240 | ||
1224 | *warntype = QUOTA_NL_NOWARN; | ||
1225 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || | 1241 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || |
1226 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1242 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
1227 | return 0; | 1243 | return 0; |
@@ -1229,7 +1245,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) | |||
1229 | if (dquot->dq_dqb.dqb_ihardlimit && | 1245 | if (dquot->dq_dqb.dqb_ihardlimit && |
1230 | newinodes > dquot->dq_dqb.dqb_ihardlimit && | 1246 | newinodes > dquot->dq_dqb.dqb_ihardlimit && |
1231 | !ignore_hardlimit(dquot)) { | 1247 | !ignore_hardlimit(dquot)) { |
1232 | *warntype = QUOTA_NL_IHARDWARN; | 1248 | prepare_warning(warn, dquot, QUOTA_NL_IHARDWARN); |
1233 | return -EDQUOT; | 1249 | return -EDQUOT; |
1234 | } | 1250 | } |
1235 | 1251 | ||
@@ -1238,14 +1254,14 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) | |||
1238 | dquot->dq_dqb.dqb_itime && | 1254 | dquot->dq_dqb.dqb_itime && |
1239 | get_seconds() >= dquot->dq_dqb.dqb_itime && | 1255 | get_seconds() >= dquot->dq_dqb.dqb_itime && |
1240 | !ignore_hardlimit(dquot)) { | 1256 | !ignore_hardlimit(dquot)) { |
1241 | *warntype = QUOTA_NL_ISOFTLONGWARN; | 1257 | prepare_warning(warn, dquot, QUOTA_NL_ISOFTLONGWARN); |
1242 | return -EDQUOT; | 1258 | return -EDQUOT; |
1243 | } | 1259 | } |
1244 | 1260 | ||
1245 | if (dquot->dq_dqb.dqb_isoftlimit && | 1261 | if (dquot->dq_dqb.dqb_isoftlimit && |
1246 | newinodes > dquot->dq_dqb.dqb_isoftlimit && | 1262 | newinodes > dquot->dq_dqb.dqb_isoftlimit && |
1247 | dquot->dq_dqb.dqb_itime == 0) { | 1263 | dquot->dq_dqb.dqb_itime == 0) { |
1248 | *warntype = QUOTA_NL_ISOFTWARN; | 1264 | prepare_warning(warn, dquot, QUOTA_NL_ISOFTWARN); |
1249 | dquot->dq_dqb.dqb_itime = get_seconds() + | 1265 | dquot->dq_dqb.dqb_itime = get_seconds() + |
1250 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; | 1266 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; |
1251 | } | 1267 | } |
@@ -1254,12 +1270,12 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) | |||
1254 | } | 1270 | } |
1255 | 1271 | ||
1256 | /* needs dq_data_lock */ | 1272 | /* needs dq_data_lock */ |
1257 | static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype) | 1273 | static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, |
1274 | struct dquot_warn *warn) | ||
1258 | { | 1275 | { |
1259 | qsize_t tspace; | 1276 | qsize_t tspace; |
1260 | struct super_block *sb = dquot->dq_sb; | 1277 | struct super_block *sb = dquot->dq_sb; |
1261 | 1278 | ||
1262 | *warntype = QUOTA_NL_NOWARN; | ||
1263 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) || | 1279 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) || |
1264 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1280 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
1265 | return 0; | 1281 | return 0; |
@@ -1271,7 +1287,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1271 | tspace > dquot->dq_dqb.dqb_bhardlimit && | 1287 | tspace > dquot->dq_dqb.dqb_bhardlimit && |
1272 | !ignore_hardlimit(dquot)) { | 1288 | !ignore_hardlimit(dquot)) { |
1273 | if (!prealloc) | 1289 | if (!prealloc) |
1274 | *warntype = QUOTA_NL_BHARDWARN; | 1290 | prepare_warning(warn, dquot, QUOTA_NL_BHARDWARN); |
1275 | return -EDQUOT; | 1291 | return -EDQUOT; |
1276 | } | 1292 | } |
1277 | 1293 | ||
@@ -1281,7 +1297,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1281 | get_seconds() >= dquot->dq_dqb.dqb_btime && | 1297 | get_seconds() >= dquot->dq_dqb.dqb_btime && |
1282 | !ignore_hardlimit(dquot)) { | 1298 | !ignore_hardlimit(dquot)) { |
1283 | if (!prealloc) | 1299 | if (!prealloc) |
1284 | *warntype = QUOTA_NL_BSOFTLONGWARN; | 1300 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTLONGWARN); |
1285 | return -EDQUOT; | 1301 | return -EDQUOT; |
1286 | } | 1302 | } |
1287 | 1303 | ||
@@ -1289,7 +1305,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1289 | tspace > dquot->dq_dqb.dqb_bsoftlimit && | 1305 | tspace > dquot->dq_dqb.dqb_bsoftlimit && |
1290 | dquot->dq_dqb.dqb_btime == 0) { | 1306 | dquot->dq_dqb.dqb_btime == 0) { |
1291 | if (!prealloc) { | 1307 | if (!prealloc) { |
1292 | *warntype = QUOTA_NL_BSOFTWARN; | 1308 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN); |
1293 | dquot->dq_dqb.dqb_btime = get_seconds() + | 1309 | dquot->dq_dqb.dqb_btime = get_seconds() + |
1294 | sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace; | 1310 | sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace; |
1295 | } | 1311 | } |
@@ -1542,10 +1558,9 @@ static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) | |||
1542 | int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | 1558 | int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) |
1543 | { | 1559 | { |
1544 | int cnt, ret = 0; | 1560 | int cnt, ret = 0; |
1545 | char warntype[MAXQUOTAS]; | 1561 | struct dquot_warn warn[MAXQUOTAS]; |
1546 | int warn = flags & DQUOT_SPACE_WARN; | 1562 | struct dquot **dquots = inode->i_dquot; |
1547 | int reserve = flags & DQUOT_SPACE_RESERVE; | 1563 | int reserve = flags & DQUOT_SPACE_RESERVE; |
1548 | int nofail = flags & DQUOT_SPACE_NOFAIL; | ||
1549 | 1564 | ||
1550 | /* | 1565 | /* |
1551 | * First test before acquiring mutex - solves deadlocks when we | 1566 | * First test before acquiring mutex - solves deadlocks when we |
@@ -1558,36 +1573,36 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
1558 | 1573 | ||
1559 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1574 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1560 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1575 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1561 | warntype[cnt] = QUOTA_NL_NOWARN; | 1576 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1562 | 1577 | ||
1563 | spin_lock(&dq_data_lock); | 1578 | spin_lock(&dq_data_lock); |
1564 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1579 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1565 | if (!inode->i_dquot[cnt]) | 1580 | if (!dquots[cnt]) |
1566 | continue; | 1581 | continue; |
1567 | ret = check_bdq(inode->i_dquot[cnt], number, !warn, | 1582 | ret = check_bdq(dquots[cnt], number, |
1568 | warntype+cnt); | 1583 | !(flags & DQUOT_SPACE_WARN), &warn[cnt]); |
1569 | if (ret && !nofail) { | 1584 | if (ret && !(flags & DQUOT_SPACE_NOFAIL)) { |
1570 | spin_unlock(&dq_data_lock); | 1585 | spin_unlock(&dq_data_lock); |
1571 | goto out_flush_warn; | 1586 | goto out_flush_warn; |
1572 | } | 1587 | } |
1573 | } | 1588 | } |
1574 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1589 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1575 | if (!inode->i_dquot[cnt]) | 1590 | if (!dquots[cnt]) |
1576 | continue; | 1591 | continue; |
1577 | if (reserve) | 1592 | if (reserve) |
1578 | dquot_resv_space(inode->i_dquot[cnt], number); | 1593 | dquot_resv_space(dquots[cnt], number); |
1579 | else | 1594 | else |
1580 | dquot_incr_space(inode->i_dquot[cnt], number); | 1595 | dquot_incr_space(dquots[cnt], number); |
1581 | } | 1596 | } |
1582 | inode_incr_space(inode, number, reserve); | 1597 | inode_incr_space(inode, number, reserve); |
1583 | spin_unlock(&dq_data_lock); | 1598 | spin_unlock(&dq_data_lock); |
1584 | 1599 | ||
1585 | if (reserve) | 1600 | if (reserve) |
1586 | goto out_flush_warn; | 1601 | goto out_flush_warn; |
1587 | mark_all_dquot_dirty(inode->i_dquot); | 1602 | mark_all_dquot_dirty(dquots); |
1588 | out_flush_warn: | 1603 | out_flush_warn: |
1589 | flush_warnings(inode->i_dquot, warntype); | ||
1590 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1604 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1605 | flush_warnings(warn); | ||
1591 | out: | 1606 | out: |
1592 | return ret; | 1607 | return ret; |
1593 | } | 1608 | } |
@@ -1599,36 +1614,37 @@ EXPORT_SYMBOL(__dquot_alloc_space); | |||
1599 | int dquot_alloc_inode(const struct inode *inode) | 1614 | int dquot_alloc_inode(const struct inode *inode) |
1600 | { | 1615 | { |
1601 | int cnt, ret = 0; | 1616 | int cnt, ret = 0; |
1602 | char warntype[MAXQUOTAS]; | 1617 | struct dquot_warn warn[MAXQUOTAS]; |
1618 | struct dquot * const *dquots = inode->i_dquot; | ||
1603 | 1619 | ||
1604 | /* First test before acquiring mutex - solves deadlocks when we | 1620 | /* First test before acquiring mutex - solves deadlocks when we |
1605 | * re-enter the quota code and are already holding the mutex */ | 1621 | * re-enter the quota code and are already holding the mutex */ |
1606 | if (!dquot_active(inode)) | 1622 | if (!dquot_active(inode)) |
1607 | return 0; | 1623 | return 0; |
1608 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1624 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1609 | warntype[cnt] = QUOTA_NL_NOWARN; | 1625 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1610 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1626 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1611 | spin_lock(&dq_data_lock); | 1627 | spin_lock(&dq_data_lock); |
1612 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1628 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1613 | if (!inode->i_dquot[cnt]) | 1629 | if (!dquots[cnt]) |
1614 | continue; | 1630 | continue; |
1615 | ret = check_idq(inode->i_dquot[cnt], 1, warntype + cnt); | 1631 | ret = check_idq(dquots[cnt], 1, &warn[cnt]); |
1616 | if (ret) | 1632 | if (ret) |
1617 | goto warn_put_all; | 1633 | goto warn_put_all; |
1618 | } | 1634 | } |
1619 | 1635 | ||
1620 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1636 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1621 | if (!inode->i_dquot[cnt]) | 1637 | if (!dquots[cnt]) |
1622 | continue; | 1638 | continue; |
1623 | dquot_incr_inodes(inode->i_dquot[cnt], 1); | 1639 | dquot_incr_inodes(dquots[cnt], 1); |
1624 | } | 1640 | } |
1625 | 1641 | ||
1626 | warn_put_all: | 1642 | warn_put_all: |
1627 | spin_unlock(&dq_data_lock); | 1643 | spin_unlock(&dq_data_lock); |
1628 | if (ret == 0) | 1644 | if (ret == 0) |
1629 | mark_all_dquot_dirty(inode->i_dquot); | 1645 | mark_all_dquot_dirty(dquots); |
1630 | flush_warnings(inode->i_dquot, warntype); | ||
1631 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1646 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1647 | flush_warnings(warn); | ||
1632 | return ret; | 1648 | return ret; |
1633 | } | 1649 | } |
1634 | EXPORT_SYMBOL(dquot_alloc_inode); | 1650 | EXPORT_SYMBOL(dquot_alloc_inode); |
@@ -1668,7 +1684,8 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty); | |||
1668 | void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | 1684 | void __dquot_free_space(struct inode *inode, qsize_t number, int flags) |
1669 | { | 1685 | { |
1670 | unsigned int cnt; | 1686 | unsigned int cnt; |
1671 | char warntype[MAXQUOTAS]; | 1687 | struct dquot_warn warn[MAXQUOTAS]; |
1688 | struct dquot **dquots = inode->i_dquot; | ||
1672 | int reserve = flags & DQUOT_SPACE_RESERVE; | 1689 | int reserve = flags & DQUOT_SPACE_RESERVE; |
1673 | 1690 | ||
1674 | /* First test before acquiring mutex - solves deadlocks when we | 1691 | /* First test before acquiring mutex - solves deadlocks when we |
@@ -1681,23 +1698,28 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | |||
1681 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1698 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1682 | spin_lock(&dq_data_lock); | 1699 | spin_lock(&dq_data_lock); |
1683 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1700 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1684 | if (!inode->i_dquot[cnt]) | 1701 | int wtype; |
1702 | |||
1703 | warn[cnt].w_type = QUOTA_NL_NOWARN; | ||
1704 | if (!dquots[cnt]) | ||
1685 | continue; | 1705 | continue; |
1686 | warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number); | 1706 | wtype = info_bdq_free(dquots[cnt], number); |
1707 | if (wtype != QUOTA_NL_NOWARN) | ||
1708 | prepare_warning(&warn[cnt], dquots[cnt], wtype); | ||
1687 | if (reserve) | 1709 | if (reserve) |
1688 | dquot_free_reserved_space(inode->i_dquot[cnt], number); | 1710 | dquot_free_reserved_space(dquots[cnt], number); |
1689 | else | 1711 | else |
1690 | dquot_decr_space(inode->i_dquot[cnt], number); | 1712 | dquot_decr_space(dquots[cnt], number); |
1691 | } | 1713 | } |
1692 | inode_decr_space(inode, number, reserve); | 1714 | inode_decr_space(inode, number, reserve); |
1693 | spin_unlock(&dq_data_lock); | 1715 | spin_unlock(&dq_data_lock); |
1694 | 1716 | ||
1695 | if (reserve) | 1717 | if (reserve) |
1696 | goto out_unlock; | 1718 | goto out_unlock; |
1697 | mark_all_dquot_dirty(inode->i_dquot); | 1719 | mark_all_dquot_dirty(dquots); |
1698 | out_unlock: | 1720 | out_unlock: |
1699 | flush_warnings(inode->i_dquot, warntype); | ||
1700 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1721 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1722 | flush_warnings(warn); | ||
1701 | } | 1723 | } |
1702 | EXPORT_SYMBOL(__dquot_free_space); | 1724 | EXPORT_SYMBOL(__dquot_free_space); |
1703 | 1725 | ||
@@ -1707,7 +1729,8 @@ EXPORT_SYMBOL(__dquot_free_space); | |||
1707 | void dquot_free_inode(const struct inode *inode) | 1729 | void dquot_free_inode(const struct inode *inode) |
1708 | { | 1730 | { |
1709 | unsigned int cnt; | 1731 | unsigned int cnt; |
1710 | char warntype[MAXQUOTAS]; | 1732 | struct dquot_warn warn[MAXQUOTAS]; |
1733 | struct dquot * const *dquots = inode->i_dquot; | ||
1711 | 1734 | ||
1712 | /* First test before acquiring mutex - solves deadlocks when we | 1735 | /* First test before acquiring mutex - solves deadlocks when we |
1713 | * re-enter the quota code and are already holding the mutex */ | 1736 | * re-enter the quota code and are already holding the mutex */ |
@@ -1717,15 +1740,20 @@ void dquot_free_inode(const struct inode *inode) | |||
1717 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1740 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1718 | spin_lock(&dq_data_lock); | 1741 | spin_lock(&dq_data_lock); |
1719 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1742 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1720 | if (!inode->i_dquot[cnt]) | 1743 | int wtype; |
1744 | |||
1745 | warn[cnt].w_type = QUOTA_NL_NOWARN; | ||
1746 | if (!dquots[cnt]) | ||
1721 | continue; | 1747 | continue; |
1722 | warntype[cnt] = info_idq_free(inode->i_dquot[cnt], 1); | 1748 | wtype = info_idq_free(dquots[cnt], 1); |
1723 | dquot_decr_inodes(inode->i_dquot[cnt], 1); | 1749 | if (wtype != QUOTA_NL_NOWARN) |
1750 | prepare_warning(&warn[cnt], dquots[cnt], wtype); | ||
1751 | dquot_decr_inodes(dquots[cnt], 1); | ||
1724 | } | 1752 | } |
1725 | spin_unlock(&dq_data_lock); | 1753 | spin_unlock(&dq_data_lock); |
1726 | mark_all_dquot_dirty(inode->i_dquot); | 1754 | mark_all_dquot_dirty(dquots); |
1727 | flush_warnings(inode->i_dquot, warntype); | ||
1728 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1755 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1756 | flush_warnings(warn); | ||
1729 | } | 1757 | } |
1730 | EXPORT_SYMBOL(dquot_free_inode); | 1758 | EXPORT_SYMBOL(dquot_free_inode); |
1731 | 1759 | ||
@@ -1746,16 +1774,20 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1746 | struct dquot *transfer_from[MAXQUOTAS] = {}; | 1774 | struct dquot *transfer_from[MAXQUOTAS] = {}; |
1747 | int cnt, ret = 0; | 1775 | int cnt, ret = 0; |
1748 | char is_valid[MAXQUOTAS] = {}; | 1776 | char is_valid[MAXQUOTAS] = {}; |
1749 | char warntype_to[MAXQUOTAS]; | 1777 | struct dquot_warn warn_to[MAXQUOTAS]; |
1750 | char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; | 1778 | struct dquot_warn warn_from_inodes[MAXQUOTAS]; |
1779 | struct dquot_warn warn_from_space[MAXQUOTAS]; | ||
1751 | 1780 | ||
1752 | /* First test before acquiring mutex - solves deadlocks when we | 1781 | /* First test before acquiring mutex - solves deadlocks when we |
1753 | * re-enter the quota code and are already holding the mutex */ | 1782 | * re-enter the quota code and are already holding the mutex */ |
1754 | if (IS_NOQUOTA(inode)) | 1783 | if (IS_NOQUOTA(inode)) |
1755 | return 0; | 1784 | return 0; |
1756 | /* Initialize the arrays */ | 1785 | /* Initialize the arrays */ |
1757 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1786 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1758 | warntype_to[cnt] = QUOTA_NL_NOWARN; | 1787 | warn_to[cnt].w_type = QUOTA_NL_NOWARN; |
1788 | warn_from_inodes[cnt].w_type = QUOTA_NL_NOWARN; | ||
1789 | warn_from_space[cnt].w_type = QUOTA_NL_NOWARN; | ||
1790 | } | ||
1759 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1791 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1760 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ | 1792 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ |
1761 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1793 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
@@ -1777,10 +1809,10 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1777 | continue; | 1809 | continue; |
1778 | is_valid[cnt] = 1; | 1810 | is_valid[cnt] = 1; |
1779 | transfer_from[cnt] = inode->i_dquot[cnt]; | 1811 | transfer_from[cnt] = inode->i_dquot[cnt]; |
1780 | ret = check_idq(transfer_to[cnt], 1, warntype_to + cnt); | 1812 | ret = check_idq(transfer_to[cnt], 1, &warn_to[cnt]); |
1781 | if (ret) | 1813 | if (ret) |
1782 | goto over_quota; | 1814 | goto over_quota; |
1783 | ret = check_bdq(transfer_to[cnt], space, 0, warntype_to + cnt); | 1815 | ret = check_bdq(transfer_to[cnt], space, 0, &warn_to[cnt]); |
1784 | if (ret) | 1816 | if (ret) |
1785 | goto over_quota; | 1817 | goto over_quota; |
1786 | } | 1818 | } |
@@ -1793,10 +1825,15 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1793 | continue; | 1825 | continue; |
1794 | /* Due to IO error we might not have transfer_from[] structure */ | 1826 | /* Due to IO error we might not have transfer_from[] structure */ |
1795 | if (transfer_from[cnt]) { | 1827 | if (transfer_from[cnt]) { |
1796 | warntype_from_inodes[cnt] = | 1828 | int wtype; |
1797 | info_idq_free(transfer_from[cnt], 1); | 1829 | wtype = info_idq_free(transfer_from[cnt], 1); |
1798 | warntype_from_space[cnt] = | 1830 | if (wtype != QUOTA_NL_NOWARN) |
1799 | info_bdq_free(transfer_from[cnt], space); | 1831 | prepare_warning(&warn_from_inodes[cnt], |
1832 | transfer_from[cnt], wtype); | ||
1833 | wtype = info_bdq_free(transfer_from[cnt], space); | ||
1834 | if (wtype != QUOTA_NL_NOWARN) | ||
1835 | prepare_warning(&warn_from_space[cnt], | ||
1836 | transfer_from[cnt], wtype); | ||
1800 | dquot_decr_inodes(transfer_from[cnt], 1); | 1837 | dquot_decr_inodes(transfer_from[cnt], 1); |
1801 | dquot_decr_space(transfer_from[cnt], cur_space); | 1838 | dquot_decr_space(transfer_from[cnt], cur_space); |
1802 | dquot_free_reserved_space(transfer_from[cnt], | 1839 | dquot_free_reserved_space(transfer_from[cnt], |
@@ -1814,9 +1851,9 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1814 | 1851 | ||
1815 | mark_all_dquot_dirty(transfer_from); | 1852 | mark_all_dquot_dirty(transfer_from); |
1816 | mark_all_dquot_dirty(transfer_to); | 1853 | mark_all_dquot_dirty(transfer_to); |
1817 | flush_warnings(transfer_to, warntype_to); | 1854 | flush_warnings(warn_to); |
1818 | flush_warnings(transfer_from, warntype_from_inodes); | 1855 | flush_warnings(warn_from_inodes); |
1819 | flush_warnings(transfer_from, warntype_from_space); | 1856 | flush_warnings(warn_from_space); |
1820 | /* Pass back references to put */ | 1857 | /* Pass back references to put */ |
1821 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1858 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1822 | if (is_valid[cnt]) | 1859 | if (is_valid[cnt]) |
@@ -1825,7 +1862,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1825 | over_quota: | 1862 | over_quota: |
1826 | spin_unlock(&dq_data_lock); | 1863 | spin_unlock(&dq_data_lock); |
1827 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1864 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1828 | flush_warnings(transfer_to, warntype_to); | 1865 | flush_warnings(warn_to); |
1829 | return ret; | 1866 | return ret; |
1830 | } | 1867 | } |
1831 | EXPORT_SYMBOL(__dquot_transfer); | 1868 | EXPORT_SYMBOL(__dquot_transfer); |