Showing error 579

User: Jiri Slaby
Error type: Double Lock
Error type description: Some lock is locked twice unintentionally in a sequence
File location: fs/jbd/commit.c
Line in file: 238
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Clang Static Analyzer (3.0)
Smatch (1.59)
Entered: 2011-11-07 22:19:59 UTC


Source:

208        spin_lock(&journal->j_list_lock);
209
210        while (commit_transaction->t_sync_datalist) {
211                jh = commit_transaction->t_sync_datalist;
212                bh = jh2bh(jh);
213                locked = 0;
214
215                /* Get reference just to make sure buffer does not disappear
216                 * when we are forced to drop various locks */
217                get_bh(bh);
218                /* If the buffer is dirty, we need to submit IO and hence
219                 * we need the buffer lock. We try to lock the buffer without
220                 * blocking. If we fail, we need to drop j_list_lock and do
221                 * blocking lock_buffer().
222                 */
223                if (buffer_dirty(bh)) {
224                        if (!trylock_buffer(bh)) {
225                                BUFFER_TRACE(bh, "needs blocking lock");
226                                spin_unlock(&journal->j_list_lock);
227                                /* Write out all data to prevent deadlocks */
228                                journal_do_submit_data(wbuf, bufs);
229                                bufs = 0;
230                                lock_buffer(bh);
231                                spin_lock(&journal->j_list_lock);
232                        }
233                        locked = 1;
234                }
235                /* We have to get bh_state lock. Again out of order, sigh. */
236                if (!inverted_lock(journal, bh)) {
237                        jbd_lock_bh_state(bh);
238                        spin_lock(&journal->j_list_lock);
239                }
240                /* Someone already cleaned up the buffer? */
241                if (!buffer_jbd(bh)
242                        || jh->b_transaction != commit_transaction
243                        || jh->b_jlist != BJ_SyncData) {
244                        jbd_unlock_bh_state(bh);
245                        if (locked)
246                                unlock_buffer(bh);
247                        BUFFER_TRACE(bh, "already cleaned up");
248                        release_data_buffer(bh);
Show full sources