Commit 2d0fa467 authored by Jan Kara's avatar Jan Kara

quota: Use function to provide i_dquot pointers

i_dquot array is used by relatively few filesystems (ext?, ocfs2, jfs,
reiserfs) so it is beneficial to move this array to fs-private part of
the inode. We cannot just pass quota pointers from filesystems to quota
functions because during quotaon and quotaoff we have to traverse list
of all inodes and manipulate i_dquot pointers for each inode. So we
provide a function which generic quota code can use to get pointer to
the i_dquot array from the filesystem.
Acked-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 17ef4fdd
...@@ -893,6 +893,14 @@ struct dquot *dqget(struct super_block *sb, struct kqid qid) ...@@ -893,6 +893,14 @@ struct dquot *dqget(struct super_block *sb, struct kqid qid)
} }
EXPORT_SYMBOL(dqget); EXPORT_SYMBOL(dqget);
static inline struct dquot **i_dquot(struct inode *inode)
{
/* Temporary workaround until all filesystems are converted. */
if (!inode->i_sb->s_op->get_dquots)
return inode->i_dquot;
return inode->i_sb->s_op->get_dquots(inode);
}
static int dqinit_needed(struct inode *inode, int type) static int dqinit_needed(struct inode *inode, int type)
{ {
int cnt; int cnt;
...@@ -900,9 +908,9 @@ static int dqinit_needed(struct inode *inode, int type) ...@@ -900,9 +908,9 @@ static int dqinit_needed(struct inode *inode, int type)
if (IS_NOQUOTA(inode)) if (IS_NOQUOTA(inode))
return 0; return 0;
if (type != -1) if (type != -1)
return !inode->i_dquot[type]; return !i_dquot(inode)[type];
for (cnt = 0; cnt < MAXQUOTAS; cnt++) for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (!inode->i_dquot[cnt]) if (!i_dquot(inode)[cnt])
return 1; return 1;
return 0; return 0;
} }
...@@ -965,9 +973,9 @@ static void add_dquot_ref(struct super_block *sb, int type) ...@@ -965,9 +973,9 @@ static void add_dquot_ref(struct super_block *sb, int type)
static void remove_inode_dquot_ref(struct inode *inode, int type, static void remove_inode_dquot_ref(struct inode *inode, int type,
struct list_head *tofree_head) struct list_head *tofree_head)
{ {
struct dquot *dquot = inode->i_dquot[type]; struct dquot *dquot = i_dquot(inode)[type];
inode->i_dquot[type] = NULL; i_dquot(inode)[type] = NULL;
if (!dquot) if (!dquot)
return; return;
...@@ -1402,7 +1410,7 @@ static void __dquot_initialize(struct inode *inode, int type) ...@@ -1402,7 +1410,7 @@ static void __dquot_initialize(struct inode *inode, int type)
* we check it without locking here to avoid unnecessary * we check it without locking here to avoid unnecessary
* dqget()/dqput() calls. * dqget()/dqput() calls.
*/ */
if (inode->i_dquot[cnt]) if (i_dquot(inode)[cnt])
continue; continue;
init_needed = 1; init_needed = 1;
...@@ -1433,8 +1441,8 @@ static void __dquot_initialize(struct inode *inode, int type) ...@@ -1433,8 +1441,8 @@ static void __dquot_initialize(struct inode *inode, int type)
/* We could race with quotaon or dqget() could have failed */ /* We could race with quotaon or dqget() could have failed */
if (!got[cnt]) if (!got[cnt])
continue; continue;
if (!inode->i_dquot[cnt]) { if (!i_dquot(inode)[cnt]) {
inode->i_dquot[cnt] = got[cnt]; i_dquot(inode)[cnt] = got[cnt];
got[cnt] = NULL; got[cnt] = NULL;
/* /*
* Make quota reservation system happy if someone * Make quota reservation system happy if someone
...@@ -1442,7 +1450,7 @@ static void __dquot_initialize(struct inode *inode, int type) ...@@ -1442,7 +1450,7 @@ static void __dquot_initialize(struct inode *inode, int type)
*/ */
rsv = inode_get_rsv_space(inode); rsv = inode_get_rsv_space(inode);
if (unlikely(rsv)) if (unlikely(rsv))
dquot_resv_space(inode->i_dquot[cnt], rsv); dquot_resv_space(i_dquot(inode)[cnt], rsv);
} }
} }
out_err: out_err:
...@@ -1472,8 +1480,8 @@ static void __dquot_drop(struct inode *inode) ...@@ -1472,8 +1480,8 @@ static void __dquot_drop(struct inode *inode)
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
put[cnt] = inode->i_dquot[cnt]; put[cnt] = i_dquot(inode)[cnt];
inode->i_dquot[cnt] = NULL; i_dquot(inode)[cnt] = NULL;
} }
spin_unlock(&dq_data_lock); spin_unlock(&dq_data_lock);
dqput_all(put); dqput_all(put);
...@@ -1494,7 +1502,7 @@ void dquot_drop(struct inode *inode) ...@@ -1494,7 +1502,7 @@ void dquot_drop(struct inode *inode)
* add quota pointers back anyway. * add quota pointers back anyway.
*/ */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt]) if (i_dquot(inode)[cnt])
break; break;
} }
...@@ -1595,7 +1603,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) ...@@ -1595,7 +1603,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
{ {
int cnt, ret = 0, index; int cnt, ret = 0, index;
struct dquot_warn warn[MAXQUOTAS]; struct dquot_warn warn[MAXQUOTAS];
struct dquot **dquots = inode->i_dquot; struct dquot **dquots = i_dquot(inode);
int reserve = flags & DQUOT_SPACE_RESERVE; int reserve = flags & DQUOT_SPACE_RESERVE;
if (!dquot_active(inode)) { if (!dquot_active(inode)) {
...@@ -1647,7 +1655,7 @@ int dquot_alloc_inode(struct inode *inode) ...@@ -1647,7 +1655,7 @@ int dquot_alloc_inode(struct inode *inode)
{ {
int cnt, ret = 0, index; int cnt, ret = 0, index;
struct dquot_warn warn[MAXQUOTAS]; struct dquot_warn warn[MAXQUOTAS];
struct dquot * const *dquots = inode->i_dquot; struct dquot * const *dquots = i_dquot(inode);
if (!dquot_active(inode)) if (!dquot_active(inode))
return 0; return 0;
...@@ -1696,14 +1704,14 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) ...@@ -1696,14 +1704,14 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
/* Claim reserved quotas to allocated quotas */ /* Claim reserved quotas to allocated quotas */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt]) if (i_dquot(inode)[cnt])
dquot_claim_reserved_space(inode->i_dquot[cnt], dquot_claim_reserved_space(i_dquot(inode)[cnt],
number); number);
} }
/* Update inode bytes */ /* Update inode bytes */
inode_claim_rsv_space(inode, number); inode_claim_rsv_space(inode, number);
spin_unlock(&dq_data_lock); spin_unlock(&dq_data_lock);
mark_all_dquot_dirty(inode->i_dquot); mark_all_dquot_dirty(i_dquot(inode));
srcu_read_unlock(&dquot_srcu, index); srcu_read_unlock(&dquot_srcu, index);
return 0; return 0;
} }
...@@ -1725,14 +1733,14 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) ...@@ -1725,14 +1733,14 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
spin_lock(&dq_data_lock); spin_lock(&dq_data_lock);
/* Claim reserved quotas to allocated quotas */ /* Claim reserved quotas to allocated quotas */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) { for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt]) if (i_dquot(inode)[cnt])
dquot_reclaim_reserved_space(inode->i_dquot[cnt], dquot_reclaim_reserved_space(i_dquot(inode)[cnt],
number); number);
} }
/* Update inode bytes */ /* Update inode bytes */
inode_reclaim_rsv_space(inode, number); inode_reclaim_rsv_space(inode, number);
spin_unlock(&dq_data_lock); spin_unlock(&dq_data_lock);
mark_all_dquot_dirty(inode->i_dquot); mark_all_dquot_dirty(i_dquot(inode));
srcu_read_unlock(&dquot_srcu, index); srcu_read_unlock(&dquot_srcu, index);
return; return;
} }
...@@ -1745,7 +1753,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) ...@@ -1745,7 +1753,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
{ {
unsigned int cnt; unsigned int cnt;
struct dquot_warn warn[MAXQUOTAS]; struct dquot_warn warn[MAXQUOTAS];
struct dquot **dquots = inode->i_dquot; struct dquot **dquots = i_dquot(inode);
int reserve = flags & DQUOT_SPACE_RESERVE, index; int reserve = flags & DQUOT_SPACE_RESERVE, index;
if (!dquot_active(inode)) { if (!dquot_active(inode)) {
...@@ -1788,7 +1796,7 @@ void dquot_free_inode(struct inode *inode) ...@@ -1788,7 +1796,7 @@ void dquot_free_inode(struct inode *inode)
{ {
unsigned int cnt; unsigned int cnt;
struct dquot_warn warn[MAXQUOTAS]; struct dquot_warn warn[MAXQUOTAS];
struct dquot * const *dquots = inode->i_dquot; struct dquot * const *dquots = i_dquot(inode);
int index; int index;
if (!dquot_active(inode)) if (!dquot_active(inode))
...@@ -1865,7 +1873,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) ...@@ -1865,7 +1873,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
if (!sb_has_quota_active(inode->i_sb, cnt)) if (!sb_has_quota_active(inode->i_sb, cnt))
continue; continue;
is_valid[cnt] = 1; is_valid[cnt] = 1;
transfer_from[cnt] = inode->i_dquot[cnt]; transfer_from[cnt] = i_dquot(inode)[cnt];
ret = check_idq(transfer_to[cnt], 1, &warn_to[cnt]); ret = check_idq(transfer_to[cnt], 1, &warn_to[cnt]);
if (ret) if (ret)
goto over_quota; goto over_quota;
...@@ -1901,7 +1909,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) ...@@ -1901,7 +1909,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
dquot_incr_space(transfer_to[cnt], cur_space); dquot_incr_space(transfer_to[cnt], cur_space);
dquot_resv_space(transfer_to[cnt], rsv_space); dquot_resv_space(transfer_to[cnt], rsv_space);
inode->i_dquot[cnt] = transfer_to[cnt]; i_dquot(inode)[cnt] = transfer_to[cnt];
} }
spin_unlock(&dq_data_lock); spin_unlock(&dq_data_lock);
......
...@@ -1591,6 +1591,7 @@ struct super_operations { ...@@ -1591,6 +1591,7 @@ struct super_operations {
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); 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_write)(struct super_block *, int, const char *, size_t, loff_t);
struct dquot **(*get_dquots)(struct inode *);
#endif #endif
int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t); int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
long (*nr_cached_objects)(struct super_block *, int); long (*nr_cached_objects)(struct super_block *, int);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment