aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/dquot.c117
-rw-r--r--include/linux/quota.h3
-rw-r--r--include/linux/quotaops.h21
3 files changed, 110 insertions, 31 deletions
diff --git a/fs/dquot.c b/fs/dquot.c
index bca3cac4bee7..9b1c4d3c9d83 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -899,6 +899,11 @@ static inline void dquot_incr_space(struct dquot *dquot, qsize_t number)
899 dquot->dq_dqb.dqb_curspace += number; 899 dquot->dq_dqb.dqb_curspace += number;
900} 900}
901 901
902static inline void dquot_resv_space(struct dquot *dquot, qsize_t number)
903{
904 dquot->dq_dqb.dqb_rsvspace += number;
905}
906
902static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number) 907static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
903{ 908{
904 if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE || 909 if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
@@ -1068,7 +1073,11 @@ err_out:
1068 kfree_skb(skb); 1073 kfree_skb(skb);
1069} 1074}
1070#endif 1075#endif
1071 1076/*
1077 * Write warnings to the console and send warning messages over netlink.
1078 *
1079 * Note that this function can sleep.
1080 */
1072static inline void flush_warnings(struct dquot * const *dquots, char *warntype) 1081static inline void flush_warnings(struct dquot * const *dquots, char *warntype)
1073{ 1082{
1074 int i; 1083 int i;
@@ -1129,13 +1138,18 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
1129/* needs dq_data_lock */ 1138/* needs dq_data_lock */
1130static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype) 1139static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
1131{ 1140{
1141 qsize_t tspace;
1142
1132 *warntype = QUOTA_NL_NOWARN; 1143 *warntype = QUOTA_NL_NOWARN;
1133 if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || 1144 if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
1134 test_bit(DQ_FAKE_B, &dquot->dq_flags)) 1145 test_bit(DQ_FAKE_B, &dquot->dq_flags))
1135 return QUOTA_OK; 1146 return QUOTA_OK;
1136 1147
1148 tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace
1149 + space;
1150
1137 if (dquot->dq_dqb.dqb_bhardlimit && 1151 if (dquot->dq_dqb.dqb_bhardlimit &&
1138 dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bhardlimit && 1152 tspace > dquot->dq_dqb.dqb_bhardlimit &&
1139 !ignore_hardlimit(dquot)) { 1153 !ignore_hardlimit(dquot)) {
1140 if (!prealloc) 1154 if (!prealloc)
1141 *warntype = QUOTA_NL_BHARDWARN; 1155 *warntype = QUOTA_NL_BHARDWARN;
@@ -1143,7 +1157,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
1143 } 1157 }
1144 1158
1145 if (dquot->dq_dqb.dqb_bsoftlimit && 1159 if (dquot->dq_dqb.dqb_bsoftlimit &&
1146 dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit && 1160 tspace > dquot->dq_dqb.dqb_bsoftlimit &&
1147 dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime && 1161 dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime &&
1148 !ignore_hardlimit(dquot)) { 1162 !ignore_hardlimit(dquot)) {
1149 if (!prealloc) 1163 if (!prealloc)
@@ -1152,7 +1166,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
1152 } 1166 }
1153 1167
1154 if (dquot->dq_dqb.dqb_bsoftlimit && 1168 if (dquot->dq_dqb.dqb_bsoftlimit &&
1155 dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit && 1169 tspace > dquot->dq_dqb.dqb_bsoftlimit &&
1156 dquot->dq_dqb.dqb_btime == 0) { 1170 dquot->dq_dqb.dqb_btime == 0) {
1157 if (!prealloc) { 1171 if (!prealloc) {
1158 *warntype = QUOTA_NL_BSOFTWARN; 1172 *warntype = QUOTA_NL_BSOFTWARN;
@@ -1306,51 +1320,92 @@ void vfs_dq_drop(struct inode *inode)
1306/* 1320/*
1307 * This operation can block, but only after everything is updated 1321 * This operation can block, but only after everything is updated
1308 */ 1322 */
1309int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) 1323int __dquot_alloc_space(struct inode *inode, qsize_t number,
1324 int warn, int reserve)
1310{ 1325{
1311 int cnt, ret = NO_QUOTA; 1326 int cnt, ret = QUOTA_OK;
1312 char warntype[MAXQUOTAS]; 1327 char warntype[MAXQUOTAS];
1313 1328
1314 /* First test before acquiring mutex - solves deadlocks when we
1315 * re-enter the quota code and are already holding the mutex */
1316 if (IS_NOQUOTA(inode)) {
1317out_add:
1318 inode_add_bytes(inode, number);
1319 return QUOTA_OK;
1320 }
1321 for (cnt = 0; cnt < MAXQUOTAS; cnt++) 1329 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1322 warntype[cnt] = QUOTA_NL_NOWARN; 1330 warntype[cnt] = QUOTA_NL_NOWARN;
1323 1331
1324 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1325 if (IS_NOQUOTA(inode)) { /* Now we can do reliable test... */
1326 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1327 goto out_add;
1328 }
1329 spin_lock(&dq_data_lock); 1332 spin_lock(&dq_data_lock);
1330 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 1333 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1331 if (inode->i_dquot[cnt] == NODQUOT) 1334 if (inode->i_dquot[cnt] == NODQUOT)
1332 continue; 1335 continue;
1333 if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA) 1336 if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt)
1334 goto warn_put_all; 1337 == NO_QUOTA) {
1338 ret = NO_QUOTA;
1339 goto out_unlock;
1340 }
1335 } 1341 }
1336 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 1342 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1337 if (inode->i_dquot[cnt] == NODQUOT) 1343 if (inode->i_dquot[cnt] == NODQUOT)
1338 continue; 1344 continue;
1339 dquot_incr_space(inode->i_dquot[cnt], number); 1345 if (reserve)
1346 dquot_resv_space(inode->i_dquot[cnt], number);
1347 else
1348 dquot_incr_space(inode->i_dquot[cnt], number);
1340 } 1349 }
1341 inode_add_bytes(inode, number); 1350 if (!reserve)
1342 ret = QUOTA_OK; 1351 inode_add_bytes(inode, number);
1343warn_put_all: 1352out_unlock:
1344 spin_unlock(&dq_data_lock); 1353 spin_unlock(&dq_data_lock);
1345 if (ret == QUOTA_OK)
1346 /* Dirtify all the dquots - this can block when journalling */
1347 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1348 if (inode->i_dquot[cnt])
1349 mark_dquot_dirty(inode->i_dquot[cnt]);
1350 flush_warnings(inode->i_dquot, warntype); 1354 flush_warnings(inode->i_dquot, warntype);
1355 return ret;
1356}
1357
1358int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
1359{
1360 int cnt, ret = QUOTA_OK;
1361
1362 /*
1363 * First test before acquiring mutex - solves deadlocks when we
1364 * re-enter the quota code and are already holding the mutex
1365 */
1366 if (IS_NOQUOTA(inode)) {
1367 inode_add_bytes(inode, number);
1368 goto out;
1369 }
1370
1371 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1372 if (IS_NOQUOTA(inode)) {
1373 inode_add_bytes(inode, number);
1374 goto out_unlock;
1375 }
1376
1377 ret = __dquot_alloc_space(inode, number, warn, 0);
1378 if (ret == NO_QUOTA)
1379 goto out_unlock;
1380
1381 /* Dirtify all the dquots - this can block when journalling */
1382 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1383 if (inode->i_dquot[cnt])
1384 mark_dquot_dirty(inode->i_dquot[cnt]);
1385out_unlock:
1351 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); 1386 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1387out:
1388 return ret;
1389}
1390
1391int dquot_reserve_space(struct inode *inode, qsize_t number, int warn)
1392{
1393 int ret = QUOTA_OK;
1394
1395 if (IS_NOQUOTA(inode))
1396 goto out;
1397
1398 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1399 if (IS_NOQUOTA(inode))
1400 goto out_unlock;
1401
1402 ret = __dquot_alloc_space(inode, number, warn, 1);
1403out_unlock:
1404 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1405out:
1352 return ret; 1406 return ret;
1353} 1407}
1408EXPORT_SYMBOL(dquot_reserve_space);
1354 1409
1355/* 1410/*
1356 * This operation can block, but only after everything is updated 1411 * This operation can block, but only after everything is updated
@@ -2057,7 +2112,7 @@ static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
2057 spin_lock(&dq_data_lock); 2112 spin_lock(&dq_data_lock);
2058 di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit); 2113 di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit);
2059 di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit); 2114 di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit);
2060 di->dqb_curspace = dm->dqb_curspace; 2115 di->dqb_curspace = dm->dqb_curspace + dm->dqb_rsvspace;
2061 di->dqb_ihardlimit = dm->dqb_ihardlimit; 2116 di->dqb_ihardlimit = dm->dqb_ihardlimit;
2062 di->dqb_isoftlimit = dm->dqb_isoftlimit; 2117 di->dqb_isoftlimit = dm->dqb_isoftlimit;
2063 di->dqb_curinodes = dm->dqb_curinodes; 2118 di->dqb_curinodes = dm->dqb_curinodes;
@@ -2097,7 +2152,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
2097 2152
2098 spin_lock(&dq_data_lock); 2153 spin_lock(&dq_data_lock);
2099 if (di->dqb_valid & QIF_SPACE) { 2154 if (di->dqb_valid & QIF_SPACE) {
2100 dm->dqb_curspace = di->dqb_curspace; 2155 dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace;
2101 check_blim = 1; 2156 check_blim = 1;
2102 __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); 2157 __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
2103 } 2158 }
diff --git a/include/linux/quota.h b/include/linux/quota.h
index d72d5d84fde5..54b837fa64f2 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -198,6 +198,7 @@ struct mem_dqblk {
198 qsize_t dqb_bhardlimit; /* absolute limit on disk blks alloc */ 198 qsize_t dqb_bhardlimit; /* absolute limit on disk blks alloc */
199 qsize_t dqb_bsoftlimit; /* preferred limit on disk blks */ 199 qsize_t dqb_bsoftlimit; /* preferred limit on disk blks */
200 qsize_t dqb_curspace; /* current used space */ 200 qsize_t dqb_curspace; /* current used space */
201 qsize_t dqb_rsvspace; /* current reserved space for delalloc*/
201 qsize_t dqb_ihardlimit; /* absolute limit on allocated inodes */ 202 qsize_t dqb_ihardlimit; /* absolute limit on allocated inodes */
202 qsize_t dqb_isoftlimit; /* preferred inode limit */ 203 qsize_t dqb_isoftlimit; /* preferred inode limit */
203 qsize_t dqb_curinodes; /* current # allocated inodes */ 204 qsize_t dqb_curinodes; /* current # allocated inodes */
@@ -308,6 +309,8 @@ struct dquot_operations {
308 int (*release_dquot) (struct dquot *); /* Quota is going to be deleted from disk */ 309 int (*release_dquot) (struct dquot *); /* Quota is going to be deleted from disk */
309 int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */ 310 int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */
310 int (*write_info) (struct super_block *, int); /* Write of quota "superblock" */ 311 int (*write_info) (struct super_block *, int); /* Write of quota "superblock" */
312 /* reserve quota for delayed block allocation */
313 int (*reserve_space) (struct inode *, qsize_t, int);
311}; 314};
312 315
313/* Operations handling requests from userspace */ 316/* Operations handling requests from userspace */
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 0b35b3a1be05..3e3a0d2874d9 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -183,6 +183,16 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr)
183 return ret; 183 return ret;
184} 184}
185 185
186static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
187{
188 if (sb_any_quota_active(inode->i_sb)) {
189 /* Used space is updated in alloc_space() */
190 if (inode->i_sb->dq_op->reserve_space(inode, nr, 0) == NO_QUOTA)
191 return 1;
192 }
193 return 0;
194}
195
186static inline int vfs_dq_alloc_inode(struct inode *inode) 196static inline int vfs_dq_alloc_inode(struct inode *inode)
187{ 197{
188 if (sb_any_quota_active(inode->i_sb)) { 198 if (sb_any_quota_active(inode->i_sb)) {
@@ -339,6 +349,11 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr)
339 return 0; 349 return 0;
340} 350}
341 351
352static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
353{
354 return 0;
355}
356
342static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr) 357static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
343{ 358{
344 inode_sub_bytes(inode, nr); 359 inode_sub_bytes(inode, nr);
@@ -376,6 +391,12 @@ static inline int vfs_dq_alloc_block(struct inode *inode, qsize_t nr)
376 nr << inode->i_sb->s_blocksize_bits); 391 nr << inode->i_sb->s_blocksize_bits);
377} 392}
378 393
394static inline int vfs_dq_reserve_block(struct inode *inode, qsize_t nr)
395{
396 return vfs_dq_reserve_space(inode,
397 nr << inode->i_blkbits);
398}
399
379static inline void vfs_dq_free_block_nodirty(struct inode *inode, qsize_t nr) 400static inline void vfs_dq_free_block_nodirty(struct inode *inode, qsize_t nr)
380{ 401{
381 vfs_dq_free_space_nodirty(inode, nr << inode->i_sb->s_blocksize_bits); 402 vfs_dq_free_space_nodirty(inode, nr << inode->i_sb->s_blocksize_bits);