--- linux-2.6.16-rc1/block/ioctl.c 2006-01-26 22:34:51 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/block/ioctl.c 2006-01-29 15:57:21 +0100 @@ -246,6 +246,13 @@ int blkdev_ioctl(struct inode *inode, st set_device_ro(bdev, n); unlock_kernel(); return 0; + + case BLKHOLDER: + printk("bdev[%p]: holder=%p[%d]\n", bdev, bdev->bd_holder, bdev->bd_holders); + if (bdev->bd_holder && bdev->bd_holders) + return -EBUSY; + return 0; + case HDIO_GETGEO: { struct hd_geometry geo; --- linux-2.6.16-rc1/fs/buffer.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/buffer.c 2006-01-21 18:28:18 +0100 @@ -168,7 +168,7 @@ EXPORT_SYMBOL(sync_blockdev); int fsync_super(struct super_block *sb) { sync_inodes_sb(sb, 0); - DQUOT_SYNC(sb); + DQUOT_SYNC(sb->s_dqh); lock_super(sb); if (sb->s_dirt && sb->s_op->write_super) sb->s_op->write_super(sb); --- linux-2.6.16-rc1/fs/buffer.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/buffer.c 2006-01-21 18:28:18 +0100 @@ -217,7 +217,7 @@ struct super_block *freeze_bdev(struct b smp_wmb(); sync_inodes_sb(sb, 0); - DQUOT_SYNC(sb); + DQUOT_SYNC(sb->s_dqh); lock_super(sb); if (sb->s_dirt && sb->s_op->write_super) --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -185,7 +187,7 @@ static void put_quota_format(struct quot /* * Dquot List Management: * The quota code uses three lists for dquot management: the inuse_list, - * free_dquots, and dquot_hash[] array. A single dquot structure may be + * free_dquots, and hash->dqh_hash[] array. A single dquot structure may be * on all three lists, depending on its current state. * * All dquots are placed to the end of inuse_list when first created, and this --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -198,7 +200,7 @@ static void put_quota_format(struct quot * dquot is invalidated it's completely released from memory. * * Dquots with a specific identity (device, type and id) are placed on - * one of the dquot_hash[] hash chains. The provides an efficient search + * one of the hash->dqh_hash[] hash chains. The provides an efficient search * mechanism to locate a specific dquot. */ --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -212,7 +214,7 @@ struct dqstats dqstats; static void dqput(struct dquot *dquot); static inline unsigned int -hashfn(const struct super_block *sb, unsigned int id, int type) +hashfn(struct dqhash *hash, unsigned int id, int type) { unsigned long tmp; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -216,7 +218,7 @@ ***** { unsigned long tmp; - tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type); + tmp = (((unsigned long)hash >> L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type); return (tmp + (tmp >> dq_hash_bits)) & dq_hash_mask; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -223,10 +225,14 @@ ***** /* * Following list functions expect dq_list_lock to be held */ -static inline void insert_dquot_hash(struct dquot *dquot) +static inline void insert_dquot_hash(struct dqhash *hash, struct dquot *dquot) { - struct hlist_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type); + struct hlist_head *head = dquot_hash + + hashfn(hash, dquot->dq_id, dquot->dq_type); + /* struct hlist_head *head = hash->dqh_hash + + hashfn(dquot->dq_dqh, dquot->dq_id, dquot->dq_type); */ hlist_add_head(&dquot->dq_hash, head); + dquot->dq_dqh = dqhget(hash); } static inline void remove_dquot_hash(struct dquot *dquot) --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -232,9 +238,12 @@ ***** static inline void remove_dquot_hash(struct dquot *dquot) { hlist_del_init(&dquot->dq_hash); + dqhput(dquot->dq_dqh); + dquot->dq_dqh = NULL; } -static inline struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, unsigned int id, int type) +static inline struct dquot *find_dquot(struct dqhash *hash, + unsigned int hashent, unsigned int id, int type) { struct hlist_node *node; struct dquot *dquot; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -239,9 +248,10 @@ ***** struct hlist_node *node; struct dquot *dquot; - hlist_for_each (node, dquot_hash+hashent) { + /* hlist_for_each (node, hash->dqh_hash + hashent) { */ + hlist_for_each (node, dquot_hash + hashent) { dquot = hlist_entry(node, struct dquot, dq_hash); - if (dquot->dq_sb == sb && dquot->dq_id == id && dquot->dq_type == type) + if (dquot->dq_dqh == hash && dquot->dq_id == id && dquot->dq_type == type) return dquot; } return NODQUOT; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -285,7 +295,7 @@ static void wait_on_dquot(struct dquot * up(&dquot->dq_lock); } -#define mark_dquot_dirty(dquot) ((dquot)->dq_sb->dq_op->mark_dirty(dquot)) +#define mark_dquot_dirty(dquot) ((dquot)->dq_dqh->dqh_qop->mark_dirty(dquot)) int dquot_mark_dquot_dirty(struct dquot *dquot) { --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -291,7 +301,7 @@ ***** { spin_lock(&dq_list_lock); if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags)) - list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)-> + list_add(&dquot->dq_dirty, &dqh_dqopt(dquot->dq_dqh)-> info[dquot->dq_type].dqi_dirty_list); spin_unlock(&dq_list_lock); return 0; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -306,9 +316,9 @@ static inline int clear_dquot_dirty(stru return 1; } -void mark_info_dirty(struct super_block *sb, int type) +void mark_info_dirty(struct dqhash *hash, int type) { - set_bit(DQF_INFO_DIRTY_B, &sb_dqopt(sb)->info[type].dqi_flags); + set_bit(DQF_INFO_DIRTY_B, &dqh_dqopt(hash)->info[type].dqi_flags); } EXPORT_SYMBOL(mark_info_dirty); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -319,7 +329,7 @@ EXPORT_SYMBOL(mark_info_dirty); int dquot_acquire(struct dquot *dquot) { int ret = 0, ret2 = 0; - struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); + struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh); down(&dquot->dq_lock); down(&dqopt->dqio_sem); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -333,7 +343,7 @@ int dquot_acquire(struct dquot *dquot) ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); /* Write the info if needed */ if (info_dirty(&dqopt->info[dquot->dq_type])) - ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type); + ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type); if (ret < 0) goto out_iolock; if (ret2 < 0) { --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -354,7 +364,7 @@ out_iolock: int dquot_commit(struct dquot *dquot) { int ret = 0, ret2 = 0; - struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); + struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh); down(&dqopt->dqio_sem); spin_lock(&dq_list_lock); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -368,7 +378,7 @@ int dquot_commit(struct dquot *dquot) if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); if (info_dirty(&dqopt->info[dquot->dq_type])) - ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type); + ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type); if (ret >= 0) ret = ret2; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -383,7 +393,7 @@ out_sem: int dquot_release(struct dquot *dquot) { int ret = 0, ret2 = 0; - struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); + struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh); down(&dquot->dq_lock); /* Check whether we are not racing with some other dqget() */ --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -394,7 +404,7 @@ int dquot_release(struct dquot *dquot) ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot); /* Write the info */ if (info_dirty(&dqopt->info[dquot->dq_type])) - ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type); + ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type); if (ret >= 0) ret = ret2; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -409,7 +419,7 @@ out_dqlock: * quota is disabled and pointers from inodes removed so there cannot be new * quota users. Also because we hold dqonoff_sem there can be no quota users * for this sb+type at all. */ -static void invalidate_dquots(struct super_block *sb, int type) +static void invalidate_dquots(struct dqhash *hash, int type) { struct dquot *dquot, *tmp; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -415,7 +425,7 @@ ***** spin_lock(&dq_list_lock); list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) { - if (dquot->dq_sb != sb) + if (dquot->dq_dqh != hash) continue; if (dquot->dq_type != type) continue; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -432,7 +442,83 @@ static void invalidate_dquots(struct sup spin_unlock(&dq_list_lock); } -int vfs_quota_sync(struct super_block *sb, int type) + +/* Dquota Hash Management Functions */ + +static LIST_HEAD(dqhash_list); + +struct dqhash *new_dqhash(struct super_block *sb, unsigned int id) +{ + struct dqhash *hash; + int err; + + err = -ENOMEM; + hash = kmalloc(sizeof(struct dqhash), GFP_USER); + if (!hash) + goto out; + + memset(hash, 0, sizeof(struct dqhash)); + hash->dqh_id = id; + atomic_set(&hash->dqh_count, 1); + + INIT_LIST_HEAD(&hash->dqh_list); + + sema_init(&hash->dqh_dqopt.dqio_sem, 1); + sema_init(&hash->dqh_dqopt.dqonoff_sem, 1); + init_rwsem(&hash->dqh_dqopt.dqptr_sem); + hash->dqh_qop = sb->s_qop; + hash->dqh_qcop = sb->s_qcop; + hash->dqh_sb = sb; + + lock_kernel(); + list_add(&hash->dqh_list, &dqhash_list); + unlock_kernel(); + vxdprintk(VXD_CBIT(misc, 0), + "new_dqhash: %p [#0x%08x]", hash, hash->dqh_id); + return hash; + + // kfree(hash); +out: + return ERR_PTR(err); +} + +void destroy_dqhash(struct dqhash *hash) +{ + int cnt; + + vxdprintk(VXD_CBIT(misc, 0), + "destroy_dqhash: %p [#0x%08x] c=%d", + hash, hash->dqh_id, atomic_read(&hash->dqh_count)); + lock_kernel(); + list_del_init(&hash->dqh_list); + unlock_kernel(); + for (cnt = 0; cnt < MAXQUOTAS; cnt++) /* should not be required anymore! */ + invalidate_dquots(hash, cnt); + kfree(hash); +} + + +struct dqhash *find_dqhash(unsigned int id) +{ + struct list_head *head; + struct dqhash *hash; + + lock_kernel(); + list_for_each(head, &dqhash_list) { + hash = list_entry(head, struct dqhash, dqh_list); + if (hash->dqh_id == id) + goto dqh_found; + } + unlock_kernel(); + return NULL; + +dqh_found: + unlock_kernel(); + return dqhget(hash); +} + + +int vfs_quota_sync(struct dqhash *hash, int type) { struct list_head *dirty; struct dquot *dquot; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -436,7 +522,7 @@ ***** { struct list_head *dirty; struct dquot *dquot; - struct quota_info *dqopt = sb_dqopt(sb); + struct quota_info *dqopt = dqh_dqopt(hash); int cnt; down(&dqopt->dqonoff_sem); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -443,7 +529,7 @@ ***** for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (type != -1 && cnt != type) continue; - if (!sb_has_quota_enabled(sb, cnt)) + if (!dqh_has_quota_enabled(hash, cnt)) continue; spin_lock(&dq_list_lock); dirty = &dqopt->info[cnt].dqi_dirty_list; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -460,7 +546,7 @@ int vfs_quota_sync(struct super_block *s atomic_inc(&dquot->dq_count); dqstats.lookups++; spin_unlock(&dq_list_lock); - sb->dq_op->write_dquot(dquot); + hash->dqh_qop->write_dquot(dquot); dqput(dquot); spin_lock(&dq_list_lock); } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -468,9 +554,10 @@ int vfs_quota_sync(struct super_block *s } for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt) + if ((cnt == type || type == -1) + && dqh_has_quota_enabled(hash, cnt) && info_dirty(&dqopt->info[cnt])) - sb->dq_op->write_info(sb, cnt); + hash->dqh_qop->write_info(hash, cnt); spin_lock(&dq_list_lock); dqstats.syncs++; spin_unlock(&dq_list_lock); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -525,7 +612,7 @@ static void dqput(struct dquot *dquot) if (!atomic_read(&dquot->dq_count)) { printk("VFS: dqput: trying to free free dquot\n"); printk("VFS: device %s, dquot of %s %d\n", - dquot->dq_sb->s_id, + dquot->dq_dqh->dqh_sb->s_id, quotatypes[dquot->dq_type], dquot->dq_id); BUG(); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -547,7 +634,7 @@ we_slept: if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) { spin_unlock(&dq_list_lock); /* Commit dquot before releasing */ - dquot->dq_sb->dq_op->write_dquot(dquot); + dquot->dq_dqh->dqh_qop->write_dquot(dquot); goto we_slept; } /* Clear flag in case dquot was inactive (something bad happened) */ --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -554,7 +641,7 @@ ***** clear_dquot_dirty(dquot); if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { spin_unlock(&dq_list_lock); - dquot->dq_sb->dq_op->release_dquot(dquot); + dquot->dq_dqh->dqh_qop->release_dquot(dquot); goto we_slept; } atomic_dec(&dquot->dq_count); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -567,7 +654,7 @@ we_slept: spin_unlock(&dq_list_lock); } -static struct dquot *get_empty_dquot(struct super_block *sb, int type) +static struct dquot *get_empty_dquot(int type) { struct dquot *dquot; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -581,7 +668,7 @@ static struct dquot *get_empty_dquot(str INIT_LIST_HEAD(&dquot->dq_inuse); INIT_HLIST_NODE(&dquot->dq_hash); INIT_LIST_HEAD(&dquot->dq_dirty); - dquot->dq_sb = sb; + dquot->dq_dqh = NULL; dquot->dq_type = type; atomic_set(&dquot->dq_count, 1); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -592,12 +679,12 @@ static struct dquot *get_empty_dquot(str * Get reference to dquot * MUST be called with either dqptr_sem or dqonoff_sem held */ -static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) +static struct dquot *dqget(struct dqhash *hash, unsigned int id, int type) { - unsigned int hashent = hashfn(sb, id, type); + unsigned int hashent = hashfn(hash, id, type); struct dquot *dquot, *empty = NODQUOT; - if (!sb_has_quota_enabled(sb, type)) + if (!dqh_has_quota_enabled(hash, type)) return NODQUOT; we_slept: spin_lock(&dq_list_lock); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -601,10 +688,10 @@ ***** return NODQUOT; we_slept: spin_lock(&dq_list_lock); - if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) { + if ((dquot = find_dquot(hash, hashent, id, type)) == NODQUOT) { if (empty == NODQUOT) { spin_unlock(&dq_list_lock); - if ((empty = get_empty_dquot(sb, type)) == NODQUOT) + if ((empty = get_empty_dquot(type)) == NODQUOT) schedule(); /* Try to wait for a moment... */ goto we_slept; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -613,7 +700,7 @@ we_slept: /* all dquots go on the inuse_list */ put_inuse(dquot); /* hash it first so it can be found */ - insert_dquot_hash(dquot); + insert_dquot_hash(hash, dquot); dqstats.lookups++; spin_unlock(&dq_list_lock); } else { --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -630,7 +717,8 @@ we_slept: * finished or it will be canceled due to dq_count > 1 test */ wait_on_dquot(dquot); /* Read the dquot and instantiate it (everything done only if needed) */ - if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) { + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && + hash->dqh_qop->acquire_dquot(dquot) < 0) { dqput(dquot); return NODQUOT; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -635,7 +723,7 @@ ***** return NODQUOT; } #ifdef __DQUOT_PARANOIA - if (!dquot->dq_sb) /* Has somebody invalidated entry under us? */ + if (!dquot->dq_dqh) /* Has somebody invalidated entry under us? */ BUG(); #endif --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -657,9 +745,10 @@ static int dqinit_needed(struct inode *i } /* This routine is guarded by dqonoff_sem semaphore */ -static void add_dquot_ref(struct super_block *sb, int type) +static void add_dquot_ref(struct dqhash *hash, int type) { struct list_head *p; + struct super_block *sb = hash->dqh_sb; restart: file_list_lock(); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -669,7 +758,7 @@ restart: if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) { struct dentry *dentry = dget(filp->f_dentry); file_list_unlock(); - sb->dq_op->initialize(inode, type); + hash->dqh_qop->initialize(inode, type); dput(dentry); /* As we may have blocked we had better restart... */ goto restart; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -728,7 +817,7 @@ static void put_dquot_list(struct list_h } /* Gather all references from inodes and drop them */ -static void drop_dquot_ref(struct super_block *sb, int type) +static void drop_dquot_ref(struct dqhash *hash, int type) { LIST_HEAD(tofree_head); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -735,9 +824,9 @@ ***** /* We need to be guarded against prune_icache to reach all the * inodes - otherwise some can be on the local list of prune_icache */ down(&iprune_sem); - down_write(&sb_dqopt(sb)->dqptr_sem); - remove_dquot_ref(sb, type, &tofree_head); - up_write(&sb_dqopt(sb)->dqptr_sem); + down_write(&dqh_dqopt(hash)->dqptr_sem); + remove_dquot_ref(hash, type, &tofree_head); + up_write(&dqh_dqopt(hash)->dqptr_sem); up(&iprune_sem); put_dquot_list(&tofree_head); } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -809,7 +898,7 @@ static void print_warning(struct dquot * if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags))) return; - tty_write_message(current->signal->tty, dquot->dq_sb->s_id); + tty_write_message(current->signal->tty, dquot->dq_dqh->dqh_sb->s_id); if (warntype == ISOFTWARN || warntype == BSOFTWARN) tty_write_message(current->signal->tty, ": warning, "); else --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -849,7 +938,7 @@ static inline void flush_warnings(struct static inline char ignore_hardlimit(struct dquot *dquot) { - struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; + struct mem_dqinfo *info = &dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type]; return capable(CAP_SYS_RESOURCE) && (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || !(info->dqi_flags & V1_DQF_RSQUASH)); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -881,7 +970,7 @@ static int check_idq(struct dquot *dquot (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit && dquot->dq_dqb.dqb_itime == 0) { *warntype = ISOFTWARN; - dquot->dq_dqb.dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; + dquot->dq_dqb.dqb_itime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_igrace; } return QUOTA_OK; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -916,7 +1005,7 @@ static int check_bdq(struct dquot *dquot dquot->dq_dqb.dqb_btime == 0) { if (!prealloc) { *warntype = BSOFTWARN; - dquot->dq_dqb.dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace; + dquot->dq_dqb.dqb_btime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_bgrace; } else /* --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -942,7 +1031,7 @@ int dquot_initialize(struct inode *inode * re-enter the quota code and are already holding the semaphore */ if (IS_NOQUOTA(inode)) return 0; - down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem); /* Having dqptr_sem we know NOQUOTA flags can't be altered... */ if (IS_NOQUOTA(inode)) goto out_err; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -958,7 +1047,7 @@ int dquot_initialize(struct inode *inode id = inode->i_gid; break; } - inode->i_dquot[cnt] = dqget(inode->i_sb, id, cnt); + inode->i_dquot[cnt] = dqget(inode->i_dqh, id, cnt); } } out_err: --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -962,7 +1051,7 @@ ***** } } out_err: - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem); return ret; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -974,7 +1063,7 @@ int dquot_drop(struct inode *inode) { int cnt; - down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (inode->i_dquot[cnt] != NODQUOT) { dqput(inode->i_dquot[cnt]); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -981,7 +1070,7 @@ ***** inode->i_dquot[cnt] = NODQUOT; } } - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem); return 0; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1012,9 +1101,9 @@ out_add: for (cnt = 0; cnt < MAXQUOTAS; cnt++) warntype[cnt] = NOWARN; - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); if (IS_NOQUOTA(inode)) { /* Now we can do reliable test... */ - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); goto out_add; } spin_lock(&dq_data_lock); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1039,7 +1128,7 @@ warn_put_all: if (inode->i_dquot[cnt]) mark_dquot_dirty(inode->i_dquot[cnt]); flush_warnings(inode->i_dquot, warntype); - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); return ret; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1057,9 +1146,9 @@ int dquot_alloc_inode(const struct inode return QUOTA_OK; for (cnt = 0; cnt < MAXQUOTAS; cnt++) warntype[cnt] = NOWARN; - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); if (IS_NOQUOTA(inode)) { - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); return QUOTA_OK; } spin_lock(&dq_data_lock); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1084,7 +1173,7 @@ warn_put_all: if (inode->i_dquot[cnt]) mark_dquot_dirty(inode->i_dquot[cnt]); flush_warnings((struct dquot **)inode->i_dquot, warntype); - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); return ret; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1102,10 +1191,10 @@ out_sub: inode_sub_bytes(inode, number); return QUOTA_OK; } - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); /* Now recheck reliably when holding dqptr_sem */ if (IS_NOQUOTA(inode)) { - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); goto out_sub; } spin_lock(&dq_data_lock); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1120,7 +1209,7 @@ out_sub: for (cnt = 0; cnt < MAXQUOTAS; cnt++) if (inode->i_dquot[cnt]) mark_dquot_dirty(inode->i_dquot[cnt]); - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); return QUOTA_OK; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1135,10 +1224,10 @@ int dquot_free_inode(const struct inode * re-enter the quota code and are already holding the semaphore */ if (IS_NOQUOTA(inode)) return QUOTA_OK; - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); /* Now recheck reliably when holding dqptr_sem */ if (IS_NOQUOTA(inode)) { - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); return QUOTA_OK; } spin_lock(&dq_data_lock); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1152,7 +1241,7 @@ int dquot_free_inode(const struct inode for (cnt = 0; cnt < MAXQUOTAS; cnt++) if (inode->i_dquot[cnt]) mark_dquot_dirty(inode->i_dquot[cnt]); - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem); return QUOTA_OK; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1167,6 +1256,7 @@ int dquot_transfer(struct inode *inode, qsize_t space; struct dquot *transfer_from[MAXQUOTAS]; struct dquot *transfer_to[MAXQUOTAS]; + struct dqhash *dqh = inode->i_sb->s_dqh; int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid, chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid; char warntype[MAXQUOTAS]; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1180,10 +1270,10 @@ int dquot_transfer(struct inode *inode, transfer_to[cnt] = transfer_from[cnt] = NODQUOT; warntype[cnt] = NOWARN; } - down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem); /* Now recheck reliably when holding dqptr_sem */ if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem); return QUOTA_OK; } /* First build the transfer_to list - here we can block on --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1194,7 +1284,7 @@ int dquot_transfer(struct inode *inode, case USRQUOTA: if (!chuid) continue; - transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt); + transfer_to[cnt] = dqget(dqh, iattr->ia_uid, cnt); break; case GRPQUOTA: if (!chgid) --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1199,7 +1289,7 @@ ***** case GRPQUOTA: if (!chgid) continue; - transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt); + transfer_to[cnt] = dqget(dqh, iattr->ia_gid, cnt); break; } } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1254,7 +1344,7 @@ warn_put_all: if (ret == NO_QUOTA && transfer_to[cnt] != NODQUOT) dqput(transfer_to[cnt]); } - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem); return ret; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1261,13 +1351,13 @@ ***** /* * Write info of quota file to disk */ -int dquot_commit_info(struct super_block *sb, int type) +int dquot_commit_info(struct dqhash *hash, int type) { int ret; - struct quota_info *dqopt = sb_dqopt(sb); + struct quota_info *dqopt = dqh_dqopt(hash); down(&dqopt->dqio_sem); - ret = dqopt->ops[type]->write_file_info(sb, type); + ret = dqopt->ops[type]->write_file_info(hash, type); up(&dqopt->dqio_sem); return ret; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1317,10 +1407,10 @@ static inline void reset_enable_flags(st /* * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) */ -int vfs_quota_off(struct super_block *sb, int type) +int vfs_quota_off(struct dqhash *hash, int type) { int cnt; - struct quota_info *dqopt = sb_dqopt(sb); + struct quota_info *dqopt = dqh_dqopt(hash); struct inode *toputinode[MAXQUOTAS]; /* We need to serialize quota_off() for device */ --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1329,7 +1419,7 @@ int vfs_quota_off(struct super_block *sb toputinode[cnt] = NULL; if (type != -1 && cnt != type) continue; - if (!sb_has_quota_enabled(sb, cnt)) + if (!dqh_has_quota_enabled(hash, cnt)) continue; reset_enable_flags(dqopt, cnt); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1334,8 +1424,8 @@ ***** reset_enable_flags(dqopt, cnt); /* Note: these are blocking operations */ - drop_dquot_ref(sb, cnt); - invalidate_dquots(sb, cnt); + drop_dquot_ref(hash, cnt); + invalidate_dquots(hash, cnt); /* * Now all dquots should be invalidated, all writes done so we should be only * users of the info. No locks needed. --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1341,9 +1431,9 @@ ***** * users of the info. No locks needed. */ if (info_dirty(&dqopt->info[cnt])) - sb->dq_op->write_info(sb, cnt); + hash->dqh_qop->write_info(hash, cnt); if (dqopt->ops[cnt]->free_file_info) - dqopt->ops[cnt]->free_file_info(sb, cnt); + dqopt->ops[cnt]->free_file_info(hash, cnt); put_quota_format(dqopt->info[cnt].dqi_format); toputinode[cnt] = dqopt->files[cnt]; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1356,9 +1446,9 @@ int vfs_quota_off(struct super_block *sb up(&dqopt->dqonoff_sem); /* 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) - sb->s_op->sync_fs(sb, 1); - sync_blockdev(sb->s_bdev); + if (hash->dqh_sb->s_op->sync_fs) + hash->dqh_sb->s_op->sync_fs(hash->dqh_sb, 1); + sync_blockdev(hash->dqh_sb->s_bdev); /* Now the quota files are just ordinary files and we can set the * inode flags back. Moreover we discard the pagecache so that * userspace sees the writes we did bypassing the pagecache. We --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1369,7 +1459,7 @@ int vfs_quota_off(struct super_block *sb down(&dqopt->dqonoff_sem); /* If quota was reenabled in the meantime, we have * nothing to do */ - if (!sb_has_quota_enabled(sb, cnt)) { + if (!dqh_has_quota_enabled(hash, cnt)) { mutex_lock(&toputinode[cnt]->i_mutex); toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | S_NOATIME | S_NOQUOTA); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1380,8 +1470,8 @@ int vfs_quota_off(struct super_block *sb } up(&dqopt->dqonoff_sem); } - if (sb->s_bdev) - invalidate_bdev(sb->s_bdev, 0); + if (hash->dqh_sb->s_bdev) + invalidate_bdev(hash->dqh_sb->s_bdev, 0); return 0; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1394,7 +1484,8 @@ static int vfs_quota_on_inode(struct ino { struct quota_format_type *fmt = find_quota_format(format_id); struct super_block *sb = inode->i_sb; - struct quota_info *dqopt = sb_dqopt(sb); + struct dqhash *hash = inode->i_dqh; + struct quota_info *dqopt = dqh_dqopt(hash); int error; int oldflags = -1; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1420,7 +1511,7 @@ static int vfs_quota_on_inode(struct ino invalidate_bdev(sb->s_bdev, 0); mutex_lock(&inode->i_mutex); down(&dqopt->dqonoff_sem); - if (sb_has_quota_enabled(sb, type)) { + if (dqh_has_quota_enabled(hash, type)) { error = -EBUSY; goto out_lock; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1431,7 +1522,7 @@ static int vfs_quota_on_inode(struct ino oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA); inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; up_write(&dqopt->dqptr_sem); - sb->dq_op->drop(inode); + hash->dqh_qop->drop(inode); error = -EIO; dqopt->files[type] = igrab(inode); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1438,7 +1529,7 @@ ***** if (!dqopt->files[type]) goto out_lock; error = -EINVAL; - if (!fmt->qf_ops->check_quota_file(sb, type)) + if (!fmt->qf_ops->check_quota_file(hash, type)) goto out_file_init; dqopt->ops[type] = fmt->qf_ops; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1445,7 +1536,7 @@ ***** dqopt->info[type].dqi_format = fmt; INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); down(&dqopt->dqio_sem); - if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) { + if ((error = dqopt->ops[type]->read_file_info(hash, type)) < 0) { up(&dqopt->dqio_sem); goto out_file_init; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1453,7 +1544,7 @@ static int vfs_quota_on_inode(struct ino mutex_unlock(&inode->i_mutex); set_enable_flags(dqopt, type); - add_dquot_ref(sb, type); + add_dquot_ref(hash, type); up(&dqopt->dqonoff_sem); return 0; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1479,7 +1570,7 @@ out_fmt: } /* Actual function called from quotactl() */ -int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path) +int vfs_quota_on(struct dqhash *hash, int type, int format_id, char *path) { struct nameidata nd; int error; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1491,7 +1582,7 @@ int vfs_quota_on(struct super_block *sb, if (error) goto out_path; /* Quota file not on the same filesystem? */ - if (nd.mnt->mnt_sb != sb) + if (nd.mnt->mnt_sb != hash->dqh_sb) error = -EXDEV; else error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1504,7 +1595,7 @@ out_path: * This function is used when filesystem needs to initialize quotas * during mount time. */ -int vfs_quota_on_mount(struct super_block *sb, char *qf_name, +int vfs_quota_on_mount(struct dqhash *hash, char *qf_name, int format_id, int type) { struct dentry *dentry; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1510,7 +1601,7 @@ ***** struct dentry *dentry; int error; - dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name)); + dentry = lookup_one_len(qf_name, hash->dqh_sb->s_root, strlen(qf_name)); if (IS_ERR(dentry)) return PTR_ERR(dentry); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1546,7 +1637,7 @@ static void do_get_dqblk(struct dquot *d spin_unlock(&dq_data_lock); } -int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di) +int vfs_get_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di) { struct dquot *dquot; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1550,9 +1641,9 @@ ***** { struct dquot *dquot; - down(&sb_dqopt(sb)->dqonoff_sem); - if (!(dquot = dqget(sb, id, type))) { - up(&sb_dqopt(sb)->dqonoff_sem); + down(&dqh_dqopt(hash)->dqonoff_sem); + if (!(dquot = dqget(hash, id, type))) { + up(&dqh_dqopt(hash)->dqonoff_sem); return -ESRCH; } do_get_dqblk(dquot, di); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1557,7 +1648,7 @@ ***** } do_get_dqblk(dquot, di); dqput(dquot); - up(&sb_dqopt(sb)->dqonoff_sem); + up(&dqh_dqopt(hash)->dqonoff_sem); return 0; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1597,7 +1688,7 @@ static void do_set_dqblk(struct dquot *d clear_bit(DQ_BLKS_B, &dquot->dq_flags); } else if (!(di->dqb_valid & QIF_BTIME)) /* Set grace only if user hasn't provided his own... */ - dm->dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace; + dm->dqb_btime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_bgrace; } if (check_ilim) { if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) { --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1605,7 +1696,7 @@ static void do_set_dqblk(struct dquot *d clear_bit(DQ_INODES_B, &dquot->dq_flags); } else if (!(di->dqb_valid & QIF_ITIME)) /* Set grace only if user hasn't provided his own... */ - dm->dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; + dm->dqb_itime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_igrace; } if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit) clear_bit(DQ_FAKE_B, &dquot->dq_flags); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1615,7 +1706,7 @@ static void do_set_dqblk(struct dquot *d mark_dquot_dirty(dquot); } -int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di) +int vfs_set_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di) { struct dquot *dquot; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1619,9 +1710,9 @@ ***** { struct dquot *dquot; - down(&sb_dqopt(sb)->dqonoff_sem); - if (!(dquot = dqget(sb, id, type))) { - up(&sb_dqopt(sb)->dqonoff_sem); + down(&dqh_dqopt(hash)->dqonoff_sem); + if (!(dquot = dqget(hash, id, type))) { + up(&dqh_dqopt(hash)->dqonoff_sem); return -ESRCH; } do_set_dqblk(dquot, di); --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1626,7 +1717,7 @@ ***** } do_set_dqblk(dquot, di); dqput(dquot); - up(&sb_dqopt(sb)->dqonoff_sem); + up(&dqh_dqopt(hash)->dqonoff_sem); return 0; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1631,7 +1722,7 @@ ***** } /* Generic routine for getting common part of quota file information */ -int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) +int vfs_get_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii) { struct mem_dqinfo *mi; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1635,12 +1726,12 @@ ***** { struct mem_dqinfo *mi; - down(&sb_dqopt(sb)->dqonoff_sem); - if (!sb_has_quota_enabled(sb, type)) { - up(&sb_dqopt(sb)->dqonoff_sem); + down(&dqh_dqopt(hash)->dqonoff_sem); + if (!dqh_has_quota_enabled(hash, type)) { + up(&dqh_dqopt(hash)->dqonoff_sem); return -ESRCH; } - mi = sb_dqopt(sb)->info + type; + mi = dqh_dqopt(hash)->info + type; spin_lock(&dq_data_lock); ii->dqi_bgrace = mi->dqi_bgrace; ii->dqi_igrace = mi->dqi_igrace; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1647,7 +1738,7 @@ ***** ii->dqi_flags = mi->dqi_flags & DQF_MASK; ii->dqi_valid = IIF_ALL; spin_unlock(&dq_data_lock); - up(&sb_dqopt(sb)->dqonoff_sem); + up(&dqh_dqopt(hash)->dqonoff_sem); return 0; } --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1652,7 +1743,7 @@ ***** } /* Generic routine for setting common part of quota file information */ -int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) +int vfs_set_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii) { struct mem_dqinfo *mi; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1656,12 +1747,12 @@ ***** { struct mem_dqinfo *mi; - down(&sb_dqopt(sb)->dqonoff_sem); - if (!sb_has_quota_enabled(sb, type)) { - up(&sb_dqopt(sb)->dqonoff_sem); + down(&dqh_dqopt(hash)->dqonoff_sem); + if (!dqh_has_quota_enabled(hash, type)) { + up(&dqh_dqopt(hash)->dqonoff_sem); return -ESRCH; } - mi = sb_dqopt(sb)->info + type; + mi = dqh_dqopt(hash)->info + type; spin_lock(&dq_data_lock); if (ii->dqi_valid & IIF_BGRACE) mi->dqi_bgrace = ii->dqi_bgrace; --- linux-2.6.16-rc1/fs/dquot.c 2006-01-26 22:35:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/dquot.c 2006-01-21 18:28:18 +0100 @@ -1670,10 +1761,10 @@ int vfs_set_dqinfo(struct super_block *s if (ii->dqi_valid & IIF_FLAGS) mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK); spin_unlock(&dq_data_lock); - mark_info_dirty(sb, type); + mark_info_dirty(hash, type); /* Force write to disk */ - sb->dq_op->write_info(sb, type); - up(&sb_dqopt(sb)->dqonoff_sem); + hash->dqh_qop->write_info(hash, type); + up(&dqh_dqopt(hash)->dqonoff_sem); return 0; } --- linux-2.6.16-rc1/fs/ext2/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext2/super.c 2006-01-25 08:05:49 +0100 @@ -225,8 +225,8 @@ static int ext2_show_options(struct seq_ } #ifdef CONFIG_QUOTA -static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off); -static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); +static ssize_t ext2_quota_read(struct dqhash *hash, int type, char *data, size_t len, loff_t off); +static ssize_t ext2_quota_write(struct dqhash *hash, int type, const char *data, size_t len, loff_t off); #endif static struct super_operations ext2_sops = { --- linux-2.6.16-rc1/fs/ext2/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext2/super.c 2006-01-25 08:05:49 +0100 @@ -1096,10 +1123,11 @@ static struct super_block *ext2_get_sb(s * acquiring the locks... As quota files are never truncated and quota code * itself serializes the operations (and noone else should touch the files) * we don't have to be afraid of races */ -static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, +static ssize_t ext2_quota_read(struct dqhash *hash, int type, char *data, size_t len, loff_t off) { - struct inode *inode = sb_dqopt(sb)->files[type]; + struct inode *inode = dqh_dqopt(hash)->files[type]; + struct super_block *sb = hash->dqh_sb; sector_t blk = off >> EXT2_BLOCK_SIZE_BITS(sb); int err = 0; int offset = off & (sb->s_blocksize - 1); --- linux-2.6.16-rc1/fs/ext2/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext2/super.c 2006-01-25 08:05:49 +0100 @@ -1140,10 +1168,11 @@ static ssize_t ext2_quota_read(struct su } /* Write to quotafile */ -static ssize_t ext2_quota_write(struct super_block *sb, int type, +static ssize_t ext2_quota_write(struct dqhash *hash, int type, const char *data, size_t len, loff_t off) { - struct inode *inode = sb_dqopt(sb)->files[type]; + struct inode *inode = dqh_dqopt(hash)->files[type]; + struct super_block *sb = hash->dqh_sb; sector_t blk = off >> EXT2_BLOCK_SIZE_BITS(sb); int err = 0; int offset = off & (sb->s_blocksize - 1); --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -563,12 +563,12 @@ static int ext3_write_dquot(struct dquot static int ext3_acquire_dquot(struct dquot *dquot); static int ext3_release_dquot(struct dquot *dquot); static int ext3_mark_dquot_dirty(struct dquot *dquot); -static int ext3_write_info(struct super_block *sb, int type); -static int ext3_quota_on(struct super_block *sb, int type, int format_id, char *path); -static int ext3_quota_on_mount(struct super_block *sb, int type); -static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, +static int ext3_write_info(struct dqhash *hash, int type); +static int ext3_quota_on(struct dqhash *hash, int type, int format_id, char *path); +static int ext3_quota_on_mount(struct dqhash *hash, int type); +static ssize_t ext3_quota_read(struct dqhash *hash, int type, char *data, size_t len, loff_t off); -static ssize_t ext3_quota_write(struct super_block *sb, int type, +static ssize_t ext3_quota_write(struct dqhash *hash, int type, const char *data, size_t len, loff_t off); static struct dquot_operations ext3_quota_operations = { --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -893,7 +911,7 @@ static int parse_options (char *options, case Opt_grpjquota: qtype = GRPQUOTA; set_qf_name: - if (sb_any_quota_enabled(sb)) { + if (dqh_any_quota_enabled(sb->s_dqh)) { printk(KERN_ERR "EXT3-fs: Cannot change journalled " "quota options when quota turned on.\n"); --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -931,7 +949,7 @@ set_qf_name: case Opt_offgrpjquota: qtype = GRPQUOTA; clear_qf_name: - if (sb_any_quota_enabled(sb)) { + if (dqh_any_quota_enabled(sb->s_dqh)) { printk(KERN_ERR "EXT3-fs: Cannot change " "journalled quota options when " "quota turned on.\n"); --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -959,7 +977,7 @@ clear_qf_name: set_opt(sbi->s_mount_opt, GRPQUOTA); break; case Opt_noquota: - if (sb_any_quota_enabled(sb)) { + if (dqh_any_quota_enabled(sb->s_dqh)) { printk(KERN_ERR "EXT3-fs: Cannot change quota " "options when quota turned on.\n"); return 0; --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -1231,7 +1249,7 @@ static void ext3_orphan_cleanup (struct /* Turn on quotas so that they are updated correctly */ for (i = 0; i < MAXQUOTAS; i++) { if (EXT3_SB(sb)->s_qf_names[i]) { - int ret = ext3_quota_on_mount(sb, i); + int ret = ext3_quota_on_mount(sb->s_dqh, i); if (ret < 0) printk(KERN_ERR "EXT3-fs: Cannot turn on journalled " --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -1281,8 +1299,8 @@ static void ext3_orphan_cleanup (struct #ifdef CONFIG_QUOTA /* Turn quotas off */ for (i = 0; i < MAXQUOTAS; i++) { - if (sb_dqopt(sb)->files[i]) - vfs_quota_off(sb, i); + if (dqh_dqopt(sb->s_dqh)->files[i]) + vfs_quota_off(sb->s_dqh, i); } #endif sb->s_flags = s_flags; /* Restore MS_RDONLY status */ --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -1620,8 +1641,8 @@ static int ext3_fill_super (struct super sb->s_export_op = &ext3_export_ops; sb->s_xattr = ext3_xattr_handlers; #ifdef CONFIG_QUOTA - sb->s_qcop = &ext3_qctl_operations; - sb->dq_op = &ext3_quota_operations; + sb->s_dqh->dqh_qop = &ext3_quota_operations; + sb->s_dqh->dqh_qcop = &ext3_qctl_operations; #endif INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2391,7 +2418,7 @@ static int ext3_statfs (struct super_blo static inline struct inode *dquot_to_inode(struct dquot *dquot) { - return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; + return dqh_dqopt(dquot->dq_dqh)->files[dquot->dq_type]; } static int ext3_dquot_initialize(struct inode *inode, int type) --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2434,7 +2461,7 @@ static int ext3_write_dquot(struct dquot inode = dquot_to_inode(dquot); handle = ext3_journal_start(inode, - EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); + EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); ret = dquot_commit(dquot); --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2450,7 +2477,7 @@ static int ext3_acquire_dquot(struct dqu handle_t *handle; handle = ext3_journal_start(dquot_to_inode(dquot), - EXT3_QUOTA_INIT_BLOCKS(dquot->dq_sb)); + EXT3_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); ret = dquot_acquire(dquot); --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2466,7 +2493,7 @@ static int ext3_release_dquot(struct dqu handle_t *handle; handle = ext3_journal_start(dquot_to_inode(dquot), - EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb)); + EXT3_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb)); if (IS_ERR(handle)) return PTR_ERR(handle); ret = dquot_release(dquot); --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2479,8 +2506,8 @@ static int ext3_release_dquot(struct dqu static int ext3_mark_dquot_dirty(struct dquot *dquot) { /* Are we journalling quotas? */ - if (EXT3_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || - EXT3_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { + if (EXT3_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[USRQUOTA] || + EXT3_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[GRPQUOTA]) { dquot_mark_dquot_dirty(dquot); return ext3_write_dquot(dquot); } else { --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2488,8 +2515,9 @@ static int ext3_mark_dquot_dirty(struct } } -static int ext3_write_info(struct super_block *sb, int type) +static int ext3_write_info(struct dqhash *hash, int type) { + struct super_block *sb = hash->dqh_sb; int ret, err; handle_t *handle; --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2497,7 +2525,7 @@ static int ext3_write_info(struct super_ handle = ext3_journal_start(sb->s_root->d_inode, 2); if (IS_ERR(handle)) return PTR_ERR(handle); - ret = dquot_commit_info(sb, type); + ret = dquot_commit_info(hash, type); err = ext3_journal_stop(handle); if (!ret) ret = err; --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2508,10 +2536,11 @@ static int ext3_write_info(struct super_ * Turn on quotas during mount time - we need to find * the quota file and such... */ -static int ext3_quota_on_mount(struct super_block *sb, int type) +static int ext3_quota_on_mount(struct dqhash *hash, int type) { - return vfs_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type], - EXT3_SB(sb)->s_jquota_fmt, type); + return vfs_quota_on_mount(hash, + EXT3_SB(hash->dqh_sb)->s_qf_names[type], + EXT3_SB(hash->dqh_sb)->s_jquota_fmt, type); } /* --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2517,9 +2546,10 @@ ***** /* * Standard function to be called on quota_on */ -static int ext3_quota_on(struct super_block *sb, int type, int format_id, +static int ext3_quota_on(struct dqhash *hash, int type, int format_id, char *path) { + struct super_block *sb = hash->dqh_sb; int err; struct nameidata nd; --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2528,7 +2558,7 @@ static int ext3_quota_on(struct super_bl /* Not journalling quota? */ if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] && !EXT3_SB(sb)->s_qf_names[GRPQUOTA]) - return vfs_quota_on(sb, type, format_id, path); + return vfs_quota_on(hash, type, format_id, path); err = path_lookup(path, LOOKUP_FOLLOW, &nd); if (err) return err; --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2543,7 +2573,7 @@ static int ext3_quota_on(struct super_bl "EXT3-fs: Quota file not on filesystem root. " "Journalled quota will not work.\n"); path_release(&nd); - return vfs_quota_on(sb, type, format_id, path); + return vfs_quota_on(hash, type, format_id, path); } /* Read data from quotafile - avoid pagecache and such because we cannot afford --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2550,10 +2580,11 @@ ***** * acquiring the locks... As quota files are never truncated and quota code * itself serializes the operations (and noone else should touch the files) * we don't have to be afraid of races */ -static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, +static ssize_t ext3_quota_read(struct dqhash *hash, int type, char *data, size_t len, loff_t off) { - struct inode *inode = sb_dqopt(sb)->files[type]; + struct inode *inode = dqh_dqopt(hash)->files[type]; + struct super_block *sb = hash->dqh_sb; sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb); int err = 0; int offset = off & (sb->s_blocksize - 1); --- linux-2.6.16-rc1/fs/ext3/super.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ext3/super.c 2006-01-25 08:05:58 +0100 @@ -2588,10 +2619,11 @@ static ssize_t ext3_quota_read(struct su /* Write to quotafile (we know the transaction is already started and has * enough credits) */ -static ssize_t ext3_quota_write(struct super_block *sb, int type, +static ssize_t ext3_quota_write(struct dqhash *hash, int type, const char *data, size_t len, loff_t off) { - struct inode *inode = sb_dqopt(sb)->files[type]; + struct inode *inode = dqh_dqopt(hash)->files[type]; + struct super_block *sb = hash->dqh_sb; sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb); int err = 0; int offset = off & (sb->s_blocksize - 1); --- linux-2.6.16-rc1/fs/inode.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/inode.c 2006-01-25 05:34:51 +0100 @@ -128,6 +131,7 @@ static struct inode *alloc_inode(struct inode->i_bytes = 0; inode->i_generation = 0; #ifdef CONFIG_QUOTA + inode->i_dqh = dqhget(sb->s_dqh); memset(&inode->i_dquot, 0, sizeof(inode->i_dquot)); #endif inode->i_pipe = NULL; --- linux-2.6.16-rc1/fs/inode.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/inode.c 2006-01-25 05:34:51 +0100 @@ -175,6 +179,8 @@ void destroy_inode(struct inode *inode) if (inode_has_buffers(inode)) BUG(); security_inode_free(inode); + if (dqhash_valid(inode->i_dqh)) + dqhput(inode->i_dqh); if (inode->i_sb->s_op->destroy_inode) inode->i_sb->s_op->destroy_inode(inode); else --- linux-2.6.16-rc1/fs/inode.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/inode.c 2006-01-25 05:34:51 +0100 @@ -1272,7 +1280,7 @@ EXPORT_SYMBOL(inode_needs_sync); /* Function back in dquot.c */ int remove_inode_dquot_ref(struct inode *, int, struct list_head *); -void remove_dquot_ref(struct super_block *sb, int type, +void remove_dquot_ref(struct dqhash *hash, int type, struct list_head *tofree_head) { struct inode *inode; --- linux-2.6.16-rc1/fs/inode.c 2006-01-26 22:35:11 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/inode.c 2006-01-25 05:34:51 +0100 @@ -1276,8 +1284,9 @@ ***** struct list_head *tofree_head) { struct inode *inode; + struct super_block *sb = hash->dqh_sb; - if (!sb->dq_op) + if (!hash->dqh_qop) return; /* nothing to do */ spin_lock(&inode_lock); /* This lock is for inodes code */ --- linux-2.6.16-rc1/fs/jfs/jfs_dtree.c 2005-08-29 22:25:31 +0200 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/jfs/jfs_dtree.c 2006-01-21 18:28:18 +0100 @@ -930,7 +937,8 @@ int dtInsert(tid_t tid, struct inode *ip static int dtSplitUp(tid_t tid, struct inode *ip, struct dtsplit * split, struct btstack * btstack) { - struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); + struct super_block *sb = ip->i_sb; + struct jfs_sb_info *sbi = JFS_SBI(sb); int rc = 0; struct metapage *smp; dtpage_t *sp; /* split page */ --- linux-2.6.16-rc1/fs/jfs/jfs_xtree.c 2006-01-03 17:29:57 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/jfs/jfs_xtree.c 2006-01-21 18:28:18 +0100 @@ -1243,7 +1251,7 @@ xtSplitPage(tid_t tid, struct inode *ip, rbn = addressPXD(pxd); /* Allocate blocks to quota. */ - if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { + if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { rc = -EDQUOT; goto clean_up; } --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -17,9 +17,12 @@ #include #include #include +#include +#include +#include /* Check validity of generic quotactl commands */ -static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) +static int generic_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id) { if (type >= MAXQUOTAS) return -EINVAL; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -23,10 +26,10 @@ ***** { if (type >= MAXQUOTAS) return -EINVAL; - if (!sb && cmd != Q_SYNC) + if (!hash && cmd != Q_SYNC) return -ENODEV; /* Is operation supported? */ - if (sb && !sb->s_qcop) + if (hash && !hash->dqh_qcop) return -ENOSYS; switch (cmd) { --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -33,7 +36,7 @@ ***** case Q_GETFMT: break; case Q_QUOTAON: - if (!sb->s_qcop->quota_on) + if (!hash->dqh_qcop->quota_on) return -ENOSYS; break; case Q_QUOTAOFF: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -37,7 +40,7 @@ ***** return -ENOSYS; break; case Q_QUOTAOFF: - if (!sb->s_qcop->quota_off) + if (!hash->dqh_qcop->quota_off) return -ENOSYS; break; case Q_SETINFO: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -41,7 +44,7 @@ ***** return -ENOSYS; break; case Q_SETINFO: - if (!sb->s_qcop->set_info) + if (!hash->dqh_qcop->set_info) return -ENOSYS; break; case Q_GETINFO: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -45,7 +48,7 @@ ***** return -ENOSYS; break; case Q_GETINFO: - if (!sb->s_qcop->get_info) + if (!hash->dqh_qcop->get_info) return -ENOSYS; break; case Q_SETQUOTA: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -49,7 +52,7 @@ ***** return -ENOSYS; break; case Q_SETQUOTA: - if (!sb->s_qcop->set_dqblk) + if (!hash->dqh_qcop->set_dqblk) return -ENOSYS; break; case Q_GETQUOTA: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -53,7 +56,7 @@ ***** return -ENOSYS; break; case Q_GETQUOTA: - if (!sb->s_qcop->get_dqblk) + if (!hash->dqh_qcop->get_dqblk) return -ENOSYS; break; case Q_SYNC: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -57,7 +60,7 @@ ***** return -ENOSYS; break; case Q_SYNC: - if (sb && !sb->s_qcop->quota_sync) + if (hash && !hash->dqh_qcop->quota_sync) return -ENOSYS; break; default: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -73,7 +76,7 @@ static int generic_quotactl_valid(struct case Q_SETQUOTA: case Q_GETQUOTA: /* This is just informative test so we are satisfied without a lock */ - if (!sb_has_quota_enabled(sb, type)) + if (!dqh_has_quota_enabled(hash, type)) return -ESRCH; } --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -92,7 +95,7 @@ ***** } /* Check validity of XFS Quota Manager commands */ -static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) +static int xqm_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id) { if (type >= XQM_MAXQUOTAS) return -EINVAL; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -96,9 +99,9 @@ ***** { if (type >= XQM_MAXQUOTAS) return -EINVAL; - if (!sb) + if (!hash) return -ENODEV; - if (!sb->s_qcop) + if (!hash->dqh_qcop) return -ENOSYS; switch (cmd) { --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -105,7 +108,7 @@ ***** case Q_XQUOTAON: case Q_XQUOTAOFF: case Q_XQUOTARM: - if (!sb->s_qcop->set_xstate) + if (!hash->dqh_qcop->set_xstate) return -ENOSYS; break; case Q_XGETQSTAT: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -109,7 +112,7 @@ ***** return -ENOSYS; break; case Q_XGETQSTAT: - if (!sb->s_qcop->get_xstate) + if (!hash->dqh_qcop->get_xstate) return -ENOSYS; break; case Q_XSETQLIM: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -113,7 +116,7 @@ ***** return -ENOSYS; break; case Q_XSETQLIM: - if (!sb->s_qcop->set_xquota) + if (!hash->dqh_qcop->set_xquota) return -ENOSYS; break; case Q_XGETQUOTA: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -117,7 +120,7 @@ ***** return -ENOSYS; break; case Q_XGETQUOTA: - if (!sb->s_qcop->get_xquota) + if (!hash->dqh_qcop->get_xquota) return -ENOSYS; break; case Q_XQUOTASYNC: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -121,7 +124,7 @@ ***** return -ENOSYS; break; case Q_XQUOTASYNC: - if (!sb->s_qcop->quota_sync) + if (!hash->dqh_qcop->quota_sync) return -ENOSYS; break; default: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -142,7 +145,7 @@ ***** return 0; } -static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) +static int check_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id) { int error; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -147,11 +150,11 @@ ***** int error; if (XQM_COMMAND(cmd)) - error = xqm_quotactl_valid(sb, type, cmd, id); + error = xqm_quotactl_valid(hash, type, cmd, id); else - error = generic_quotactl_valid(sb, type, cmd, id); + error = generic_quotactl_valid(hash, type, cmd, id); if (!error) - error = security_quotactl(cmd, type, id, sb); + error = security_quotactl(cmd, type, id, hash); return error; } --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -155,12 +158,8 @@ ***** return error; } -static void quota_sync_sb(struct super_block *sb, int type) +static void quota_sync_sb(struct super_block *sb) { - int cnt; - struct inode *discard[MAXQUOTAS]; - - sb->s_qcop->quota_sync(sb, type); /* This is not very clever (and fast) but currently I don't know about * any other simple way of getting quota data to disk and we must get * them there for userspace to be visible... */ --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -167,6 +166,18 @@ ***** if (sb->s_op->sync_fs) sb->s_op->sync_fs(sb, 1); sync_blockdev(sb->s_bdev); +} + +static void quota_sync_dqh(struct dqhash *hash, int type) +{ + int cnt; + struct inode *discard[MAXQUOTAS]; + + vxdprintk(VXD_CBIT(quota, 1), + "quota_sync_dqh(%p,%d)", hash, type); + hash->dqh_qcop->quota_sync(hash, type); + + quota_sync_sb(hash->dqh_sb); /* Now when everything is written we can discard the pagecache so * that userspace sees the changes. We need i_mutex and so we could --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -173,7 +184,7 @@ ***** * not do it inside dqonoff_sem. Moreover we need to be carefull * about races with quotaoff() (that is the reason why we have own * reference to inode). */ - down(&sb_dqopt(sb)->dqonoff_sem); + down(&dqh_dqopt(hash)->dqonoff_sem); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { discard[cnt] = NULL; if (type != -1 && cnt != type) --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -178,11 +189,14 @@ ***** discard[cnt] = NULL; if (type != -1 && cnt != type) continue; - if (!sb_has_quota_enabled(sb, cnt)) + if (!dqh_has_quota_enabled(hash, cnt)) continue; - discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]); + vxdprintk(VXD_CBIT(quota, 0), + "quota_sync_dqh(%p,%d) discard inode %p", + hash, type, dqh_dqopt(hash)->files[cnt]); + discard[cnt] = igrab(dqh_dqopt(hash)->files[cnt]); } - up(&sb_dqopt(sb)->dqonoff_sem); + up(&dqh_dqopt(hash)->dqonoff_sem); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (discard[cnt]) { mutex_lock(&discard[cnt]->i_mutex); --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -193,37 +207,26 @@ static void quota_sync_sb(struct super_b } } -void sync_dquots(struct super_block *sb, int type) +void sync_dquots_dqh(struct dqhash *hash, int type) { - int cnt, dirty; + vxdprintk(VXD_CBIT(quota, 1), + "sync_dquots_dqh(%p,%d)", hash, type); - if (sb) { - if (sb->s_qcop->quota_sync) - quota_sync_sb(sb, type); - return; - } + if (hash->dqh_qcop->quota_sync) + quota_sync_dqh(hash, type); +} - spin_lock(&sb_lock); -restart: - list_for_each_entry(sb, &super_blocks, s_list) { - /* This test just improves performance so it needn't be reliable... */ - for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++) - if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt) - && info_any_dirty(&sb_dqopt(sb)->info[cnt])) - dirty = 1; - if (!dirty) - continue; - sb->s_count++; - spin_unlock(&sb_lock); - down_read(&sb->s_umount); - if (sb->s_root && sb->s_qcop->quota_sync) - quota_sync_sb(sb, type); - up_read(&sb->s_umount); - spin_lock(&sb_lock); - if (__put_super_and_need_restart(sb)) - goto restart; +void sync_dquots(struct dqhash *hash, int type) + +{ + vxdprintk(VXD_CBIT(quota, 1), + "sync_dquots(%p,%d)", hash, type); + + if (hash) { + if (hash->dqh_qcop->quota_sync) + quota_sync_dqh(hash, type); + return; } - spin_unlock(&sb_lock); } /* Copy parameters and call proper function */ --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -227,7 +230,7 @@ ***** } /* Copy parameters and call proper function */ -static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void __user *addr) +static int do_quotactl(struct dqhash *hash, int type, int cmd, qid_t id, void __user *addr) { int ret; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -231,6 +234,9 @@ ***** { int ret; + vxdprintk(VXD_CBIT(quota, 3), + "do_quotactl(%p,%d,cmd=%d,id=%d,%p)", hash, type, cmd, id, addr); + switch (cmd) { case Q_QUOTAON: { char *pathname; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -237,7 +243,7 @@ ***** if (IS_ERR(pathname = getname(addr))) return PTR_ERR(pathname); - ret = sb->s_qcop->quota_on(sb, type, id, pathname); + ret = hash->dqh_qcop->quota_on(hash, type, id, pathname); putname(pathname); return ret; } --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -242,7 +248,7 @@ ***** return ret; } case Q_QUOTAOFF: - return sb->s_qcop->quota_off(sb, type); + return hash->dqh_qcop->quota_off(hash, type); case Q_GETFMT: { __u32 fmt; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -247,13 +253,13 @@ ***** case Q_GETFMT: { __u32 fmt; - down_read(&sb_dqopt(sb)->dqptr_sem); - if (!sb_has_quota_enabled(sb, type)) { - up_read(&sb_dqopt(sb)->dqptr_sem); + down_read(&dqh_dqopt(hash)->dqptr_sem); + if (!dqh_has_quota_enabled(hash, type)) { + up_read(&dqh_dqopt(hash)->dqptr_sem); return -ESRCH; } - fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; - up_read(&sb_dqopt(sb)->dqptr_sem); + fmt = dqh_dqopt(hash)->info[type].dqi_format->qf_fmt_id; + up_read(&dqh_dqopt(hash)->dqptr_sem); if (copy_to_user(addr, &fmt, sizeof(fmt))) return -EFAULT; return 0; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -261,7 +267,7 @@ static int do_quotactl(struct super_bloc case Q_GETINFO: { struct if_dqinfo info; - if ((ret = sb->s_qcop->get_info(sb, type, &info))) + if ((ret = hash->dqh_qcop->get_info(hash, type, &info))) return ret; if (copy_to_user(addr, &info, sizeof(info))) return -EFAULT; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -272,7 +278,7 @@ static int do_quotactl(struct super_bloc if (copy_from_user(&info, addr, sizeof(info))) return -EFAULT; - return sb->s_qcop->set_info(sb, type, &info); + return hash->dqh_qcop->set_info(hash, type, &info); } case Q_GETQUOTA: { struct if_dqblk idq; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -277,7 +283,7 @@ ***** case Q_GETQUOTA: { struct if_dqblk idq; - if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq))) + if ((ret = hash->dqh_qcop->get_dqblk(hash, type, id, &idq))) return ret; if (copy_to_user(addr, &idq, sizeof(idq))) return -EFAULT; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -288,10 +294,10 @@ static int do_quotactl(struct super_bloc if (copy_from_user(&idq, addr, sizeof(idq))) return -EFAULT; - return sb->s_qcop->set_dqblk(sb, type, id, &idq); + return hash->dqh_qcop->set_dqblk(hash, type, id, &idq); } case Q_SYNC: - sync_dquots(sb, type); + sync_dquots_dqh(hash, type); return 0; case Q_XQUOTAON: --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -301,7 +307,7 @@ static int do_quotactl(struct super_bloc if (copy_from_user(&flags, addr, sizeof(flags))) return -EFAULT; - return sb->s_qcop->set_xstate(sb, flags, cmd); + return hash->dqh_qcop->set_xstate(hash, flags, cmd); } case Q_XGETQSTAT: { struct fs_quota_stat fqs; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -306,7 +312,7 @@ ***** case Q_XGETQSTAT: { struct fs_quota_stat fqs; - if ((ret = sb->s_qcop->get_xstate(sb, &fqs))) + if ((ret = hash->dqh_qcop->get_xstate(hash, &fqs))) return ret; if (copy_to_user(addr, &fqs, sizeof(fqs))) return -EFAULT; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -317,7 +323,7 @@ static int do_quotactl(struct super_bloc if (copy_from_user(&fdq, addr, sizeof(fdq))) return -EFAULT; - return sb->s_qcop->set_xquota(sb, type, id, &fdq); + return hash->dqh_qcop->set_xquota(hash, type, id, &fdq); } case Q_XGETQUOTA: { struct fs_disk_quota fdq; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -322,7 +328,7 @@ ***** case Q_XGETQUOTA: { struct fs_disk_quota fdq; - if ((ret = sb->s_qcop->get_xquota(sb, type, id, &fdq))) + if ((ret = hash->dqh_qcop->get_xquota(hash, type, id, &fdq))) return ret; if (copy_to_user(addr, &fdq, sizeof(fdq))) return -EFAULT; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -329,7 +335,7 @@ ***** return 0; } case Q_XQUOTASYNC: - return sb->s_qcop->quota_sync(sb, type); + return hash->dqh_qcop->quota_sync(hash, type); /* We never reach here unless validity check is broken */ default: BUG(); --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -347,6 +390,7 @@ asmlinkage long sys_quotactl(unsigned in { uint cmds, type; struct super_block *sb = NULL; + struct dqhash *dqh = NULL; struct block_device *bdev; char *tmp; int ret; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -367,10 +428,11 @@ ***** if (!sb) return -ENODEV; } - - ret = check_quotactl_valid(sb, type, cmds, id); + if (sb) + dqh = sb->s_dqh; + ret = check_quotactl_valid(dqh, type, cmds, id); if (ret >= 0) - ret = do_quotactl(sb, type, cmds, id, addr); + ret = do_quotactl(dqh, type, cmds, id, addr); if (sb) drop_super(sb); --- linux-2.6.16-rc1/fs/quota_v1.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v1.c 2006-01-21 18:28:18 +0100 @@ -42,7 +42,7 @@ static int v1_read_dqblk(struct dquot *d int type = dquot->dq_type; struct v1_disk_dqblk dqblk; - if (!sb_dqopt(dquot->dq_sb)->files[type]) + if (!dqh_dqopt(dquot->dq_dqh)->files[type]) return -EINVAL; /* Set structure to 0s in case read fails/is after end of file */ --- linux-2.6.16-rc1/fs/quota_v1.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v1.c 2006-01-21 18:28:18 +0100 @@ -47,7 +47,8 @@ ***** /* Set structure to 0s in case read fails/is after end of file */ memset(&dqblk, 0, sizeof(struct v1_disk_dqblk)); - dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); + dquot->dq_dqh->dqh_sb->s_op->quota_read(dquot->dq_dqh, type, + (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk); if (dquot->dq_dqb.dqb_bhardlimit == 0 && dquot->dq_dqb.dqb_bsoftlimit == 0 && --- linux-2.6.16-rc1/fs/quota_v1.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v1.c 2006-01-21 18:28:18 +0100 @@ -66,16 +67,16 @@ static int v1_commit_dqblk(struct dquot v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb); if (dquot->dq_id == 0) { - dqblk.dqb_btime = sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace; - dqblk.dqb_itime = sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace; + dqblk.dqb_btime = dqh_dqopt(dquot->dq_dqh)->info[type].dqi_bgrace; + dqblk.dqb_itime = dqh_dqopt(dquot->dq_dqh)->info[type].dqi_igrace; } ret = 0; - if (sb_dqopt(dquot->dq_sb)->files[type]) - ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, (char *)&dqblk, - sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); + if (dqh_dqopt(dquot->dq_dqh)->files[type]) + ret = dquot->dq_dqh->dqh_sb->s_op->quota_write(dquot->dq_dqh, type, + (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); if (ret != sizeof(struct v1_disk_dqblk)) { printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", - dquot->dq_sb->s_id); + dquot->dq_dqh->dqh_sb->s_id); if (ret >= 0) ret = -EIO; goto out; --- linux-2.6.16-rc1/fs/quota_v1.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v1.c 2006-01-21 18:28:18 +0100 @@ -100,9 +101,9 @@ struct v2_disk_dqheader { __le32 dqh_version; /* File version */ }; -static int v1_check_quota_file(struct super_block *sb, int type) +static int v1_check_quota_file(struct dqhash *hash, int type) { - struct inode *inode = sb_dqopt(sb)->files[type]; + struct inode *inode = dqh_dqopt(hash)->files[type]; ulong blocks; size_t off; struct v2_disk_dqheader dqhead; --- linux-2.6.16-rc1/fs/quota_v1.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v1.c 2006-01-21 18:28:18 +0100 @@ -118,7 +119,8 @@ static int v1_check_quota_file(struct su if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % sizeof(struct v1_disk_dqblk)) return 0; /* Doublecheck whether we didn't get file with new format - with old quotactl() this could happen */ - size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); + size = hash->dqh_sb->s_op->quota_read(hash, type, + (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); if (size != sizeof(struct v2_disk_dqheader)) return 1; /* Probably not new format */ if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type]) --- linux-2.6.16-rc1/fs/quota_v1.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v1.c 2006-01-21 18:28:18 +0100 @@ -127,9 +130,9 @@ ***** return 0; /* Seems like a new format file -> refuse it */ } -static int v1_read_file_info(struct super_block *sb, int type) +static int v1_read_file_info(struct dqhash *hash, int type) { - struct quota_info *dqopt = sb_dqopt(sb); + struct quota_info *dqopt = dqh_dqopt(hash); struct v1_disk_dqblk dqblk; int ret; --- linux-2.6.16-rc1/fs/quota_v1.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v1.c 2006-01-21 18:28:18 +0100 @@ -133,7 +136,9 @@ ***** struct v1_disk_dqblk dqblk; int ret; - if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) { + if ((ret = hash->dqh_sb->s_op->quota_read(hash, type, + (char *)&dqblk, sizeof(struct v1_disk_dqblk), + v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) { if (ret >= 0) ret = -EIO; goto out; --- linux-2.6.16-rc1/fs/quota_v1.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v1.c 2006-01-21 18:28:18 +0100 @@ -145,9 +150,9 @@ out: return ret; } -static int v1_write_file_info(struct super_block *sb, int type) +static int v1_write_file_info(struct dqhash *hash, int type) { - struct quota_info *dqopt = sb_dqopt(sb); + struct quota_info *dqopt = dqh_dqopt(hash); struct v1_disk_dqblk dqblk; int ret; --- linux-2.6.16-rc1/fs/quota_v1.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v1.c 2006-01-21 18:28:18 +0100 @@ -152,7 +157,7 @@ ***** int ret; dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY; - if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, + if ((ret = hash->dqh_sb->s_op->quota_read(hash, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) { if (ret >= 0) ret = -EIO; --- linux-2.6.16-rc1/fs/quota_v1.c 2005-03-02 12:38:45 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v1.c 2006-01-21 18:28:18 +0100 @@ -160,7 +165,7 @@ static int v1_write_file_info(struct sup } dqblk.dqb_itime = dqopt->info[type].dqi_igrace; dqblk.dqb_btime = dqopt->info[type].dqi_bgrace; - ret = sb->s_op->quota_write(sb, type, (char *)&dqblk, + ret = hash->dqh_sb->s_op->quota_write(hash, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0)); if (ret == sizeof(struct v1_disk_dqblk)) ret = 0; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -26,7 +26,7 @@ typedef char *dqbuf_t; #define GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)buf)+sizeof(struct v2_disk_dqdbheader))) /* Check whether given file is really vfsv0 quotafile */ -static int v2_check_quota_file(struct super_block *sb, int type) +static int v2_check_quota_file(struct dqhash *hash, int type) { struct v2_disk_dqheader dqhead; ssize_t size; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -33,7 +33,8 @@ ***** static const uint quota_magics[] = V2_INITQMAGICS; static const uint quota_versions[] = V2_INITQVERSIONS; - size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); + size = hash->dqh_sb->s_op->quota_read(hash, type, + (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); if (size != sizeof(struct v2_disk_dqheader)) { printk("quota_v2: failed read expected=%d got=%d\n", sizeof(struct v2_disk_dqheader), size); --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -46,17 +47,17 @@ static int v2_check_quota_file(struct su } /* Read information header from quota file */ -static int v2_read_file_info(struct super_block *sb, int type) +static int v2_read_file_info(struct dqhash *hash, int type) { struct v2_disk_dqinfo dinfo; - struct mem_dqinfo *info = sb_dqopt(sb)->info+type; + struct mem_dqinfo *info = dqh_dqopt(hash)->info+type; ssize_t size; - size = sb->s_op->quota_read(sb, type, (char *)&dinfo, - sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); + size = hash->dqh_sb->s_op->quota_read(hash, type, + (char *)&dinfo, sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); if (size != sizeof(struct v2_disk_dqinfo)) { printk(KERN_WARNING "Can't read info structure on device %s.\n", - sb->s_id); + hash->dqh_sb->s_id); return -1; } info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace); --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -69,10 +70,10 @@ static int v2_read_file_info(struct supe } /* Write information header to quota file */ -static int v2_write_file_info(struct super_block *sb, int type) +static int v2_write_file_info(struct dqhash *hash, int type) { struct v2_disk_dqinfo dinfo; - struct mem_dqinfo *info = sb_dqopt(sb)->info+type; + struct mem_dqinfo *info = dqh_dqopt(hash)->info+type; ssize_t size; spin_lock(&dq_data_lock); --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -132,17 +133,17 @@ static inline void freedqbuf(dqbuf_t buf kfree(buf); } -static inline ssize_t read_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf) +static inline ssize_t read_blk(struct dqhash *hash, int type, uint blk, dqbuf_t buf) { memset(buf, 0, V2_DQBLKSIZE); - return sb->s_op->quota_read(sb, type, (char *)buf, - V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS); + return hash->dqh_sb->s_op->quota_read(hash, type, + (char *)buf, V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS); } -static inline ssize_t write_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf) +static inline ssize_t write_blk(struct dqhash *hash, int type, uint blk, dqbuf_t buf) { - return sb->s_op->quota_write(sb, type, (char *)buf, - V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS); + return hash->dqh_sb->s_op->quota_write(hash, type, + (char *)buf, V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS); } /* Remove empty block from list and return it */ --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -146,10 +147,10 @@ ***** } /* Remove empty block from list and return it */ -static int get_free_dqblk(struct super_block *sb, int type) +static int get_free_dqblk(struct dqhash *hash, int type) { dqbuf_t buf = getdqbuf(); - struct mem_dqinfo *info = sb_dqinfo(sb, type); + struct mem_dqinfo *info = dqh_dqinfo(hash, type); struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf; int ret, blk; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -157,7 +158,7 @@ static int get_free_dqblk(struct super_b return -ENOMEM; if (info->u.v2_i.dqi_free_blk) { blk = info->u.v2_i.dqi_free_blk; - if ((ret = read_blk(sb, type, blk, buf)) < 0) + if ((ret = read_blk(hash, type, blk, buf)) < 0) goto out_buf; info->u.v2_i.dqi_free_blk = le32_to_cpu(dh->dqdh_next_free); } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -164,7 +165,7 @@ ***** else { memset(buf, 0, V2_DQBLKSIZE); /* Assure block allocation... */ - if ((ret = write_blk(sb, type, info->u.v2_i.dqi_blocks, buf)) < 0) + if ((ret = write_blk(hash, type, info->u.v2_i.dqi_blocks, buf)) < 0) goto out_buf; blk = info->u.v2_i.dqi_blocks++; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -168,7 +169,7 @@ ***** goto out_buf; blk = info->u.v2_i.dqi_blocks++; } - mark_info_dirty(sb, type); + mark_info_dirty(hash, type); ret = blk; out_buf: freedqbuf(buf); --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -176,9 +177,9 @@ out_buf: } /* Insert empty block to the list */ -static int put_free_dqblk(struct super_block *sb, int type, dqbuf_t buf, uint blk) +static int put_free_dqblk(struct dqhash *hash, int type, dqbuf_t buf, uint blk) { - struct mem_dqinfo *info = sb_dqinfo(sb, type); + struct mem_dqinfo *info = dqh_dqinfo(hash, type); struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf; int err; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -186,9 +187,9 @@ static int put_free_dqblk(struct super_b dh->dqdh_prev_free = cpu_to_le32(0); dh->dqdh_entries = cpu_to_le16(0); info->u.v2_i.dqi_free_blk = blk; - mark_info_dirty(sb, type); + mark_info_dirty(hash, type); /* Some strange block. We had better leave it... */ - if ((err = write_blk(sb, type, blk, buf)) < 0) + if ((err = write_blk(hash, type, blk, buf)) < 0) return err; return 0; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -194,10 +195,10 @@ ***** } /* Remove given block from the list of blocks with free entries */ -static int remove_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk) +static int remove_free_dqentry(struct dqhash *hash, int type, dqbuf_t buf, uint blk) { dqbuf_t tmpbuf = getdqbuf(); - struct mem_dqinfo *info = sb_dqinfo(sb, type); + struct mem_dqinfo *info = dqh_dqinfo(hash, type); struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf; uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free); int err; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -205,10 +206,10 @@ static int remove_free_dqentry(struct su if (!tmpbuf) return -ENOMEM; if (nextblk) { - if ((err = read_blk(sb, type, nextblk, tmpbuf)) < 0) + if ((err = read_blk(hash, type, nextblk, tmpbuf)) < 0) goto out_buf; ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = dh->dqdh_prev_free; - if ((err = write_blk(sb, type, nextblk, tmpbuf)) < 0) + if ((err = write_blk(hash, type, nextblk, tmpbuf)) < 0) goto out_buf; } if (prevblk) { --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -212,10 +213,10 @@ ***** goto out_buf; } if (prevblk) { - if ((err = read_blk(sb, type, prevblk, tmpbuf)) < 0) + if ((err = read_blk(hash, type, prevblk, tmpbuf)) < 0) goto out_buf; ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_next_free = dh->dqdh_next_free; - if ((err = write_blk(sb, type, prevblk, tmpbuf)) < 0) + if ((err = write_blk(hash, type, prevblk, tmpbuf)) < 0) goto out_buf; } else { --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -220,7 +221,7 @@ ***** } else { info->u.v2_i.dqi_free_entry = nextblk; - mark_info_dirty(sb, type); + mark_info_dirty(hash, type); } freedqbuf(tmpbuf); dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -225,7 +226,7 @@ ***** freedqbuf(tmpbuf); dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); /* No matter whether write succeeds block is out of list */ - if (write_blk(sb, type, blk, buf) < 0) + if (write_blk(hash, type, blk, buf) < 0) printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk); return 0; out_buf: --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -234,10 +235,10 @@ out_buf: } /* Insert given block to the beginning of list with free entries */ -static int insert_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk) +static int insert_free_dqentry(struct dqhash *hash, int type, dqbuf_t buf, uint blk) { dqbuf_t tmpbuf = getdqbuf(); - struct mem_dqinfo *info = sb_dqinfo(sb, type); + struct mem_dqinfo *info = dqh_dqinfo(hash, type); struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf; int err; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -245,13 +246,13 @@ static int insert_free_dqentry(struct su return -ENOMEM; dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_entry); dh->dqdh_prev_free = cpu_to_le32(0); - if ((err = write_blk(sb, type, blk, buf)) < 0) + if ((err = write_blk(hash, type, blk, buf)) < 0) goto out_buf; if (info->u.v2_i.dqi_free_entry) { - if ((err = read_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0) + if ((err = read_blk(hash, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0) goto out_buf; ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = cpu_to_le32(blk); - if ((err = write_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0) + if ((err = write_blk(hash, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0) goto out_buf; } freedqbuf(tmpbuf); --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -256,7 +257,7 @@ ***** } freedqbuf(tmpbuf); info->u.v2_i.dqi_free_entry = blk; - mark_info_dirty(sb, type); + mark_info_dirty(hash, type); return 0; out_buf: freedqbuf(tmpbuf); --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -266,8 +267,9 @@ out_buf: /* Find space for dquot */ static uint find_free_dqentry(struct dquot *dquot, int *err) { - struct super_block *sb = dquot->dq_sb; - struct mem_dqinfo *info = sb_dqopt(sb)->info+dquot->dq_type; + // struct super_block *sb = dquot->dq_sb; + struct dqhash *dqh = dquot->dq_dqh; + struct mem_dqinfo *info = dqh_dqopt(dqh)->info+dquot->dq_type; uint blk, i; struct v2_disk_dqdbheader *dh; struct v2_disk_dqblk *ddquot; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -283,7 +285,7 @@ static uint find_free_dqentry(struct dqu ddquot = GETENTRIES(buf); if (info->u.v2_i.dqi_free_entry) { blk = info->u.v2_i.dqi_free_entry; - if ((*err = read_blk(sb, dquot->dq_type, blk, buf)) < 0) + if ((*err = read_blk(dqh, dquot->dq_type, blk, buf)) < 0) goto out_buf; } else { --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -287,7 +289,7 @@ ***** goto out_buf; } else { - blk = get_free_dqblk(sb, dquot->dq_type); + blk = get_free_dqblk(dqh, dquot->dq_type); if ((int)blk < 0) { *err = blk; freedqbuf(buf); --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -296,10 +298,10 @@ static uint find_free_dqentry(struct dqu memset(buf, 0, V2_DQBLKSIZE); /* This is enough as block is already zeroed and entry list is empty... */ info->u.v2_i.dqi_free_entry = blk; - mark_info_dirty(sb, dquot->dq_type); + mark_info_dirty(dqh, dquot->dq_type); } if (le16_to_cpu(dh->dqdh_entries)+1 >= V2_DQSTRINBLK) /* Block will be full? */ - if ((*err = remove_free_dqentry(sb, dquot->dq_type, buf, blk)) < 0) { + if ((*err = remove_free_dqentry(dqh, dquot->dq_type, buf, blk)) < 0) { printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk); goto out_buf; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -314,7 +316,7 @@ static uint find_free_dqentry(struct dqu goto out_buf; } #endif - if ((*err = write_blk(sb, dquot->dq_type, blk, buf)) < 0) { + if ((*err = write_blk(dqh, dquot->dq_type, blk, buf)) < 0) { printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk); goto out_buf; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -329,7 +331,7 @@ out_buf: /* Insert reference to structure into the trie */ static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth) { - struct super_block *sb = dquot->dq_sb; + struct dqhash *dqh = dquot->dq_dqh; dqbuf_t buf; int ret = 0, newson = 0, newact = 0; __le32 *ref; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -338,7 +340,7 @@ static int do_insert_tree(struct dquot * if (!(buf = getdqbuf())) return -ENOMEM; if (!*treeblk) { - ret = get_free_dqblk(sb, dquot->dq_type); + ret = get_free_dqblk(dqh, dquot->dq_type); if (ret < 0) goto out_buf; *treeblk = ret; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -346,7 +348,7 @@ static int do_insert_tree(struct dquot * newact = 1; } else { - if ((ret = read_blk(sb, dquot->dq_type, *treeblk, buf)) < 0) { + if ((ret = read_blk(dqh, dquot->dq_type, *treeblk, buf)) < 0) { printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk); goto out_buf; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -369,10 +371,10 @@ static int do_insert_tree(struct dquot * ret = do_insert_tree(dquot, &newblk, depth+1); if (newson && ret >= 0) { ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk); - ret = write_blk(sb, dquot->dq_type, *treeblk, buf); + ret = write_blk(dqh, dquot->dq_type, *treeblk, buf); } else if (newact && ret < 0) - put_free_dqblk(sb, dquot->dq_type, buf, *treeblk); + put_free_dqblk(dqh, dquot->dq_type, buf, *treeblk); out_buf: freedqbuf(buf); return ret; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -409,10 +411,11 @@ static int v2_write_dquot(struct dquot * if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk))) ddquot.dqb_itime = cpu_to_le64(1); spin_unlock(&dq_data_lock); - ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, + ret = dquot->dq_dqh->dqh_sb->s_op->quota_write(dquot->dq_dqh, type, (char *)&ddquot, sizeof(struct v2_disk_dqblk), dquot->dq_off); if (ret != sizeof(struct v2_disk_dqblk)) { - printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id); + printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", + dquot->dq_dqh->dqh_sb->s_id); if (ret >= 0) ret = -ENOSPC; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -426,7 +429,8 @@ static int v2_write_dquot(struct dquot * /* Free dquot entry in data block */ static int free_dqentry(struct dquot *dquot, uint blk) { - struct super_block *sb = dquot->dq_sb; + // struct super_block *sb = dquot->dq_sb; + struct dqhash *dqh = dquot->dq_dqh; int type = dquot->dq_type; struct v2_disk_dqdbheader *dh; dqbuf_t buf = getdqbuf(); --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -440,7 +444,7 @@ static int free_dqentry(struct dquot *dq (uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS)); goto out_buf; } - if ((ret = read_blk(sb, type, blk, buf)) < 0) { + if ((ret = read_blk(dqh, type, blk, buf)) < 0) { printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk); goto out_buf; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -447,8 +451,8 @@ ***** dh = (struct v2_disk_dqdbheader *)buf; dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1); if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */ - if ((ret = remove_free_dqentry(sb, type, buf, blk)) < 0 || - (ret = put_free_dqblk(sb, type, buf, blk)) < 0) { + if ((ret = remove_free_dqentry(dqh, type, buf, blk)) < 0 || + (ret = put_free_dqblk(dqh, type, buf, blk)) < 0) { printk(KERN_ERR "VFS: Can't move quota data block (%u) " "to free list.\n", blk); goto out_buf; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -459,7 +463,7 @@ static int free_dqentry(struct dquot *dq sizeof(struct v2_disk_dqblk)); if (le16_to_cpu(dh->dqdh_entries) == V2_DQSTRINBLK-1) { /* Insert will write block itself */ - if ((ret = insert_free_dqentry(sb, type, buf, blk)) < 0) { + if ((ret = insert_free_dqentry(dqh, type, buf, blk)) < 0) { printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk); goto out_buf; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -465,7 +469,7 @@ ***** } } else - if ((ret = write_blk(sb, type, blk, buf)) < 0) { + if ((ret = write_blk(dqh, type, blk, buf)) < 0) { printk(KERN_ERR "VFS: Can't write quota data " "block %u\n", blk); goto out_buf; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -480,7 +484,7 @@ out_buf: /* Remove reference to dquot from tree */ static int remove_tree(struct dquot *dquot, uint *blk, int depth) { - struct super_block *sb = dquot->dq_sb; + struct dqhash *dqh = dquot->dq_dqh; int type = dquot->dq_type; dqbuf_t buf = getdqbuf(); int ret = 0; --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -489,7 +493,7 @@ static int remove_tree(struct dquot *dqu if (!buf) return -ENOMEM; - if ((ret = read_blk(sb, type, *blk, buf)) < 0) { + if ((ret = read_blk(dqh, type, *blk, buf)) < 0) { printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk); goto out_buf; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -506,7 +510,7 @@ static int remove_tree(struct dquot *dqu for (i = 0; i < V2_DQBLKSIZE && !buf[i]; i++); /* Block got empty? */ /* Don't put the root block into the free block list */ if (i == V2_DQBLKSIZE && *blk != V2_DQTREEOFF) { - put_free_dqblk(sb, type, buf, *blk); + put_free_dqblk(dqh, type, buf, *blk); *blk = 0; } else --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -510,7 +514,7 @@ ***** *blk = 0; } else - if ((ret = write_blk(sb, type, *blk, buf)) < 0) + if ((ret = write_blk(dqh, type, *blk, buf)) < 0) printk(KERN_ERR "VFS: Can't write quota tree " "block %u.\n", *blk); } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -539,7 +543,7 @@ static loff_t find_block_dqentry(struct if (!buf) return -ENOMEM; - if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) { + if ((ret = read_blk(dquot->dq_dqh, dquot->dq_type, blk, buf)) < 0) { printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); goto out_buf; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -578,7 +582,7 @@ static loff_t find_tree_dqentry(struct d if (!buf) return -ENOMEM; - if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) { + if ((ret = read_blk(dquot->dq_dqh, dquot->dq_type, blk, buf)) < 0) { printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); goto out_buf; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -610,7 +614,7 @@ static int v2_read_dquot(struct dquot *d #ifdef __QUOTA_V2_PARANOIA /* Invalidated quota? */ - if (!dquot->dq_sb || !sb_dqopt(dquot->dq_sb)->files[type]) { + if (!dquot->dq_dqh || !dqh_dqopt(dquot->dq_dqh)->files[type]) { printk(KERN_ERR "VFS: Quota invalidated while reading!\n"); return -EIO; } --- linux-2.6.16-rc1/fs/quota_v2.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota_v2.c 2006-01-21 18:28:18 +0100 @@ -627,7 +631,7 @@ static int v2_read_dquot(struct dquot *d } else { dquot->dq_off = offset; - if ((ret = dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, + if ((ret = dquot->dq_dqh->dqh_sb->s_op->quota_read(dquot->dq_dqh, type, (char *)&ddquot, sizeof(struct v2_disk_dqblk), offset)) != sizeof(struct v2_disk_dqblk)) { if (ret >= 0) --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -138,7 +138,7 @@ static int remove_save_link_only(struct } #ifdef CONFIG_QUOTA -static int reiserfs_quota_on_mount(struct super_block *, int); +static int reiserfs_quota_on_mount(struct dqhash *, int); #endif /* look for uncompleted unlinks and truncates and complete them */ --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -178,7 +178,7 @@ static int finish_unfinished(struct supe /* Turn on quotas so that they are updated correctly */ for (i = 0; i < MAXQUOTAS; i++) { if (REISERFS_SB(s)->s_qf_names[i]) { - int ret = reiserfs_quota_on_mount(s, i); + int ret = reiserfs_quota_on_mount(s->s_dqh, i); if (ret < 0) reiserfs_warning(s, "reiserfs: cannot turn on journalled quota: error %d", --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -292,8 +292,8 @@ static int finish_unfinished(struct supe #ifdef CONFIG_QUOTA /* Turn quotas off */ for (i = 0; i < MAXQUOTAS; i++) { - if (sb_dqopt(s)->files[i]) - vfs_quota_off_mount(s, i); + if (dqh_dqopt(s->s_dqh)->files[i]) + vfs_quota_off_mount(s->s_dqh, i); } if (ms_active_set) /* Restore the flag back */ --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -584,9 +584,9 @@ static void reiserfs_clear_inode(struct } #ifdef CONFIG_QUOTA -static ssize_t reiserfs_quota_write(struct super_block *, int, const char *, +static ssize_t reiserfs_quota_write(struct dqhash *, int, const char *, size_t, loff_t); -static ssize_t reiserfs_quota_read(struct super_block *, int, char *, size_t, +static ssize_t reiserfs_quota_read(struct dqhash *, int, char *, size_t, loff_t); #endif --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -619,8 +619,8 @@ static int reiserfs_write_dquot(struct d static int reiserfs_acquire_dquot(struct dquot *); static int reiserfs_release_dquot(struct dquot *); static int reiserfs_mark_dquot_dirty(struct dquot *); -static int reiserfs_write_info(struct super_block *, int); -static int reiserfs_quota_on(struct super_block *, int, int, char *); +static int reiserfs_write_info(struct dqhash *, int); +static int reiserfs_quota_on(struct dqhash *, int, int, char *); static struct dquot_operations reiserfs_quota_operations = { .initialize = reiserfs_dquot_initialize, --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -995,7 +1003,7 @@ static int reiserfs_parse_options(struct if (c == 'u' || c == 'g') { int qtype = c == 'u' ? USRQUOTA : GRPQUOTA; - if (sb_any_quota_enabled(s)) { + if (dqh_any_quota_enabled(s->s_dqh)) { reiserfs_warning(s, "reiserfs_parse_options: cannot change journalled quota options when quota turned on."); return 0; --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -1058,7 +1066,7 @@ static int reiserfs_parse_options(struct } /* This checking is not precise wrt the quota type but for our purposes it is sufficient */ if (!(*mount_options & (1 << REISERFS_QUOTA)) - && sb_any_quota_enabled(s)) { + && dqh_any_quota_enabled(s->s_dqh)) { reiserfs_warning(s, "reiserfs_parse_options: quota options must be present when quota is turned on."); return 0; --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -1464,7 +1478,7 @@ static int read_super_block(struct super s->s_export_op = &reiserfs_export_ops; #ifdef CONFIG_QUOTA s->s_qcop = &reiserfs_qctl_operations; - s->dq_op = &reiserfs_quota_operations; + s->s_qop = &reiserfs_quota_operations; #endif /* new format is limited by the 32 bit wide i_blocks field, want to --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2011,10 +2029,10 @@ static int reiserfs_write_dquot(struct d struct reiserfs_transaction_handle th; int ret, err; - reiserfs_write_lock(dquot->dq_sb); + reiserfs_write_lock(dquot->dq_dqh->dqh_sb); ret = - journal_begin(&th, dquot->dq_sb, - REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); + journal_begin(&th, dquot->dq_dqh->dqh_sb, + REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb)); if (ret) goto out; ret = dquot_commit(dquot); --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2019,8 +2037,8 @@ ***** goto out; ret = dquot_commit(dquot); err = - journal_end(&th, dquot->dq_sb, - REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); + journal_end(&th, dquot->dq_dqh->dqh_sb, + REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb)); if (!ret && err) ret = err; out: --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2033,10 +2051,10 @@ static int reiserfs_acquire_dquot(struct struct reiserfs_transaction_handle th; int ret, err; - reiserfs_write_lock(dquot->dq_sb); + reiserfs_write_lock(dquot->dq_dqh->dqh_sb); ret = - journal_begin(&th, dquot->dq_sb, - REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); + journal_begin(&th, dquot->dq_dqh->dqh_sb, + REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb)); if (ret) goto out; ret = dquot_acquire(dquot); --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2041,8 +2059,8 @@ ***** goto out; ret = dquot_acquire(dquot); err = - journal_end(&th, dquot->dq_sb, - REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); + journal_end(&th, dquot->dq_dqh->dqh_sb, + REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb)); if (!ret && err) ret = err; out: --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2046,7 +2064,7 @@ ***** if (!ret && err) ret = err; out: - reiserfs_write_unlock(dquot->dq_sb); + reiserfs_write_unlock(dquot->dq_dqh->dqh_sb); return ret; } --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2055,10 +2073,10 @@ static int reiserfs_release_dquot(struct struct reiserfs_transaction_handle th; int ret, err; - reiserfs_write_lock(dquot->dq_sb); + reiserfs_write_lock(dquot->dq_dqh->dqh_sb); ret = - journal_begin(&th, dquot->dq_sb, - REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); + journal_begin(&th, dquot->dq_dqh->dqh_sb, + REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb)); if (ret) goto out; ret = dquot_release(dquot); --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2063,8 +2081,8 @@ ***** goto out; ret = dquot_release(dquot); err = - journal_end(&th, dquot->dq_sb, - REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); + journal_end(&th, dquot->dq_dqh->dqh_sb, + REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb)); if (!ret && err) ret = err; out: --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2068,7 +2086,7 @@ ***** if (!ret && err) ret = err; out: - reiserfs_write_unlock(dquot->dq_sb); + reiserfs_write_unlock(dquot->dq_dqh->dqh_sb); return ret; } --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2075,8 +2093,8 @@ ***** static int reiserfs_mark_dquot_dirty(struct dquot *dquot) { /* Are we journalling quotas? */ - if (REISERFS_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || - REISERFS_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { + if (REISERFS_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[USRQUOTA] || + REISERFS_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[GRPQUOTA]) { dquot_mark_dquot_dirty(dquot); return reiserfs_write_dquot(dquot); } else --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2083,9 +2101,10 @@ ***** return dquot_mark_dquot_dirty(dquot); } -static int reiserfs_write_info(struct super_block *sb, int type) +static int reiserfs_write_info(struct dqhash *hash, int type) { struct reiserfs_transaction_handle th; + struct super_block *sb = hash->dqh_sb; int ret, err; /* Data block + inode block */ --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2093,7 +2112,7 @@ static int reiserfs_write_info(struct su ret = journal_begin(&th, sb, 2); if (ret) goto out; - ret = dquot_commit_info(sb, type); + ret = dquot_commit_info(hash, type); err = journal_end(&th, sb, 2); if (!ret && err) ret = err; --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2105,9 +2124,11 @@ static int reiserfs_write_info(struct su /* * Turn on quotas during mount time - we need to find the quota file and such... */ -static int reiserfs_quota_on_mount(struct super_block *sb, int type) +static int reiserfs_quota_on_mount(struct dqhash *hash, int type) { - return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type], + struct super_block *sb = hash->dqh_sb; + + return vfs_quota_on_mount(hash, REISERFS_SB(sb)->s_qf_names[type], REISERFS_SB(sb)->s_jquota_fmt, type); } --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2114,9 +2135,10 @@ ***** /* * Standard function to be called on quota_on */ -static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, +static int reiserfs_quota_on(struct dqhash *hash, int type, int format_id, char *path) { + struct super_block *sb = hash->dqh_sb; int err; struct nameidata nd; --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2141,7 +2163,7 @@ static int reiserfs_quota_on(struct supe if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] && !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) { path_release(&nd); - return vfs_quota_on(sb, type, format_id, path); + return vfs_quota_on(hash, type, format_id, path); } /* Quotafile not of fs root? */ if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode) --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2149,7 +2171,7 @@ static int reiserfs_quota_on(struct supe "reiserfs: Quota file not on filesystem root. " "Journalled quota will not work."); path_release(&nd); - return vfs_quota_on(sb, type, format_id, path); + return vfs_quota_on(hash, type, format_id, path); } /* Read data from quotafile - avoid pagecache and such because we cannot afford --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2156,10 +2178,11 @@ ***** * acquiring the locks... As quota files are never truncated and quota code * itself serializes the operations (and noone else should touch the files) * we don't have to be afraid of races */ -static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data, +static ssize_t reiserfs_quota_read(struct dqhash *hash, int type, char *data, size_t len, loff_t off) { - struct inode *inode = sb_dqopt(sb)->files[type]; + struct inode *inode = dqh_dqopt(hash)->files[type]; + struct super_block *sb = hash->dqh_sb; unsigned long blk = off >> sb->s_blocksize_bits; int err = 0, offset = off & (sb->s_blocksize - 1), tocopy; size_t toread; --- linux-2.6.16-rc1/fs/reiserfs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/reiserfs/super.c 2006-01-25 05:34:51 +0100 @@ -2201,10 +2224,11 @@ static ssize_t reiserfs_quota_read(struc /* Write to quotafile (we know the transaction is already started and has * enough credits) */ -static ssize_t reiserfs_quota_write(struct super_block *sb, int type, +static ssize_t reiserfs_quota_write(struct dqhash *hash, int type, const char *data, size_t len, loff_t off) { - struct inode *inode = sb_dqopt(sb)->files[type]; + struct inode *inode = dqh_dqopt(hash)->files[type]; + struct super_block *sb = hash->dqh_sb; unsigned long blk = off >> sb->s_blocksize_bits; int err = 0, offset = off & (sb->s_blocksize - 1), tocopy; int journal_quota = REISERFS_SB(sb)->s_qf_names[type] != NULL; --- linux-2.6.16-rc1/fs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/super.c 2006-01-21 18:28:18 +0100 @@ -77,12 +79,9 @@ static struct super_block *alloc_super(v s->s_count = S_BIAS; atomic_set(&s->s_active, 1); sema_init(&s->s_vfs_rename_sem,1); - sema_init(&s->s_dquot.dqio_sem, 1); - sema_init(&s->s_dquot.dqonoff_sem, 1); - init_rwsem(&s->s_dquot.dqptr_sem); init_waitqueue_head(&s->s_wait_unfrozen); s->s_maxbytes = MAX_NON_LFS; - s->dq_op = sb_dquot_ops; + s->s_qop = sb_dquot_ops; s->s_qcop = sb_quotactl_ops; s->s_op = &default_op; s->s_time_gran = 1000000000; --- linux-2.6.16-rc1/fs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/super.c 2006-01-21 18:28:18 +0100 @@ -86,6 +85,8 @@ ***** s->s_qcop = sb_quotactl_ops; s->s_op = &default_op; s->s_time_gran = 1000000000; + /* quick hack to make dqhash id unique, sufficient for now */ + s->s_dqh = new_dqhash(s, (unsigned long)s); } out: return s; --- linux-2.6.16-rc1/fs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/super.c 2006-01-21 18:28:18 +0100 @@ -100,6 +101,7 @@ out: static inline void destroy_super(struct super_block *s) { security_sb_free(s); + dqhput(s->s_dqh); kfree(s); } --- linux-2.6.16-rc1/fs/udf/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/udf/super.c 2006-01-21 18:28:18 +0100 @@ -1559,7 +1559,7 @@ static int udf_fill_super(struct super_b /* Fill in the rest of the superblock */ sb->s_op = &udf_sb_ops; - sb->dq_op = NULL; + sb->s_qop = NULL; sb->s_dirt = 0; sb->s_magic = UDF_SUPER_MAGIC; sb->s_time_gran = 1000; --- linux-2.6.16-rc1/fs/ufs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ufs/super.c 2006-01-21 18:28:18 +0100 @@ -871,7 +871,7 @@ magic_found: * Read ufs_super_block into internal data structures */ sb->s_op = &ufs_super_ops; - sb->dq_op = NULL; /***/ + sb->s_qop = NULL; /***/ sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic); uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno); --- linux-2.6.16-rc1/fs/ufs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ufs/super.c 2006-01-21 18:28:18 +0100 @@ -1196,8 +1196,8 @@ static void destroy_inodecache(void) } #ifdef CONFIG_QUOTA -static ssize_t ufs_quota_read(struct super_block *, int, char *,size_t, loff_t); -static ssize_t ufs_quota_write(struct super_block *, int, const char *, size_t, loff_t); +static ssize_t ufs_quota_read(struct dqhash *, int, char *,size_t, loff_t); +static ssize_t ufs_quota_write(struct dqhash *, int, const char *, size_t, loff_t); #endif static struct super_operations ufs_super_ops = { --- linux-2.6.16-rc1/fs/ufs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ufs/super.c 2006-01-21 18:28:18 +0100 @@ -1222,10 +1222,11 @@ static struct super_operations ufs_super * acquiring the locks... As quota files are never truncated and quota code * itself serializes the operations (and noone else should touch the files) * we don't have to be afraid of races */ -static ssize_t ufs_quota_read(struct super_block *sb, int type, char *data, +static ssize_t ufs_quota_read(struct dqhash *hash, int type, char *data, size_t len, loff_t off) { - struct inode *inode = sb_dqopt(sb)->files[type]; + struct inode *inode = dqh_dqopt(hash)->files[type]; + struct super_block *sb = hash->dqh_sb; sector_t blk = off >> sb->s_blocksize_bits; int err = 0; int offset = off & (sb->s_blocksize - 1); --- linux-2.6.16-rc1/fs/ufs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/ufs/super.c 2006-01-21 18:28:18 +0100 @@ -1261,10 +1262,11 @@ static ssize_t ufs_quota_read(struct sup } /* Write to quotafile */ -static ssize_t ufs_quota_write(struct super_block *sb, int type, +static ssize_t ufs_quota_write(struct dqhash *hash, int type, const char *data, size_t len, loff_t off) { - struct inode *inode = sb_dqopt(sb)->files[type]; + struct inode *inode = dqh_dqopt(hash)->files[type]; + struct super_block *sb = hash->dqh_sb; sector_t blk = off >> sb->s_blocksize_bits; int err = 0; int offset = off & (sb->s_blocksize - 1); --- linux-2.6.16-rc1/fs/xfs/linux-2.6/xfs_super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/linux-2.6/xfs_super.c 2006-01-25 05:34:51 +0100 @@ -756,9 +771,10 @@ linvfs_show_options( STATIC int linvfs_quotasync( - struct super_block *sb, + struct dqhash *hash, int type) { + struct super_block *sb = hash->dqh_sb; struct vfs *vfsp = LINVFS_GET_VFS(sb); int error; --- linux-2.6.16-rc1/fs/xfs/linux-2.6/xfs_super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/linux-2.6/xfs_super.c 2006-01-25 05:34:51 +0100 @@ -768,10 +784,10 @@ linvfs_quotasync( STATIC int linvfs_getxstate( - struct super_block *sb, + struct dqhash *hash, struct fs_quota_stat *fqs) { - struct vfs *vfsp = LINVFS_GET_VFS(sb); + struct vfs *vfsp = LINVFS_GET_VFS(hash->dqh_sb); int error; VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error); --- linux-2.6.16-rc1/fs/xfs/linux-2.6/xfs_super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/linux-2.6/xfs_super.c 2006-01-25 05:34:51 +0100 @@ -780,7 +796,7 @@ linvfs_getxstate( STATIC int linvfs_setxstate( - struct super_block *sb, + struct dqhash *hash, unsigned int flags, int op) { --- linux-2.6.16-rc1/fs/xfs/linux-2.6/xfs_super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/linux-2.6/xfs_super.c 2006-01-25 05:34:51 +0100 @@ -784,7 +800,7 @@ ***** unsigned int flags, int op) { - struct vfs *vfsp = LINVFS_GET_VFS(sb); + struct vfs *vfsp = LINVFS_GET_VFS(hash->dqh_sb); int error; VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error); --- linux-2.6.16-rc1/fs/xfs/linux-2.6/xfs_super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/linux-2.6/xfs_super.c 2006-01-25 05:34:51 +0100 @@ -793,7 +809,7 @@ linvfs_setxstate( STATIC int linvfs_getxquota( - struct super_block *sb, + struct dqhash *hash, int type, qid_t id, struct fs_disk_quota *fdq) --- linux-2.6.16-rc1/fs/xfs/linux-2.6/xfs_super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/linux-2.6/xfs_super.c 2006-01-25 05:34:51 +0100 @@ -798,7 +814,7 @@ ***** qid_t id, struct fs_disk_quota *fdq) { - struct vfs *vfsp = LINVFS_GET_VFS(sb); + struct vfs *vfsp = LINVFS_GET_VFS(hash->dqh_sb); int error, getmode; getmode = (type == USRQUOTA) ? Q_XGETQUOTA : --- linux-2.6.16-rc1/fs/xfs/linux-2.6/xfs_super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/linux-2.6/xfs_super.c 2006-01-25 05:34:51 +0100 @@ -809,7 +825,7 @@ linvfs_getxquota( STATIC int linvfs_setxquota( - struct super_block *sb, + struct dqhash *hash, int type, qid_t id, struct fs_disk_quota *fdq) --- linux-2.6.16-rc1/fs/xfs/linux-2.6/xfs_super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/linux-2.6/xfs_super.c 2006-01-25 05:34:51 +0100 @@ -814,7 +830,7 @@ ***** qid_t id, struct fs_disk_quota *fdq) { - struct vfs *vfsp = LINVFS_GET_VFS(sb); + struct vfs *vfsp = LINVFS_GET_VFS(hash->dqh_sb); int error, setmode; setmode = (type == USRQUOTA) ? Q_XSETQLIM : --- linux-2.6.16-rc1/fs/xfs/linux-2.6/xfs_super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/linux-2.6/xfs_super.c 2006-01-25 05:34:51 +0100 @@ -852,6 +868,9 @@ linvfs_fill_super( sb->s_export_op = &linvfs_export_ops; #endif sb->s_qcop = &linvfs_qops; +#ifdef CONFIG_QUOTA + sb->s_dqh->dqh_qcop = &linvfs_qops; +#endif sb->s_op = &linvfs_sops; VFS_MOUNT(vfsp, args, NULL, error); --- linux-2.6.16-rc1/fs/xfs/quota/xfs_qm_syscalls.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/quota/xfs_qm_syscalls.c 2006-01-21 18:28:18 +0100 @@ -215,7 +215,7 @@ xfs_qm_scall_quotaoff( xfs_qoff_logitem_t *qoffstart; int nculprits; - if (!force && !capable(CAP_SYS_ADMIN)) + if (!force && !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) return XFS_ERROR(EPERM); /* * No file system can have quotas enabled on disk but not in core. --- linux-2.6.16-rc1/fs/xfs/xfs_vnodeops.c 2006-01-26 22:35:14 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/xfs_vnodeops.c 2006-01-25 05:34:51 +0100 @@ -709,6 +717,12 @@ xfs_setattr( * Change the ownerships and register quota modifications * in the transaction. */ + if (itag != tag) { + if (XFS_IS_GQUOTA_ON(mp)) { + /* FIXME: handle tag quota? */ + } + ip->i_d.di_tag = tag; + } if (iuid != uid) { if (XFS_IS_UQUOTA_ON(mp)) { ASSERT(mask & XFS_AT_UID); --- linux-2.6.16-rc1/include/linux/ext3_jbd.h 2005-08-29 22:25:41 +0200 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/ext3_jbd.h 2006-01-21 18:28:18 +0100 @@ -77,10 +77,10 @@ #define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) /* Amount of blocks needed for quota insert/delete - we do some block writes * but inode, sb and group updates are done only once */ -#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) -#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) +#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? \ + (DQUOT_INIT_ALLOC*(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) +#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? \ + (DQUOT_DEL_ALLOC*(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) #else #define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 #define EXT3_QUOTA_INIT_BLOCKS(sb) 0 --- linux-2.6.16-rc1/include/linux/fs.h 2006-01-26 22:35:19 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/fs.h 2006-01-29 16:01:52 +0100 @@ -488,6 +506,7 @@ struct inode { struct address_space *i_mapping; struct address_space i_data; #ifdef CONFIG_QUOTA + struct dqhash *i_dqh; struct dquot *i_dquot[MAXQUOTAS]; #endif /* These three should probably be a union */ --- linux-2.6.16-rc1/include/linux/fs.h 2006-01-26 22:35:19 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/fs.h 2006-01-29 16:01:52 +0100 @@ -808,7 +829,7 @@ struct super_block { unsigned long long s_maxbytes; /* Max file size */ struct file_system_type *s_type; struct super_operations *s_op; - struct dquot_operations *dq_op; + struct dquot_operations *s_qop; struct quotactl_ops *s_qcop; struct export_operations *s_export_op; unsigned long s_flags; --- linux-2.6.16-rc1/include/linux/fs.h 2006-01-26 22:35:19 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/fs.h 2006-01-29 16:01:52 +0100 @@ -831,7 +852,7 @@ struct super_block { struct block_device *s_bdev; struct list_head s_instances; - struct quota_info s_dquot; /* Diskquota specific options */ + struct dqhash *s_dqh; /* Diskquota hash */ int s_frozen; wait_queue_head_t s_wait_unfrozen; --- linux-2.6.16-rc1/include/linux/fs.h 2006-01-26 22:35:19 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/fs.h 2006-01-29 16:01:52 +0100 @@ -1084,8 +1107,8 @@ struct super_operations { int (*show_options)(struct seq_file *, struct vfsmount *); - ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); - ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); + ssize_t (*quota_read)(struct dqhash *, int, char *, size_t, loff_t); + ssize_t (*quota_write)(struct dqhash *, int, const char *, size_t, loff_t); }; /* Inode state bits. Protected by inode_lock. */ --- linux-2.6.16-rc1/include/linux/fs.h 2006-01-26 22:35:19 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/fs.h 2006-01-29 16:01:52 +0100 @@ -1532,7 +1555,7 @@ extern void clear_inode(struct inode *); extern void destroy_inode(struct inode *); extern struct inode *new_inode(struct super_block *); extern int remove_suid(struct dentry *); -extern void remove_dquot_ref(struct super_block *, int, struct list_head *); +extern void remove_dquot_ref(struct dqhash *, int, struct list_head *); extern struct semaphore iprune_sem; extern void __insert_inode_hash(struct inode *, unsigned long hashval); --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -56,6 +56,13 @@ extern spinlock_t dq_data_lock; #define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10)) #define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS) +/* are NULL dqhash ptrs valid? */ +#ifdef HANDLE_DQHASH_NULL +#define dqhash_valid(hash) ((hash) != NULL) +#else +#define dqhash_valid(hash) (0 == 0) +#endif + #define MAXQUOTAS 2 #define USRQUOTA 0 /* element used for user quotas */ #define GRPQUOTA 1 /* element used for group quotas */ --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -175,7 +182,7 @@ struct mem_dqinfo { } u; }; -struct super_block; +struct dqhash; #define DQF_MASK 0xffff /* Mask for format specific flags */ #define DQF_INFO_DIRTY_B 16 --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -181,7 +188,8 @@ ***** #define DQF_INFO_DIRTY_B 16 #define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */ -extern void mark_info_dirty(struct super_block *sb, int type); +extern void mark_info_dirty(struct dqhash *hash, int type); + #define info_dirty(info) test_bit(DQF_INFO_DIRTY_B, &(info)->dqi_flags) #define info_any_dquot_dirty(info) (!list_empty(&(info)->dqi_dirty_list)) #define info_any_dirty(info) (info_dirty(info) || info_any_dquot_dirty(info)) --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -186,8 +194,8 @@ ***** #define info_any_dquot_dirty(info) (!list_empty(&(info)->dqi_dirty_list)) #define info_any_dirty(info) (info_dirty(info) || info_any_dquot_dirty(info)) -#define sb_dqopt(sb) (&(sb)->s_dquot) -#define sb_dqinfo(sb, type) (sb_dqopt(sb)->info+(type)) +#define dqh_dqopt(hash) (&(hash)->dqh_dqopt) +#define dqh_dqinfo(hash, type) (dqh_dqopt(hash)->info+(type)) struct dqstats { int lookups; --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -218,7 +226,7 @@ struct dquot { struct semaphore dq_lock; /* dquot IO lock */ atomic_t dq_count; /* Use count */ wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */ - struct super_block *dq_sb; /* superblock this applies to */ + struct dqhash *dq_dqh; /* quota hash backpointer */ unsigned int dq_id; /* ID this applies to (uid, gid) */ loff_t dq_off; /* Offset of dquot on disk */ unsigned long dq_flags; /* See DQ_* */ --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -233,13 +241,14 @@ struct dquot { /* Operations which must be implemented by each quota format */ struct quota_format_ops { - int (*check_quota_file)(struct super_block *sb, int type); /* Detect whether file is in our format */ - int (*read_file_info)(struct super_block *sb, int type); /* Read main info about file - called on quotaon() */ - int (*write_file_info)(struct super_block *sb, int type); /* Write main info about file */ - int (*free_file_info)(struct super_block *sb, int type); /* Called on quotaoff() */ - int (*read_dqblk)(struct dquot *dquot); /* Read structure for one user */ - int (*commit_dqblk)(struct dquot *dquot); /* Write structure for one user */ - int (*release_dqblk)(struct dquot *dquot); /* Called when last reference to dquot is being dropped */ + int (*check_quota_file)(struct dqhash *, int); /* Detect whether file is in our format */ + int (*read_file_info)(struct dqhash *, int); /* Read main info about file - called on quotaon() */ + int (*write_file_info)(struct dqhash *, int); /* Write main info about file */ + int (*free_file_info)(struct dqhash *, int); /* Called on quotaoff() */ + + int (*read_dqblk)(struct dquot *); /* Read structure for one user */ + int (*commit_dqblk)(struct dquot *); /* Write structure for one user */ + int (*release_dqblk)(struct dquot *); /* Called when last reference to dquot is being dropped */ }; /* Operations working with dquots */ --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -255,7 +264,7 @@ struct dquot_operations { int (*acquire_dquot) (struct dquot *); /* Quota is going to be created on disk */ int (*release_dquot) (struct dquot *); /* Quota is going to be deleted from disk */ int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */ - int (*write_info) (struct super_block *, int); /* Write of quota "superblock" */ + int (*write_info) (struct dqhash *, int); /* Write of quota "superblock" */ }; /* Operations handling requests from userspace */ --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -260,17 +269,17 @@ ***** /* Operations handling requests from userspace */ struct quotactl_ops { - int (*quota_on)(struct super_block *, int, int, char *); - int (*quota_off)(struct super_block *, int); - int (*quota_sync)(struct super_block *, int); - int (*get_info)(struct super_block *, int, struct if_dqinfo *); - int (*set_info)(struct super_block *, int, struct if_dqinfo *); - int (*get_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *); - int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *); - int (*get_xstate)(struct super_block *, struct fs_quota_stat *); - int (*set_xstate)(struct super_block *, unsigned int, int); - int (*get_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *); - int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *); + int (*quota_on)(struct dqhash *, int, int, char *); + int (*quota_off)(struct dqhash *, int); + int (*quota_sync)(struct dqhash *, int); + int (*get_info)(struct dqhash *, int, struct if_dqinfo *); + int (*set_info)(struct dqhash *, int, struct if_dqinfo *); + int (*get_dqblk)(struct dqhash *, int, qid_t, struct if_dqblk *); + int (*set_dqblk)(struct dqhash *, int, qid_t, struct if_dqblk *); + int (*get_xstate)(struct dqhash *, struct fs_quota_stat *); + int (*set_xstate)(struct dqhash *, unsigned int, int); + int (*get_xquota)(struct dqhash *, int, qid_t, struct fs_disk_quota *); + int (*set_xquota)(struct dqhash *, int, qid_t, struct fs_disk_quota *); }; struct quota_format_type { --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -293,8 +302,6 @@ struct quota_info { struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ }; -/* Inline would be better but we need to dereference super_block which is not defined yet */ -int mark_dquot_dirty(struct dquot *dquot); #define dquot_dirty(dquot) test_bit(DQ_MOD_B, &(dquot)->dq_flags) --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -298,11 +305,12 @@ ***** #define dquot_dirty(dquot) test_bit(DQ_MOD_B, &(dquot)->dq_flags) -#define sb_has_quota_enabled(sb, type) ((type)==USRQUOTA ? \ - (sb_dqopt(sb)->flags & DQUOT_USR_ENABLED) : (sb_dqopt(sb)->flags & DQUOT_GRP_ENABLED)) +#define dqh_has_quota_enabled(hash, type) (dqhash_valid(hash) && ((type)==USRQUOTA ? \ + (dqh_dqopt(hash)->flags & DQUOT_USR_ENABLED) : (dqh_dqopt(hash)->flags & DQUOT_GRP_ENABLED))) + +#define dqh_any_quota_enabled(hash) (dqhash_valid(hash) && \ + (dqh_has_quota_enabled(hash, USRQUOTA) || dqh_has_quota_enabled(hash, GRPQUOTA))) -#define sb_any_quota_enabled(sb) (sb_has_quota_enabled(sb, USRQUOTA) | \ - sb_has_quota_enabled(sb, GRPQUOTA)) int register_quota_format(struct quota_format_type *fmt); void unregister_quota_format(struct quota_format_type *fmt); --- linux-2.6.16-rc1/include/linux/quota.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quota.h 2006-01-21 18:28:18 +0100 @@ -317,6 +325,51 @@ struct quota_module_name { {QFMT_VFS_V0, "quota_v2"},\ {0, NULL}} +struct dqhash { + struct list_head dqh_list; /* List of all quota hashes */ + unsigned int dqh_id; /* ID for hash */ + atomic_t dqh_count; /* Use count */ + struct quota_info dqh_dqopt; /* Diskquota specific options */ + struct dquot_operations *dqh_qop; + struct quotactl_ops *dqh_qcop; + struct super_block *dqh_sb; /* super block */ + unsigned int dqh_hash_bits; + unsigned int dqh_hash_mask; + struct hlist_head *dqh_hash; +}; + +#if defined(CONFIG_QUOTA) + + +struct dqhash *new_dqhash(struct super_block *, unsigned int); +void destroy_dqhash(struct dqhash *); +struct dqhash *find_dqhash(unsigned int); + +static inline void dqhput(struct dqhash *hash) +{ + if (dqhash_valid(hash)) + if (atomic_dec_and_test(&hash->dqh_count)) + destroy_dqhash(hash); +} + +static inline struct dqhash *dqhget(struct dqhash *hash) +{ + if (dqhash_valid(hash)) + atomic_inc(&hash->dqh_count); + return hash; +} + +#else /* CONFIG_QUOTA */ + +#define new_dqhash(sb, dqdom) (0) +#define find_dqhash(dqdom) (0) +#define destroy_dqhash(hash) do { } while(0) + +#define dqhput(hash) do { } while(0) +#define dqhget(hash) (hash) + +#endif /* CONFIG_QUOTA */ + #else # /* nodep */ include --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -20,7 +20,7 @@ /* * declaration of quota_function calls in kernel. */ -extern void sync_dquots(struct super_block *sb, int type); +extern void sync_dquots(struct dqhash *hash, int type); extern int dquot_initialize(struct inode *inode, int type); extern int dquot_drop(struct inode *inode); --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -35,19 +35,19 @@ extern int dquot_transfer(struct inode * extern int dquot_commit(struct dquot *dquot); extern int dquot_acquire(struct dquot *dquot); extern int dquot_release(struct dquot *dquot); -extern int dquot_commit_info(struct super_block *sb, int type); +extern int dquot_commit_info(struct dqhash *hash, int type); extern int dquot_mark_dquot_dirty(struct dquot *dquot); -extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path); -extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name, +extern int vfs_quota_on(struct dqhash *hash, int type, int format_id, char *path); +extern int vfs_quota_on_mount(struct dqhash *hash, char *qf_name, int format_id, int type); -extern int vfs_quota_off(struct super_block *sb, int type); -#define vfs_quota_off_mount(sb, type) vfs_quota_off(sb, type) -extern int vfs_quota_sync(struct super_block *sb, int type); -extern int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); -extern int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); -extern int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di); -extern int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di); +extern int vfs_quota_off(struct dqhash *hash, int type); +#define vfs_quota_off_mount(dqh, type) vfs_quota_off(dqh, type) +extern int vfs_quota_sync(struct dqhash *hash, int type); +extern int vfs_get_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii); +extern int vfs_set_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii); +extern int vfs_get_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di); +extern int vfs_set_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di); /* * Operations supported for diskquotas. --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -62,9 +62,12 @@ extern struct quotactl_ops vfs_quotactl_ * need a lot of space in journal for dquot structure allocation. */ static __inline__ void DQUOT_INIT(struct inode *inode) { - BUG_ON(!inode->i_sb); - if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) - inode->i_sb->dq_op->initialize(inode, -1); + if (!dqhash_valid(inode->i_dqh)) + return; + BUG_ON(!inode->i_dqh); + // printk("DQUOT_INIT(%p,%p,%d)\n", inode, inode->i_dqh, dqh_any_quota_enabled(inode->i_dqh)); + if (dqh_any_quota_enabled(inode->i_dqh) && !IS_NOQUOTA(inode)) + inode->i_dqh->dqh_qop->initialize(inode, -1); } /* The same as with DQUOT_INIT */ --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -73,8 +76,8 @@ static __inline__ void DQUOT_DROP(struct /* Here we can get arbitrary inode from clear_inode() so we have * to be careful. OTOH we don't need locking as quota operations * are allowed to change only at mount time */ - if (!IS_NOQUOTA(inode) && inode->i_sb && inode->i_sb->dq_op - && inode->i_sb->dq_op->drop) { + if (!IS_NOQUOTA(inode) && inode->i_dqh && inode->i_dqh->dqh_qop + && inode->i_dqh->dqh_qop->drop) { int cnt; /* Test before calling to rule out calls from proc and such * where we are not allowed to block. Note that this is --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -85,7 +88,7 @@ static __inline__ void DQUOT_DROP(struct if (inode->i_dquot[cnt] != NODQUOT) break; if (cnt < MAXQUOTAS) - inode->i_sb->dq_op->drop(inode); + inode->i_dqh->dqh_qop->drop(inode); } } --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -93,9 +96,9 @@ static __inline__ void DQUOT_DROP(struct * a transaction (deadlocks possible otherwise) */ static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { - if (sb_any_quota_enabled(inode->i_sb)) { + if (dqh_any_quota_enabled(inode->i_dqh)) { /* Used space is updated in alloc_space() */ - if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA) + if (inode->i_dqh->dqh_qop->alloc_space(inode, nr, 1) == NO_QUOTA) return 1; } else --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -113,9 +116,9 @@ static __inline__ int DQUOT_PREALLOC_SPA static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { - if (sb_any_quota_enabled(inode->i_sb)) { + if (dqh_any_quota_enabled(inode->i_dqh)) { /* Used space is updated in alloc_space() */ - if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA) + if (inode->i_dqh->dqh_qop->alloc_space(inode, nr, 0) == NO_QUOTA) return 1; } else --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -133,9 +136,9 @@ static __inline__ int DQUOT_ALLOC_SPACE( static __inline__ int DQUOT_ALLOC_INODE(struct inode *inode) { - if (sb_any_quota_enabled(inode->i_sb)) { + if (dqh_any_quota_enabled(inode->i_dqh)) { DQUOT_INIT(inode); - if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) + if (inode->i_dqh->dqh_qop->alloc_inode(inode, 1) == NO_QUOTA) return 1; } return 0; --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -143,8 +146,8 @@ static __inline__ int DQUOT_ALLOC_INODE( static __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { - if (sb_any_quota_enabled(inode->i_sb)) - inode->i_sb->dq_op->free_space(inode, nr); + if (dqh_any_quota_enabled(inode->i_dqh)) + inode->i_dqh->dqh_qop->free_space(inode, nr); else inode_sub_bytes(inode, nr); } --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -157,8 +160,8 @@ static __inline__ void DQUOT_FREE_SPACE( static __inline__ void DQUOT_FREE_INODE(struct inode *inode) { - if (sb_any_quota_enabled(inode->i_sb)) - inode->i_sb->dq_op->free_inode(inode, 1); + if (dqh_any_quota_enabled(inode->i_dqh)) + inode->i_dqh->dqh_qop->free_inode(inode, 1); } static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr) --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -163,9 +166,9 @@ ***** static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr) { - if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) { + if (dqh_any_quota_enabled(inode->i_dqh) && !IS_NOQUOTA(inode)) { DQUOT_INIT(inode); - if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA) + if (inode->i_dqh->dqh_qop->transfer(inode, iattr) == NO_QUOTA) return 1; } return 0; --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -172,9 +175,9 @@ ***** } /* The following two functions cannot be called inside a transaction */ -#define DQUOT_SYNC(sb) sync_dquots(sb, -1) +#define DQUOT_SYNC(hash) sync_dquots(hash, -1) -static __inline__ int DQUOT_OFF(struct super_block *sb) +static __inline__ int DQUOT_OFF(struct dqhash *hash) { int ret = -ENOSYS; --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -178,8 +181,9 @@ ***** { int ret = -ENOSYS; - if (sb_any_quota_enabled(sb) && sb->s_qcop && sb->s_qcop->quota_off) - ret = sb->s_qcop->quota_off(sb, -1); + if (dqh_any_quota_enabled(hash) && hash->dqh_qcop && + hash->dqh_qcop->quota_off) + ret = hash->dqh_qcop->quota_off(hash, -1); return ret; } --- linux-2.6.16-rc1/include/linux/quotaops.h 2006-01-03 17:30:10 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/quotaops.h 2006-01-21 18:28:18 +0100 @@ -195,8 +199,8 @@ static __inline__ int DQUOT_OFF(struct s #define DQUOT_DROP(inode) do { } while(0) #define DQUOT_ALLOC_INODE(inode) (0) #define DQUOT_FREE_INODE(inode) do { } while(0) -#define DQUOT_SYNC(sb) do { } while(0) -#define DQUOT_OFF(sb) do { } while(0) +#define DQUOT_SYNC(hash) do { } while(0) +#define DQUOT_OFF(hash) do { } while(0) #define DQUOT_TRANSFER(inode, iattr) (0) static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { --- linux-2.6.16-rc1/include/linux/security.h 2006-01-26 22:35:20 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/security.h 2006-01-21 18:28:18 +0100 @@ -1102,7 +1102,7 @@ struct security_operations { int (*acct) (struct file * file); int (*sysctl) (struct ctl_table * table, int op); int (*capable) (struct task_struct * tsk, int cap); - int (*quotactl) (int cmds, int type, int id, struct super_block * sb); + int (*quotactl) (int cmds, int type, int id, struct dqhash *); int (*quota_on) (struct dentry * dentry); int (*syslog) (int type); int (*settime) (struct timespec *ts, struct timezone *tz); --- linux-2.6.16-rc1/include/linux/security.h 2006-01-26 22:35:20 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/security.h 2006-01-21 18:28:18 +0100 @@ -1357,9 +1357,9 @@ static inline int security_sysctl(struct } static inline int security_quotactl (int cmds, int type, int id, - struct super_block *sb) + struct dqhash *hash) { - return security_ops->quotactl (cmds, type, id, sb); + return security_ops->quotactl (cmds, type, id, hash); } static inline int security_quota_on (struct dentry * dentry) --- linux-2.6.16-rc1/include/linux/security.h 2006-01-26 22:35:20 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/include/linux/security.h 2006-01-21 18:28:18 +0100 @@ -2064,7 +2064,7 @@ static inline int security_sysctl(struct } static inline int security_quotactl (int cmds, int type, int id, - struct super_block * sb) + struct dqhash * hash) { return 0; } --- linux-2.6.16-rc1/security/dummy.c 2006-01-26 22:35:40 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/security/dummy.c 2006-01-21 18:28:18 +0100 @@ -85,7 +85,7 @@ static int dummy_sysctl (ctl_table * tab return 0; } -static int dummy_quotactl (int cmds, int type, int id, struct super_block *sb) +static int dummy_quotactl (int cmds, int type, int id, struct dqhash *hash) { return 0; } --- linux-2.6.16-rc1/security/selinux/hooks.c 2006-01-26 22:35:40 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/security/selinux/hooks.c 2006-01-21 18:28:18 +0100 @@ -1377,9 +1377,10 @@ static int selinux_sysctl(ctl_table *tab return error; } -static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) +static int selinux_quotactl(int cmds, int type, int id, struct dqhash *hash) { int rc = 0; + struct super_block *sb = hash->dqh_sb; if (!sb) return 0;