diff options
| -rw-r--r-- | fs/quota/dquot.c | 51 |
1 files changed, 19 insertions, 32 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 251771916069..fb2d2e2a89e7 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
| @@ -733,7 +733,6 @@ static struct shrinker dqcache_shrinker = { | |||
| 733 | 733 | ||
| 734 | /* | 734 | /* |
| 735 | * Put reference to dquot | 735 | * Put reference to dquot |
| 736 | * NOTE: If you change this function please check whether dqput_blocks() works right... | ||
| 737 | */ | 736 | */ |
| 738 | void dqput(struct dquot *dquot) | 737 | void dqput(struct dquot *dquot) |
| 739 | { | 738 | { |
| @@ -963,46 +962,34 @@ static void add_dquot_ref(struct super_block *sb, int type) | |||
| 963 | } | 962 | } |
| 964 | 963 | ||
| 965 | /* | 964 | /* |
| 966 | * Return 0 if dqput() won't block. | ||
| 967 | * (note that 1 doesn't necessarily mean blocking) | ||
| 968 | */ | ||
| 969 | static inline int dqput_blocks(struct dquot *dquot) | ||
| 970 | { | ||
| 971 | if (atomic_read(&dquot->dq_count) <= 1) | ||
| 972 | return 1; | ||
| 973 | return 0; | ||
| 974 | } | ||
| 975 | |||
| 976 | /* | ||
| 977 | * Remove references to dquots from inode and add dquot to list for freeing | 965 | * Remove references to dquots from inode and add dquot to list for freeing |
| 978 | * if we have the last reference to dquot | 966 | * if we have the last reference to dquot |
| 979 | * We can't race with anybody because we hold dqptr_sem for writing... | 967 | * We can't race with anybody because we hold dqptr_sem for writing... |
| 980 | */ | 968 | */ |
| 981 | static int remove_inode_dquot_ref(struct inode *inode, int type, | 969 | static void remove_inode_dquot_ref(struct inode *inode, int type, |
| 982 | struct list_head *tofree_head) | 970 | struct list_head *tofree_head) |
| 983 | { | 971 | { |
| 984 | struct dquot *dquot = inode->i_dquot[type]; | 972 | struct dquot *dquot = inode->i_dquot[type]; |
| 985 | 973 | ||
| 986 | inode->i_dquot[type] = NULL; | 974 | inode->i_dquot[type] = NULL; |
| 987 | if (dquot) { | 975 | if (!dquot) |
| 988 | if (dqput_blocks(dquot)) { | 976 | return; |
| 989 | #ifdef CONFIG_QUOTA_DEBUG | 977 | |
| 990 | if (atomic_read(&dquot->dq_count) != 1) | 978 | if (list_empty(&dquot->dq_free)) { |
| 991 | quota_error(inode->i_sb, "Adding dquot with " | 979 | /* |
| 992 | "dq_count %d to dispose list", | 980 | * The inode still has reference to dquot so it can't be in the |
| 993 | atomic_read(&dquot->dq_count)); | 981 | * free list |
| 994 | #endif | 982 | */ |
| 995 | spin_lock(&dq_list_lock); | 983 | spin_lock(&dq_list_lock); |
| 996 | /* As dquot must have currently users it can't be on | 984 | list_add(&dquot->dq_free, tofree_head); |
| 997 | * the free list... */ | 985 | spin_unlock(&dq_list_lock); |
| 998 | list_add(&dquot->dq_free, tofree_head); | 986 | } else { |
| 999 | spin_unlock(&dq_list_lock); | 987 | /* |
| 1000 | return 1; | 988 | * Dquot is already in a list to put so we won't drop the last |
| 1001 | } | 989 | * reference here. |
| 1002 | else | 990 | */ |
| 1003 | dqput(dquot); /* We have guaranteed we won't block */ | 991 | dqput(dquot); |
| 1004 | } | 992 | } |
| 1005 | return 0; | ||
| 1006 | } | 993 | } |
| 1007 | 994 | ||
| 1008 | /* | 995 | /* |
