|
@@ -254,10 +254,21 @@ static void inode_free_security(struct inode *inode)
|
|
|
struct inode_security_struct *isec = inode->i_security;
|
|
|
struct superblock_security_struct *sbsec = inode->i_sb->s_security;
|
|
|
|
|
|
- spin_lock(&sbsec->isec_lock);
|
|
|
- if (!list_empty(&isec->list))
|
|
|
+ /*
|
|
|
+ * As not all inode security structures are in a list, we check for
|
|
|
+ * empty list outside of the lock to make sure that we won't waste
|
|
|
+ * time taking a lock doing nothing.
|
|
|
+ *
|
|
|
+ * The list_del_init() function can be safely called more than once.
|
|
|
+ * It should not be possible for this function to be called with
|
|
|
+ * concurrent list_add(), but for better safety against future changes
|
|
|
+ * in the code, we use list_empty_careful() here.
|
|
|
+ */
|
|
|
+ if (!list_empty_careful(&isec->list)) {
|
|
|
+ spin_lock(&sbsec->isec_lock);
|
|
|
list_del_init(&isec->list);
|
|
|
- spin_unlock(&sbsec->isec_lock);
|
|
|
+ spin_unlock(&sbsec->isec_lock);
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* The inode may still be referenced in a path walk and
|