diff options
-rw-r--r-- | fs/dquot.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/fs/dquot.c b/fs/dquot.c index 5bdc4b2a872a..9eb166f91489 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -688,23 +688,27 @@ static int dqinit_needed(struct inode *inode, int type) | |||
688 | /* This routine is guarded by dqonoff_mutex mutex */ | 688 | /* This routine is guarded by dqonoff_mutex mutex */ |
689 | static void add_dquot_ref(struct super_block *sb, int type) | 689 | static void add_dquot_ref(struct super_block *sb, int type) |
690 | { | 690 | { |
691 | struct list_head *p; | 691 | struct inode *inode; |
692 | 692 | ||
693 | restart: | 693 | restart: |
694 | file_list_lock(); | 694 | spin_lock(&inode_lock); |
695 | list_for_each(p, &sb->s_files) { | 695 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { |
696 | struct file *filp = list_entry(p, struct file, f_u.fu_list); | 696 | if (!atomic_read(&inode->i_writecount)) |
697 | struct inode *inode = filp->f_path.dentry->d_inode; | 697 | continue; |
698 | if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) { | 698 | if (!dqinit_needed(inode, type)) |
699 | struct dentry *dentry = dget(filp->f_path.dentry); | 699 | continue; |
700 | file_list_unlock(); | 700 | if (inode->i_state & (I_FREEING|I_WILL_FREE)) |
701 | sb->dq_op->initialize(inode, type); | 701 | continue; |
702 | dput(dentry); | 702 | |
703 | /* As we may have blocked we had better restart... */ | 703 | __iget(inode); |
704 | goto restart; | 704 | spin_unlock(&inode_lock); |
705 | } | 705 | |
706 | sb->dq_op->initialize(inode, type); | ||
707 | iput(inode); | ||
708 | /* As we may have blocked we had better restart... */ | ||
709 | goto restart; | ||
706 | } | 710 | } |
707 | file_list_unlock(); | 711 | spin_unlock(&inode_lock); |
708 | } | 712 | } |
709 | 713 | ||
710 | /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */ | 714 | /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */ |