X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Fdquot.c;h=0122a279106a9dd4a0475557901471be5c428546;hb=e7515d065d09f6450c996a8fa206ad66569e183c;hp=9376a4378988b0d9217edfc39010975b2def6719;hpb=6362e4d4eda61efb04ac1cdae32e48ac6d90b701;p=linux-2.6 diff --git a/fs/dquot.c b/fs/dquot.c index 9376a43789..0122a27910 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -103,12 +103,12 @@ * (these locking rules also apply for S_NOQUOTA flag in the inode - note that * for altering the flag i_mutex is also needed). If operation is holding * reference to dquot in other way (e.g. quotactl ops) it must be guarded by - * dqonoff_sem. + * dqonoff_mutex. * This locking assures that: * a) update/access to dquot pointers in inode is serialized * b) everyone is guarded against invalidate_dquots() * - * Each dquot has its dq_lock semaphore. Locked dquots might not be referenced + * Each dquot has its dq_lock mutex. Locked dquots might not be referenced * from inodes (dquot_alloc_space() and such don't check the dq_lock). * Currently dquot is locked only when it is being read to memory (or space for * it is being allocated) on the first dqget() and when it is being released on @@ -118,8 +118,9 @@ * spinlock to internal buffers before writing. * * Lock ordering (including related VFS locks) is the following: - * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > dqio_sem - * i_mutex on quota files is special (it's below dqio_sem) + * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > + * dqio_mutex + * i_mutex on quota files is special (it's below dqio_mutex) */ static DEFINE_SPINLOCK(dq_list_lock); @@ -249,7 +250,7 @@ static inline struct dquot *find_dquot(unsigned int hashent, struct super_block /* Add a dquot to the tail of the free list */ static inline void put_dquot_last(struct dquot *dquot) { - list_add(&dquot->dq_free, free_dquots.prev); + list_add_tail(&dquot->dq_free, &free_dquots); dqstats.free_dquots++; } @@ -265,7 +266,7 @@ static inline void put_inuse(struct dquot *dquot) { /* We add to the back of inuse list so we don't have to restart * when traversing this list and we block */ - list_add(&dquot->dq_inuse, inuse_list.prev); + list_add_tail(&dquot->dq_inuse, &inuse_list); dqstats.allocated_dquots++; } @@ -280,8 +281,8 @@ static inline void remove_inuse(struct dquot *dquot) static void wait_on_dquot(struct dquot *dquot) { - down(&dquot->dq_lock); - up(&dquot->dq_lock); + mutex_lock(&dquot->dq_lock); + mutex_unlock(&dquot->dq_lock); } #define mark_dquot_dirty(dquot) ((dquot)->dq_sb->dq_op->mark_dirty(dquot)) @@ -320,8 +321,8 @@ int dquot_acquire(struct dquot *dquot) int ret = 0, ret2 = 0; struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); - down(&dquot->dq_lock); - down(&dqopt->dqio_sem); + mutex_lock(&dquot->dq_lock); + mutex_lock(&dqopt->dqio_mutex); if (!test_bit(DQ_READ_B, &dquot->dq_flags)) ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot); if (ret < 0) @@ -342,8 +343,8 @@ int dquot_acquire(struct dquot *dquot) } set_bit(DQ_ACTIVE_B, &dquot->dq_flags); out_iolock: - up(&dqopt->dqio_sem); - up(&dquot->dq_lock); + mutex_unlock(&dqopt->dqio_mutex); + mutex_unlock(&dquot->dq_lock); return ret; } @@ -355,7 +356,7 @@ int dquot_commit(struct dquot *dquot) int ret = 0, ret2 = 0; struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); - down(&dqopt->dqio_sem); + mutex_lock(&dqopt->dqio_mutex); spin_lock(&dq_list_lock); if (!clear_dquot_dirty(dquot)) { spin_unlock(&dq_list_lock); @@ -372,7 +373,7 @@ int dquot_commit(struct dquot *dquot) ret = ret2; } out_sem: - up(&dqopt->dqio_sem); + mutex_unlock(&dqopt->dqio_mutex); return ret; } @@ -384,11 +385,11 @@ int dquot_release(struct dquot *dquot) int ret = 0, ret2 = 0; struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); - down(&dquot->dq_lock); + mutex_lock(&dquot->dq_lock); /* Check whether we are not racing with some other dqget() */ if (atomic_read(&dquot->dq_count) > 1) goto out_dqlock; - down(&dqopt->dqio_sem); + mutex_lock(&dqopt->dqio_mutex); if (dqopt->ops[dquot->dq_type]->release_dqblk) { ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot); /* Write the info */ @@ -398,9 +399,9 @@ int dquot_release(struct dquot *dquot) ret = ret2; } clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); - up(&dqopt->dqio_sem); + mutex_unlock(&dqopt->dqio_mutex); out_dqlock: - up(&dquot->dq_lock); + mutex_unlock(&dquot->dq_lock); return ret; } @@ -464,7 +465,7 @@ int vfs_quota_sync(struct super_block *sb, int type) struct quota_info *dqopt = sb_dqopt(sb); int cnt; - down(&dqopt->dqonoff_sem); + mutex_lock(&dqopt->dqonoff_mutex); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (type != -1 && cnt != type) continue; @@ -499,7 +500,7 @@ int vfs_quota_sync(struct super_block *sb, int type) spin_lock(&dq_list_lock); dqstats.syncs++; spin_unlock(&dq_list_lock); - up(&dqopt->dqonoff_sem); + mutex_unlock(&dqopt->dqonoff_mutex); return 0; } @@ -540,7 +541,7 @@ static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) /* * Put reference to dquot * NOTE: If you change this function please check whether dqput_blocks() works right... - * MUST be called with either dqptr_sem or dqonoff_sem held + * MUST be called with either dqptr_sem or dqonoff_mutex held */ static void dqput(struct dquot *dquot) { @@ -589,8 +590,7 @@ we_slept: atomic_dec(&dquot->dq_count); #ifdef __DQUOT_PARANOIA /* sanity check */ - if (!list_empty(&dquot->dq_free)) - BUG(); + BUG_ON(!list_empty(&dquot->dq_free)); #endif put_dquot_last(dquot); spin_unlock(&dq_list_lock); @@ -605,7 +605,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) return NODQUOT; memset((caddr_t)dquot, 0, sizeof(struct dquot)); - sema_init(&dquot->dq_lock, 1); + mutex_init(&dquot->dq_lock); INIT_LIST_HEAD(&dquot->dq_free); INIT_LIST_HEAD(&dquot->dq_inuse); INIT_HLIST_NODE(&dquot->dq_hash); @@ -620,7 +620,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) /* * Get reference to dquot - * MUST be called with either dqptr_sem or dqonoff_sem held + * MUST be called with either dqptr_sem or dqonoff_mutex held */ static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) { @@ -665,8 +665,7 @@ we_slept: return NODQUOT; } #ifdef __DQUOT_PARANOIA - if (!dquot->dq_sb) /* Has somebody invalidated entry under us? */ - BUG(); + BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ #endif return dquot; @@ -686,7 +685,7 @@ static int dqinit_needed(struct inode *inode, int type) return 0; } -/* This routine is guarded by dqonoff_sem semaphore */ +/* This routine is guarded by dqonoff_mutex mutex */ static void add_dquot_ref(struct super_block *sb, int type) { struct list_head *p; @@ -964,8 +963,8 @@ int dquot_initialize(struct inode *inode, int type) unsigned int id = 0; int cnt, ret = 0; - /* First test before acquiring semaphore - solves deadlocks when we - * re-enter the quota code and are already holding the semaphore */ + /* First test before acquiring mutex - solves deadlocks when we + * re-enter the quota code and are already holding the mutex */ if (IS_NOQUOTA(inode)) return 0; down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); @@ -1028,8 +1027,8 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) int cnt, ret = NO_QUOTA; char warntype[MAXQUOTAS]; - /* First test before acquiring semaphore - solves deadlocks when we - * re-enter the quota code and are already holding the semaphore */ + /* First test before acquiring mutex - solves deadlocks when we + * re-enter the quota code and are already holding the mutex */ if (IS_NOQUOTA(inode)) { out_add: inode_add_bytes(inode, number); @@ -1077,8 +1076,8 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number) int cnt, ret = NO_QUOTA; char warntype[MAXQUOTAS]; - /* First test before acquiring semaphore - solves deadlocks when we - * re-enter the quota code and are already holding the semaphore */ + /* First test before acquiring mutex - solves deadlocks when we + * re-enter the quota code and are already holding the mutex */ if (IS_NOQUOTA(inode)) return QUOTA_OK; for (cnt = 0; cnt < MAXQUOTAS; cnt++) @@ -1121,8 +1120,8 @@ int dquot_free_space(struct inode *inode, qsize_t number) { unsigned int cnt; - /* First test before acquiring semaphore - solves deadlocks when we - * re-enter the quota code and are already holding the semaphore */ + /* First test before acquiring mutex - solves deadlocks when we + * re-enter the quota code and are already holding the mutex */ if (IS_NOQUOTA(inode)) { out_sub: inode_sub_bytes(inode, number); @@ -1157,8 +1156,8 @@ int dquot_free_inode(const struct inode *inode, unsigned long number) { unsigned int cnt; - /* First test before acquiring semaphore - solves deadlocks when we - * re-enter the quota code and are already holding the semaphore */ + /* First test before acquiring mutex - solves deadlocks when we + * re-enter the quota code and are already holding the mutex */ if (IS_NOQUOTA(inode)) return QUOTA_OK; down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); @@ -1197,8 +1196,8 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid; char warntype[MAXQUOTAS]; - /* First test before acquiring semaphore - solves deadlocks when we - * re-enter the quota code and are already holding the semaphore */ + /* First test before acquiring mutex - solves deadlocks when we + * re-enter the quota code and are already holding the mutex */ if (IS_NOQUOTA(inode)) return QUOTA_OK; /* Clear the arrays */ @@ -1292,9 +1291,9 @@ int dquot_commit_info(struct super_block *sb, int type) int ret; struct quota_info *dqopt = sb_dqopt(sb); - down(&dqopt->dqio_sem); + mutex_lock(&dqopt->dqio_mutex); ret = dqopt->ops[type]->write_file_info(sb, type); - up(&dqopt->dqio_sem); + mutex_unlock(&dqopt->dqio_mutex); return ret; } @@ -1350,7 +1349,7 @@ int vfs_quota_off(struct super_block *sb, int type) struct inode *toputinode[MAXQUOTAS]; /* We need to serialize quota_off() for device */ - down(&dqopt->dqonoff_sem); + mutex_lock(&dqopt->dqonoff_mutex); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { toputinode[cnt] = NULL; if (type != -1 && cnt != type) @@ -1379,7 +1378,7 @@ int vfs_quota_off(struct super_block *sb, int type) dqopt->info[cnt].dqi_bgrace = 0; dqopt->ops[cnt] = NULL; } - up(&dqopt->dqonoff_sem); + mutex_unlock(&dqopt->dqonoff_mutex); /* Sync the superblock so that buffers with quota data are written to * disk (and so userspace sees correct data afterwards). */ if (sb->s_op->sync_fs) @@ -1392,7 +1391,7 @@ int vfs_quota_off(struct super_block *sb, int type) * changes done by userspace on the next quotaon() */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) if (toputinode[cnt]) { - down(&dqopt->dqonoff_sem); + mutex_lock(&dqopt->dqonoff_mutex); /* If quota was reenabled in the meantime, we have * nothing to do */ if (!sb_has_quota_enabled(sb, cnt)) { @@ -1404,7 +1403,7 @@ int vfs_quota_off(struct super_block *sb, int type) mark_inode_dirty(toputinode[cnt]); iput(toputinode[cnt]); } - up(&dqopt->dqonoff_sem); + mutex_unlock(&dqopt->dqonoff_mutex); } if (sb->s_bdev) invalidate_bdev(sb->s_bdev, 0); @@ -1445,7 +1444,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) /* And now flush the block cache so that kernel sees the changes */ invalidate_bdev(sb->s_bdev, 0); mutex_lock(&inode->i_mutex); - down(&dqopt->dqonoff_sem); + mutex_lock(&dqopt->dqonoff_mutex); if (sb_has_quota_enabled(sb, type)) { error = -EBUSY; goto out_lock; @@ -1470,17 +1469,17 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) dqopt->ops[type] = fmt->qf_ops; dqopt->info[type].dqi_format = fmt; INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); - down(&dqopt->dqio_sem); + mutex_lock(&dqopt->dqio_mutex); if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) { - up(&dqopt->dqio_sem); + mutex_unlock(&dqopt->dqio_mutex); goto out_file_init; } - up(&dqopt->dqio_sem); + mutex_unlock(&dqopt->dqio_mutex); mutex_unlock(&inode->i_mutex); set_enable_flags(dqopt, type); add_dquot_ref(sb, type); - up(&dqopt->dqonoff_sem); + mutex_unlock(&dqopt->dqonoff_mutex); return 0; @@ -1488,7 +1487,7 @@ out_file_init: dqopt->files[type] = NULL; iput(inode); out_lock: - up(&dqopt->dqonoff_sem); + mutex_unlock(&dqopt->dqonoff_mutex); if (oldflags != -1) { down_write(&dqopt->dqptr_sem); /* Set the flags back (in the case of accidental quotaon() @@ -1576,14 +1575,14 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d { struct dquot *dquot; - down(&sb_dqopt(sb)->dqonoff_sem); + mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); if (!(dquot = dqget(sb, id, type))) { - up(&sb_dqopt(sb)->dqonoff_sem); + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return -ESRCH; } do_get_dqblk(dquot, di); dqput(dquot); - up(&sb_dqopt(sb)->dqonoff_sem); + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return 0; } @@ -1645,14 +1644,14 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d { struct dquot *dquot; - down(&sb_dqopt(sb)->dqonoff_sem); + mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); if (!(dquot = dqget(sb, id, type))) { - up(&sb_dqopt(sb)->dqonoff_sem); + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return -ESRCH; } do_set_dqblk(dquot, di); dqput(dquot); - up(&sb_dqopt(sb)->dqonoff_sem); + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return 0; } @@ -1661,9 +1660,9 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) { struct mem_dqinfo *mi; - down(&sb_dqopt(sb)->dqonoff_sem); + mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); if (!sb_has_quota_enabled(sb, type)) { - up(&sb_dqopt(sb)->dqonoff_sem); + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return -ESRCH; } mi = sb_dqopt(sb)->info + type; @@ -1673,7 +1672,7 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) ii->dqi_flags = mi->dqi_flags & DQF_MASK; ii->dqi_valid = IIF_ALL; spin_unlock(&dq_data_lock); - up(&sb_dqopt(sb)->dqonoff_sem); + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return 0; } @@ -1682,9 +1681,9 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) { struct mem_dqinfo *mi; - down(&sb_dqopt(sb)->dqonoff_sem); + mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); if (!sb_has_quota_enabled(sb, type)) { - up(&sb_dqopt(sb)->dqonoff_sem); + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return -ESRCH; } mi = sb_dqopt(sb)->info + type; @@ -1699,7 +1698,7 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) mark_info_dirty(sb, type); /* Force write to disk */ sb->dq_op->write_info(sb, type); - up(&sb_dqopt(sb)->dqonoff_sem); + mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return 0; } @@ -1820,7 +1819,8 @@ static int __init dquot_init(void) dquot_cachep = kmem_cache_create("dquot", sizeof(struct dquot), sizeof(unsigned long) * 4, - SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC, + (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| + SLAB_MEM_SPREAD|SLAB_PANIC), NULL, NULL); order = 0;