diff options
-rw-r--r-- | fs/dquot.c | 117 | ||||
-rw-r--r-- | fs/ext3/super.c | 4 | ||||
-rw-r--r-- | fs/quota.c | 6 | ||||
-rw-r--r-- | fs/quota_v2.c | 2 | ||||
-rw-r--r-- | fs/super.c | 4 | ||||
-rw-r--r-- | include/linux/quota.h | 7 |
6 files changed, 71 insertions, 69 deletions
diff --git a/fs/dquot.c b/fs/dquot.c index 9376a4378988..acf07e581f8c 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -103,12 +103,12 @@ | |||
103 | * (these locking rules also apply for S_NOQUOTA flag in the inode - note that | 103 | * (these locking rules also apply for S_NOQUOTA flag in the inode - note that |
104 | * for altering the flag i_mutex is also needed). If operation is holding | 104 | * for altering the flag i_mutex is also needed). If operation is holding |
105 | * reference to dquot in other way (e.g. quotactl ops) it must be guarded by | 105 | * reference to dquot in other way (e.g. quotactl ops) it must be guarded by |
106 | * dqonoff_sem. | 106 | * dqonoff_mutex. |
107 | * This locking assures that: | 107 | * This locking assures that: |
108 | * a) update/access to dquot pointers in inode is serialized | 108 | * a) update/access to dquot pointers in inode is serialized |
109 | * b) everyone is guarded against invalidate_dquots() | 109 | * b) everyone is guarded against invalidate_dquots() |
110 | * | 110 | * |
111 | * Each dquot has its dq_lock semaphore. Locked dquots might not be referenced | 111 | * Each dquot has its dq_lock mutex. Locked dquots might not be referenced |
112 | * from inodes (dquot_alloc_space() and such don't check the dq_lock). | 112 | * from inodes (dquot_alloc_space() and such don't check the dq_lock). |
113 | * Currently dquot is locked only when it is being read to memory (or space for | 113 | * Currently dquot is locked only when it is being read to memory (or space for |
114 | * it is being allocated) on the first dqget() and when it is being released on | 114 | * it is being allocated) on the first dqget() and when it is being released on |
@@ -118,8 +118,9 @@ | |||
118 | * spinlock to internal buffers before writing. | 118 | * spinlock to internal buffers before writing. |
119 | * | 119 | * |
120 | * Lock ordering (including related VFS locks) is the following: | 120 | * Lock ordering (including related VFS locks) is the following: |
121 | * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > dqio_sem | 121 | * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > |
122 | * i_mutex on quota files is special (it's below dqio_sem) | 122 | * dqio_mutex |
123 | * i_mutex on quota files is special (it's below dqio_mutex) | ||
123 | */ | 124 | */ |
124 | 125 | ||
125 | static DEFINE_SPINLOCK(dq_list_lock); | 126 | static DEFINE_SPINLOCK(dq_list_lock); |
@@ -280,8 +281,8 @@ static inline void remove_inuse(struct dquot *dquot) | |||
280 | 281 | ||
281 | static void wait_on_dquot(struct dquot *dquot) | 282 | static void wait_on_dquot(struct dquot *dquot) |
282 | { | 283 | { |
283 | down(&dquot->dq_lock); | 284 | mutex_lock(&dquot->dq_lock); |
284 | up(&dquot->dq_lock); | 285 | mutex_unlock(&dquot->dq_lock); |
285 | } | 286 | } |
286 | 287 | ||
287 | #define mark_dquot_dirty(dquot) ((dquot)->dq_sb->dq_op->mark_dirty(dquot)) | 288 | #define mark_dquot_dirty(dquot) ((dquot)->dq_sb->dq_op->mark_dirty(dquot)) |
@@ -320,8 +321,8 @@ int dquot_acquire(struct dquot *dquot) | |||
320 | int ret = 0, ret2 = 0; | 321 | int ret = 0, ret2 = 0; |
321 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); | 322 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); |
322 | 323 | ||
323 | down(&dquot->dq_lock); | 324 | mutex_lock(&dquot->dq_lock); |
324 | down(&dqopt->dqio_sem); | 325 | mutex_lock(&dqopt->dqio_mutex); |
325 | if (!test_bit(DQ_READ_B, &dquot->dq_flags)) | 326 | if (!test_bit(DQ_READ_B, &dquot->dq_flags)) |
326 | ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot); | 327 | ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot); |
327 | if (ret < 0) | 328 | if (ret < 0) |
@@ -342,8 +343,8 @@ int dquot_acquire(struct dquot *dquot) | |||
342 | } | 343 | } |
343 | set_bit(DQ_ACTIVE_B, &dquot->dq_flags); | 344 | set_bit(DQ_ACTIVE_B, &dquot->dq_flags); |
344 | out_iolock: | 345 | out_iolock: |
345 | up(&dqopt->dqio_sem); | 346 | mutex_unlock(&dqopt->dqio_mutex); |
346 | up(&dquot->dq_lock); | 347 | mutex_unlock(&dquot->dq_lock); |
347 | return ret; | 348 | return ret; |
348 | } | 349 | } |
349 | 350 | ||
@@ -355,7 +356,7 @@ int dquot_commit(struct dquot *dquot) | |||
355 | int ret = 0, ret2 = 0; | 356 | int ret = 0, ret2 = 0; |
356 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); | 357 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); |
357 | 358 | ||
358 | down(&dqopt->dqio_sem); | 359 | mutex_lock(&dqopt->dqio_mutex); |
359 | spin_lock(&dq_list_lock); | 360 | spin_lock(&dq_list_lock); |
360 | if (!clear_dquot_dirty(dquot)) { | 361 | if (!clear_dquot_dirty(dquot)) { |
361 | spin_unlock(&dq_list_lock); | 362 | spin_unlock(&dq_list_lock); |
@@ -372,7 +373,7 @@ int dquot_commit(struct dquot *dquot) | |||
372 | ret = ret2; | 373 | ret = ret2; |
373 | } | 374 | } |
374 | out_sem: | 375 | out_sem: |
375 | up(&dqopt->dqio_sem); | 376 | mutex_unlock(&dqopt->dqio_mutex); |
376 | return ret; | 377 | return ret; |
377 | } | 378 | } |
378 | 379 | ||
@@ -384,11 +385,11 @@ int dquot_release(struct dquot *dquot) | |||
384 | int ret = 0, ret2 = 0; | 385 | int ret = 0, ret2 = 0; |
385 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); | 386 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); |
386 | 387 | ||
387 | down(&dquot->dq_lock); | 388 | mutex_lock(&dquot->dq_lock); |
388 | /* Check whether we are not racing with some other dqget() */ | 389 | /* Check whether we are not racing with some other dqget() */ |
389 | if (atomic_read(&dquot->dq_count) > 1) | 390 | if (atomic_read(&dquot->dq_count) > 1) |
390 | goto out_dqlock; | 391 | goto out_dqlock; |
391 | down(&dqopt->dqio_sem); | 392 | mutex_lock(&dqopt->dqio_mutex); |
392 | if (dqopt->ops[dquot->dq_type]->release_dqblk) { | 393 | if (dqopt->ops[dquot->dq_type]->release_dqblk) { |
393 | ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot); | 394 | ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot); |
394 | /* Write the info */ | 395 | /* Write the info */ |
@@ -398,9 +399,9 @@ int dquot_release(struct dquot *dquot) | |||
398 | ret = ret2; | 399 | ret = ret2; |
399 | } | 400 | } |
400 | clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); | 401 | clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); |
401 | up(&dqopt->dqio_sem); | 402 | mutex_unlock(&dqopt->dqio_mutex); |
402 | out_dqlock: | 403 | out_dqlock: |
403 | up(&dquot->dq_lock); | 404 | mutex_unlock(&dquot->dq_lock); |
404 | return ret; | 405 | return ret; |
405 | } | 406 | } |
406 | 407 | ||
@@ -464,7 +465,7 @@ int vfs_quota_sync(struct super_block *sb, int type) | |||
464 | struct quota_info *dqopt = sb_dqopt(sb); | 465 | struct quota_info *dqopt = sb_dqopt(sb); |
465 | int cnt; | 466 | int cnt; |
466 | 467 | ||
467 | down(&dqopt->dqonoff_sem); | 468 | mutex_lock(&dqopt->dqonoff_mutex); |
468 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 469 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
469 | if (type != -1 && cnt != type) | 470 | if (type != -1 && cnt != type) |
470 | continue; | 471 | continue; |
@@ -499,7 +500,7 @@ int vfs_quota_sync(struct super_block *sb, int type) | |||
499 | spin_lock(&dq_list_lock); | 500 | spin_lock(&dq_list_lock); |
500 | dqstats.syncs++; | 501 | dqstats.syncs++; |
501 | spin_unlock(&dq_list_lock); | 502 | spin_unlock(&dq_list_lock); |
502 | up(&dqopt->dqonoff_sem); | 503 | mutex_unlock(&dqopt->dqonoff_mutex); |
503 | 504 | ||
504 | return 0; | 505 | return 0; |
505 | } | 506 | } |
@@ -540,7 +541,7 @@ static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) | |||
540 | /* | 541 | /* |
541 | * Put reference to dquot | 542 | * Put reference to dquot |
542 | * NOTE: If you change this function please check whether dqput_blocks() works right... | 543 | * NOTE: If you change this function please check whether dqput_blocks() works right... |
543 | * MUST be called with either dqptr_sem or dqonoff_sem held | 544 | * MUST be called with either dqptr_sem or dqonoff_mutex held |
544 | */ | 545 | */ |
545 | static void dqput(struct dquot *dquot) | 546 | static void dqput(struct dquot *dquot) |
546 | { | 547 | { |
@@ -605,7 +606,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |||
605 | return NODQUOT; | 606 | return NODQUOT; |
606 | 607 | ||
607 | memset((caddr_t)dquot, 0, sizeof(struct dquot)); | 608 | memset((caddr_t)dquot, 0, sizeof(struct dquot)); |
608 | sema_init(&dquot->dq_lock, 1); | 609 | mutex_init(&dquot->dq_lock); |
609 | INIT_LIST_HEAD(&dquot->dq_free); | 610 | INIT_LIST_HEAD(&dquot->dq_free); |
610 | INIT_LIST_HEAD(&dquot->dq_inuse); | 611 | INIT_LIST_HEAD(&dquot->dq_inuse); |
611 | INIT_HLIST_NODE(&dquot->dq_hash); | 612 | INIT_HLIST_NODE(&dquot->dq_hash); |
@@ -620,7 +621,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |||
620 | 621 | ||
621 | /* | 622 | /* |
622 | * Get reference to dquot | 623 | * Get reference to dquot |
623 | * MUST be called with either dqptr_sem or dqonoff_sem held | 624 | * MUST be called with either dqptr_sem or dqonoff_mutex held |
624 | */ | 625 | */ |
625 | static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) | 626 | static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) |
626 | { | 627 | { |
@@ -686,7 +687,7 @@ static int dqinit_needed(struct inode *inode, int type) | |||
686 | return 0; | 687 | return 0; |
687 | } | 688 | } |
688 | 689 | ||
689 | /* This routine is guarded by dqonoff_sem semaphore */ | 690 | /* This routine is guarded by dqonoff_mutex mutex */ |
690 | static void add_dquot_ref(struct super_block *sb, int type) | 691 | static void add_dquot_ref(struct super_block *sb, int type) |
691 | { | 692 | { |
692 | struct list_head *p; | 693 | struct list_head *p; |
@@ -964,8 +965,8 @@ int dquot_initialize(struct inode *inode, int type) | |||
964 | unsigned int id = 0; | 965 | unsigned int id = 0; |
965 | int cnt, ret = 0; | 966 | int cnt, ret = 0; |
966 | 967 | ||
967 | /* First test before acquiring semaphore - solves deadlocks when we | 968 | /* First test before acquiring mutex - solves deadlocks when we |
968 | * re-enter the quota code and are already holding the semaphore */ | 969 | * re-enter the quota code and are already holding the mutex */ |
969 | if (IS_NOQUOTA(inode)) | 970 | if (IS_NOQUOTA(inode)) |
970 | return 0; | 971 | return 0; |
971 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 972 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
@@ -1028,8 +1029,8 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) | |||
1028 | int cnt, ret = NO_QUOTA; | 1029 | int cnt, ret = NO_QUOTA; |
1029 | char warntype[MAXQUOTAS]; | 1030 | char warntype[MAXQUOTAS]; |
1030 | 1031 | ||
1031 | /* First test before acquiring semaphore - solves deadlocks when we | 1032 | /* First test before acquiring mutex - solves deadlocks when we |
1032 | * re-enter the quota code and are already holding the semaphore */ | 1033 | * re-enter the quota code and are already holding the mutex */ |
1033 | if (IS_NOQUOTA(inode)) { | 1034 | if (IS_NOQUOTA(inode)) { |
1034 | out_add: | 1035 | out_add: |
1035 | inode_add_bytes(inode, number); | 1036 | inode_add_bytes(inode, number); |
@@ -1077,8 +1078,8 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number) | |||
1077 | int cnt, ret = NO_QUOTA; | 1078 | int cnt, ret = NO_QUOTA; |
1078 | char warntype[MAXQUOTAS]; | 1079 | char warntype[MAXQUOTAS]; |
1079 | 1080 | ||
1080 | /* First test before acquiring semaphore - solves deadlocks when we | 1081 | /* First test before acquiring mutex - solves deadlocks when we |
1081 | * re-enter the quota code and are already holding the semaphore */ | 1082 | * re-enter the quota code and are already holding the mutex */ |
1082 | if (IS_NOQUOTA(inode)) | 1083 | if (IS_NOQUOTA(inode)) |
1083 | return QUOTA_OK; | 1084 | return QUOTA_OK; |
1084 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1085 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
@@ -1121,8 +1122,8 @@ int dquot_free_space(struct inode *inode, qsize_t number) | |||
1121 | { | 1122 | { |
1122 | unsigned int cnt; | 1123 | unsigned int cnt; |
1123 | 1124 | ||
1124 | /* First test before acquiring semaphore - solves deadlocks when we | 1125 | /* First test before acquiring mutex - solves deadlocks when we |
1125 | * re-enter the quota code and are already holding the semaphore */ | 1126 | * re-enter the quota code and are already holding the mutex */ |
1126 | if (IS_NOQUOTA(inode)) { | 1127 | if (IS_NOQUOTA(inode)) { |
1127 | out_sub: | 1128 | out_sub: |
1128 | inode_sub_bytes(inode, number); | 1129 | inode_sub_bytes(inode, number); |
@@ -1157,8 +1158,8 @@ int dquot_free_inode(const struct inode *inode, unsigned long number) | |||
1157 | { | 1158 | { |
1158 | unsigned int cnt; | 1159 | unsigned int cnt; |
1159 | 1160 | ||
1160 | /* First test before acquiring semaphore - solves deadlocks when we | 1161 | /* First test before acquiring mutex - solves deadlocks when we |
1161 | * re-enter the quota code and are already holding the semaphore */ | 1162 | * re-enter the quota code and are already holding the mutex */ |
1162 | if (IS_NOQUOTA(inode)) | 1163 | if (IS_NOQUOTA(inode)) |
1163 | return QUOTA_OK; | 1164 | return QUOTA_OK; |
1164 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1165 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
@@ -1197,8 +1198,8 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1197 | chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid; | 1198 | chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid; |
1198 | char warntype[MAXQUOTAS]; | 1199 | char warntype[MAXQUOTAS]; |
1199 | 1200 | ||
1200 | /* First test before acquiring semaphore - solves deadlocks when we | 1201 | /* First test before acquiring mutex - solves deadlocks when we |
1201 | * re-enter the quota code and are already holding the semaphore */ | 1202 | * re-enter the quota code and are already holding the mutex */ |
1202 | if (IS_NOQUOTA(inode)) | 1203 | if (IS_NOQUOTA(inode)) |
1203 | return QUOTA_OK; | 1204 | return QUOTA_OK; |
1204 | /* Clear the arrays */ | 1205 | /* Clear the arrays */ |
@@ -1292,9 +1293,9 @@ int dquot_commit_info(struct super_block *sb, int type) | |||
1292 | int ret; | 1293 | int ret; |
1293 | struct quota_info *dqopt = sb_dqopt(sb); | 1294 | struct quota_info *dqopt = sb_dqopt(sb); |
1294 | 1295 | ||
1295 | down(&dqopt->dqio_sem); | 1296 | mutex_lock(&dqopt->dqio_mutex); |
1296 | ret = dqopt->ops[type]->write_file_info(sb, type); | 1297 | ret = dqopt->ops[type]->write_file_info(sb, type); |
1297 | up(&dqopt->dqio_sem); | 1298 | mutex_unlock(&dqopt->dqio_mutex); |
1298 | return ret; | 1299 | return ret; |
1299 | } | 1300 | } |
1300 | 1301 | ||
@@ -1350,7 +1351,7 @@ int vfs_quota_off(struct super_block *sb, int type) | |||
1350 | struct inode *toputinode[MAXQUOTAS]; | 1351 | struct inode *toputinode[MAXQUOTAS]; |
1351 | 1352 | ||
1352 | /* We need to serialize quota_off() for device */ | 1353 | /* We need to serialize quota_off() for device */ |
1353 | down(&dqopt->dqonoff_sem); | 1354 | mutex_lock(&dqopt->dqonoff_mutex); |
1354 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1355 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1355 | toputinode[cnt] = NULL; | 1356 | toputinode[cnt] = NULL; |
1356 | if (type != -1 && cnt != type) | 1357 | if (type != -1 && cnt != type) |
@@ -1379,7 +1380,7 @@ int vfs_quota_off(struct super_block *sb, int type) | |||
1379 | dqopt->info[cnt].dqi_bgrace = 0; | 1380 | dqopt->info[cnt].dqi_bgrace = 0; |
1380 | dqopt->ops[cnt] = NULL; | 1381 | dqopt->ops[cnt] = NULL; |
1381 | } | 1382 | } |
1382 | up(&dqopt->dqonoff_sem); | 1383 | mutex_unlock(&dqopt->dqonoff_mutex); |
1383 | /* Sync the superblock so that buffers with quota data are written to | 1384 | /* Sync the superblock so that buffers with quota data are written to |
1384 | * disk (and so userspace sees correct data afterwards). */ | 1385 | * disk (and so userspace sees correct data afterwards). */ |
1385 | if (sb->s_op->sync_fs) | 1386 | if (sb->s_op->sync_fs) |
@@ -1392,7 +1393,7 @@ int vfs_quota_off(struct super_block *sb, int type) | |||
1392 | * changes done by userspace on the next quotaon() */ | 1393 | * changes done by userspace on the next quotaon() */ |
1393 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1394 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1394 | if (toputinode[cnt]) { | 1395 | if (toputinode[cnt]) { |
1395 | down(&dqopt->dqonoff_sem); | 1396 | mutex_lock(&dqopt->dqonoff_mutex); |
1396 | /* If quota was reenabled in the meantime, we have | 1397 | /* If quota was reenabled in the meantime, we have |
1397 | * nothing to do */ | 1398 | * nothing to do */ |
1398 | if (!sb_has_quota_enabled(sb, cnt)) { | 1399 | if (!sb_has_quota_enabled(sb, cnt)) { |
@@ -1404,7 +1405,7 @@ int vfs_quota_off(struct super_block *sb, int type) | |||
1404 | mark_inode_dirty(toputinode[cnt]); | 1405 | mark_inode_dirty(toputinode[cnt]); |
1405 | iput(toputinode[cnt]); | 1406 | iput(toputinode[cnt]); |
1406 | } | 1407 | } |
1407 | up(&dqopt->dqonoff_sem); | 1408 | mutex_unlock(&dqopt->dqonoff_mutex); |
1408 | } | 1409 | } |
1409 | if (sb->s_bdev) | 1410 | if (sb->s_bdev) |
1410 | invalidate_bdev(sb->s_bdev, 0); | 1411 | invalidate_bdev(sb->s_bdev, 0); |
@@ -1445,7 +1446,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | |||
1445 | /* And now flush the block cache so that kernel sees the changes */ | 1446 | /* And now flush the block cache so that kernel sees the changes */ |
1446 | invalidate_bdev(sb->s_bdev, 0); | 1447 | invalidate_bdev(sb->s_bdev, 0); |
1447 | mutex_lock(&inode->i_mutex); | 1448 | mutex_lock(&inode->i_mutex); |
1448 | down(&dqopt->dqonoff_sem); | 1449 | mutex_lock(&dqopt->dqonoff_mutex); |
1449 | if (sb_has_quota_enabled(sb, type)) { | 1450 | if (sb_has_quota_enabled(sb, type)) { |
1450 | error = -EBUSY; | 1451 | error = -EBUSY; |
1451 | goto out_lock; | 1452 | goto out_lock; |
@@ -1470,17 +1471,17 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | |||
1470 | dqopt->ops[type] = fmt->qf_ops; | 1471 | dqopt->ops[type] = fmt->qf_ops; |
1471 | dqopt->info[type].dqi_format = fmt; | 1472 | dqopt->info[type].dqi_format = fmt; |
1472 | INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); | 1473 | INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); |
1473 | down(&dqopt->dqio_sem); | 1474 | mutex_lock(&dqopt->dqio_mutex); |
1474 | if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) { | 1475 | if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) { |
1475 | up(&dqopt->dqio_sem); | 1476 | mutex_unlock(&dqopt->dqio_mutex); |
1476 | goto out_file_init; | 1477 | goto out_file_init; |
1477 | } | 1478 | } |
1478 | up(&dqopt->dqio_sem); | 1479 | mutex_unlock(&dqopt->dqio_mutex); |
1479 | mutex_unlock(&inode->i_mutex); | 1480 | mutex_unlock(&inode->i_mutex); |
1480 | set_enable_flags(dqopt, type); | 1481 | set_enable_flags(dqopt, type); |
1481 | 1482 | ||
1482 | add_dquot_ref(sb, type); | 1483 | add_dquot_ref(sb, type); |
1483 | up(&dqopt->dqonoff_sem); | 1484 | mutex_unlock(&dqopt->dqonoff_mutex); |
1484 | 1485 | ||
1485 | return 0; | 1486 | return 0; |
1486 | 1487 | ||
@@ -1488,7 +1489,7 @@ out_file_init: | |||
1488 | dqopt->files[type] = NULL; | 1489 | dqopt->files[type] = NULL; |
1489 | iput(inode); | 1490 | iput(inode); |
1490 | out_lock: | 1491 | out_lock: |
1491 | up(&dqopt->dqonoff_sem); | 1492 | mutex_unlock(&dqopt->dqonoff_mutex); |
1492 | if (oldflags != -1) { | 1493 | if (oldflags != -1) { |
1493 | down_write(&dqopt->dqptr_sem); | 1494 | down_write(&dqopt->dqptr_sem); |
1494 | /* Set the flags back (in the case of accidental quotaon() | 1495 | /* Set the flags back (in the case of accidental quotaon() |
@@ -1576,14 +1577,14 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d | |||
1576 | { | 1577 | { |
1577 | struct dquot *dquot; | 1578 | struct dquot *dquot; |
1578 | 1579 | ||
1579 | down(&sb_dqopt(sb)->dqonoff_sem); | 1580 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
1580 | if (!(dquot = dqget(sb, id, type))) { | 1581 | if (!(dquot = dqget(sb, id, type))) { |
1581 | up(&sb_dqopt(sb)->dqonoff_sem); | 1582 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1582 | return -ESRCH; | 1583 | return -ESRCH; |
1583 | } | 1584 | } |
1584 | do_get_dqblk(dquot, di); | 1585 | do_get_dqblk(dquot, di); |
1585 | dqput(dquot); | 1586 | dqput(dquot); |
1586 | up(&sb_dqopt(sb)->dqonoff_sem); | 1587 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1587 | return 0; | 1588 | return 0; |
1588 | } | 1589 | } |
1589 | 1590 | ||
@@ -1645,14 +1646,14 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d | |||
1645 | { | 1646 | { |
1646 | struct dquot *dquot; | 1647 | struct dquot *dquot; |
1647 | 1648 | ||
1648 | down(&sb_dqopt(sb)->dqonoff_sem); | 1649 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
1649 | if (!(dquot = dqget(sb, id, type))) { | 1650 | if (!(dquot = dqget(sb, id, type))) { |
1650 | up(&sb_dqopt(sb)->dqonoff_sem); | 1651 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1651 | return -ESRCH; | 1652 | return -ESRCH; |
1652 | } | 1653 | } |
1653 | do_set_dqblk(dquot, di); | 1654 | do_set_dqblk(dquot, di); |
1654 | dqput(dquot); | 1655 | dqput(dquot); |
1655 | up(&sb_dqopt(sb)->dqonoff_sem); | 1656 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1656 | return 0; | 1657 | return 0; |
1657 | } | 1658 | } |
1658 | 1659 | ||
@@ -1661,9 +1662,9 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
1661 | { | 1662 | { |
1662 | struct mem_dqinfo *mi; | 1663 | struct mem_dqinfo *mi; |
1663 | 1664 | ||
1664 | down(&sb_dqopt(sb)->dqonoff_sem); | 1665 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
1665 | if (!sb_has_quota_enabled(sb, type)) { | 1666 | if (!sb_has_quota_enabled(sb, type)) { |
1666 | up(&sb_dqopt(sb)->dqonoff_sem); | 1667 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1667 | return -ESRCH; | 1668 | return -ESRCH; |
1668 | } | 1669 | } |
1669 | mi = sb_dqopt(sb)->info + type; | 1670 | mi = sb_dqopt(sb)->info + type; |
@@ -1673,7 +1674,7 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
1673 | ii->dqi_flags = mi->dqi_flags & DQF_MASK; | 1674 | ii->dqi_flags = mi->dqi_flags & DQF_MASK; |
1674 | ii->dqi_valid = IIF_ALL; | 1675 | ii->dqi_valid = IIF_ALL; |
1675 | spin_unlock(&dq_data_lock); | 1676 | spin_unlock(&dq_data_lock); |
1676 | up(&sb_dqopt(sb)->dqonoff_sem); | 1677 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1677 | return 0; | 1678 | return 0; |
1678 | } | 1679 | } |
1679 | 1680 | ||
@@ -1682,9 +1683,9 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
1682 | { | 1683 | { |
1683 | struct mem_dqinfo *mi; | 1684 | struct mem_dqinfo *mi; |
1684 | 1685 | ||
1685 | down(&sb_dqopt(sb)->dqonoff_sem); | 1686 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
1686 | if (!sb_has_quota_enabled(sb, type)) { | 1687 | if (!sb_has_quota_enabled(sb, type)) { |
1687 | up(&sb_dqopt(sb)->dqonoff_sem); | 1688 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1688 | return -ESRCH; | 1689 | return -ESRCH; |
1689 | } | 1690 | } |
1690 | mi = sb_dqopt(sb)->info + type; | 1691 | mi = sb_dqopt(sb)->info + type; |
@@ -1699,7 +1700,7 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
1699 | mark_info_dirty(sb, type); | 1700 | mark_info_dirty(sb, type); |
1700 | /* Force write to disk */ | 1701 | /* Force write to disk */ |
1701 | sb->dq_op->write_info(sb, type); | 1702 | sb->dq_op->write_info(sb, type); |
1702 | up(&sb_dqopt(sb)->dqonoff_sem); | 1703 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1703 | return 0; | 1704 | return 0; |
1704 | } | 1705 | } |
1705 | 1706 | ||
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 56bf76586019..efa832059143 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -2382,8 +2382,8 @@ static int ext3_statfs (struct super_block * sb, struct kstatfs * buf) | |||
2382 | * Process 1 Process 2 | 2382 | * Process 1 Process 2 |
2383 | * ext3_create() quota_sync() | 2383 | * ext3_create() quota_sync() |
2384 | * journal_start() write_dquot() | 2384 | * journal_start() write_dquot() |
2385 | * DQUOT_INIT() down(dqio_sem) | 2385 | * DQUOT_INIT() down(dqio_mutex) |
2386 | * down(dqio_sem) journal_start() | 2386 | * down(dqio_mutex) journal_start() |
2387 | * | 2387 | * |
2388 | */ | 2388 | */ |
2389 | 2389 | ||
diff --git a/fs/quota.c b/fs/quota.c index ba9e0bf32f67..d6a2be826e29 100644 --- a/fs/quota.c +++ b/fs/quota.c | |||
@@ -170,10 +170,10 @@ static void quota_sync_sb(struct super_block *sb, int type) | |||
170 | 170 | ||
171 | /* Now when everything is written we can discard the pagecache so | 171 | /* Now when everything is written we can discard the pagecache so |
172 | * that userspace sees the changes. We need i_mutex and so we could | 172 | * that userspace sees the changes. We need i_mutex and so we could |
173 | * not do it inside dqonoff_sem. Moreover we need to be carefull | 173 | * not do it inside dqonoff_mutex. Moreover we need to be carefull |
174 | * about races with quotaoff() (that is the reason why we have own | 174 | * about races with quotaoff() (that is the reason why we have own |
175 | * reference to inode). */ | 175 | * reference to inode). */ |
176 | down(&sb_dqopt(sb)->dqonoff_sem); | 176 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
177 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 177 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
178 | discard[cnt] = NULL; | 178 | discard[cnt] = NULL; |
179 | if (type != -1 && cnt != type) | 179 | if (type != -1 && cnt != type) |
@@ -182,7 +182,7 @@ static void quota_sync_sb(struct super_block *sb, int type) | |||
182 | continue; | 182 | continue; |
183 | discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]); | 183 | discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]); |
184 | } | 184 | } |
185 | up(&sb_dqopt(sb)->dqonoff_sem); | 185 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
186 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 186 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
187 | if (discard[cnt]) { | 187 | if (discard[cnt]) { |
188 | mutex_lock(&discard[cnt]->i_mutex); | 188 | mutex_lock(&discard[cnt]->i_mutex); |
diff --git a/fs/quota_v2.c b/fs/quota_v2.c index b4199ec3ece4..c519a583e681 100644 --- a/fs/quota_v2.c +++ b/fs/quota_v2.c | |||
@@ -394,7 +394,7 @@ static int v2_write_dquot(struct dquot *dquot) | |||
394 | ssize_t ret; | 394 | ssize_t ret; |
395 | struct v2_disk_dqblk ddquot, empty; | 395 | struct v2_disk_dqblk ddquot, empty; |
396 | 396 | ||
397 | /* dq_off is guarded by dqio_sem */ | 397 | /* dq_off is guarded by dqio_mutex */ |
398 | if (!dquot->dq_off) | 398 | if (!dquot->dq_off) |
399 | if ((ret = dq_insert_tree(dquot)) < 0) { | 399 | if ((ret = dq_insert_tree(dquot)) < 0) { |
400 | printk(KERN_ERR "VFS: Error %zd occurred while creating quota.\n", ret); | 400 | printk(KERN_ERR "VFS: Error %zd occurred while creating quota.\n", ret); |
diff --git a/fs/super.c b/fs/super.c index 8f9c9b3af70c..9cc6545dfa4c 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -77,8 +77,8 @@ static struct super_block *alloc_super(void) | |||
77 | s->s_count = S_BIAS; | 77 | s->s_count = S_BIAS; |
78 | atomic_set(&s->s_active, 1); | 78 | atomic_set(&s->s_active, 1); |
79 | sema_init(&s->s_vfs_rename_sem,1); | 79 | sema_init(&s->s_vfs_rename_sem,1); |
80 | sema_init(&s->s_dquot.dqio_sem, 1); | 80 | mutex_init(&s->s_dquot.dqio_mutex); |
81 | sema_init(&s->s_dquot.dqonoff_sem, 1); | 81 | mutex_init(&s->s_dquot.dqonoff_mutex); |
82 | init_rwsem(&s->s_dquot.dqptr_sem); | 82 | init_rwsem(&s->s_dquot.dqptr_sem); |
83 | init_waitqueue_head(&s->s_wait_unfrozen); | 83 | init_waitqueue_head(&s->s_wait_unfrozen); |
84 | s->s_maxbytes = MAX_NON_LFS; | 84 | s->s_maxbytes = MAX_NON_LFS; |
diff --git a/include/linux/quota.h b/include/linux/quota.h index f33aeb22c26a..8dc2d04a103f 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/errno.h> | 38 | #include <linux/errno.h> |
39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
40 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
41 | #include <linux/mutex.h> | ||
41 | 42 | ||
42 | #define __DQUOT_VERSION__ "dquot_6.5.1" | 43 | #define __DQUOT_VERSION__ "dquot_6.5.1" |
43 | #define __DQUOT_NUM_VERSION__ 6*10000+5*100+1 | 44 | #define __DQUOT_NUM_VERSION__ 6*10000+5*100+1 |
@@ -215,7 +216,7 @@ struct dquot { | |||
215 | struct list_head dq_inuse; /* List of all quotas */ | 216 | struct list_head dq_inuse; /* List of all quotas */ |
216 | struct list_head dq_free; /* Free list element */ | 217 | struct list_head dq_free; /* Free list element */ |
217 | struct list_head dq_dirty; /* List of dirty dquots */ | 218 | struct list_head dq_dirty; /* List of dirty dquots */ |
218 | struct semaphore dq_lock; /* dquot IO lock */ | 219 | struct mutex dq_lock; /* dquot IO lock */ |
219 | atomic_t dq_count; /* Use count */ | 220 | atomic_t dq_count; /* Use count */ |
220 | wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */ | 221 | wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */ |
221 | struct super_block *dq_sb; /* superblock this applies to */ | 222 | struct super_block *dq_sb; /* superblock this applies to */ |
@@ -285,8 +286,8 @@ struct quota_format_type { | |||
285 | 286 | ||
286 | struct quota_info { | 287 | struct quota_info { |
287 | unsigned int flags; /* Flags for diskquotas on this device */ | 288 | unsigned int flags; /* Flags for diskquotas on this device */ |
288 | struct semaphore dqio_sem; /* lock device while I/O in progress */ | 289 | struct mutex dqio_mutex; /* lock device while I/O in progress */ |
289 | struct semaphore dqonoff_sem; /* Serialize quotaon & quotaoff */ | 290 | struct mutex dqonoff_mutex; /* Serialize quotaon & quotaoff */ |
290 | struct rw_semaphore dqptr_sem; /* serialize ops using quota_info struct, pointers from inode to dquots */ | 291 | struct rw_semaphore dqptr_sem; /* serialize ops using quota_info struct, pointers from inode to dquots */ |
291 | struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */ | 292 | struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */ |
292 | struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ | 293 | struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ |