Skip to content

Commit

Permalink
vfs: Set special lockdep map for dirs only if not set by fs
Browse files Browse the repository at this point in the history
Some filesystems need to set lockdep map for i_mutex differently for
different directories. For example OCFS2 has system directories (for
orphan inode tracking and for gathering all system files like journal
or quota files into a single place) which have different locking
locking rules than standard directories. For a filesystem setting
lockdep map is naturaly done when the inode is read but we have to
modify unlock_new_inode() not to overwrite the lockdep map the filesystem
has set.

Acked-by: peterz@infradead.org
CC: mingo@redhat.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
  • Loading branch information
Jan Kara authored and Joel Becker committed Jun 22, 2009
1 parent df152c2 commit 9a7aa12
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
17 changes: 11 additions & 6 deletions fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -665,12 +665,17 @@ void unlock_new_inode(struct inode *inode)
if (inode->i_mode & S_IFDIR) {
struct file_system_type *type = inode->i_sb->s_type;

/*
* ensure nobody is actually holding i_mutex
*/
mutex_destroy(&inode->i_mutex);
mutex_init(&inode->i_mutex);
lockdep_set_class(&inode->i_mutex, &type->i_mutex_dir_key);
/* Set new key only if filesystem hasn't already changed it */
if (!lockdep_match_class(&inode->i_mutex,
&type->i_mutex_key)) {
/*
* ensure nobody is actually holding i_mutex
*/
mutex_destroy(&inode->i_mutex);
mutex_init(&inode->i_mutex);
lockdep_set_class(&inode->i_mutex,
&type->i_mutex_dir_key);
}
}
#endif
/*
Expand Down
15 changes: 15 additions & 0 deletions include/linux/lockdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,16 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
#define lockdep_set_subclass(lock, sub) \
lockdep_init_map(&(lock)->dep_map, #lock, \
(lock)->dep_map.key, sub)
/*
* Compare locking classes
*/
#define lockdep_match_class(lock, key) lockdep_match_key(&(lock)->dep_map, key)

static inline int lockdep_match_key(struct lockdep_map *lock,
struct lock_class_key *key)
{
return lock->key == key;
}

/*
* Acquire a lock.
Expand Down Expand Up @@ -326,6 +336,11 @@ static inline void lockdep_on(void)
#define lockdep_set_class_and_subclass(lock, key, sub) \
do { (void)(key); } while (0)
#define lockdep_set_subclass(lock, sub) do { } while (0)
/*
* We don't define lockdep_match_class() and lockdep_match_key() for !LOCKDEP
* case since the result is not well defined and the caller should rather
* #ifdef the call himself.
*/

# define INIT_LOCKDEP
# define lockdep_reset() do { debug_locks = 1; } while (0)
Expand Down

0 comments on commit 9a7aa12

Please sign in to comment.