diff options
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r-- | fs/sysfs/dir.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 53bc7fc31af3..c18342641cec 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -370,17 +370,17 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, | |||
370 | memset(acxt, 0, sizeof(*acxt)); | 370 | memset(acxt, 0, sizeof(*acxt)); |
371 | acxt->parent_sd = parent_sd; | 371 | acxt->parent_sd = parent_sd; |
372 | 372 | ||
373 | /* Lookup parent inode. inode initialization and I_NEW | 373 | /* Lookup parent inode. inode initialization is protected by |
374 | * clearing are protected by sysfs_mutex. By grabbing it and | 374 | * sysfs_mutex, so inode existence can be determined by |
375 | * looking up with _nowait variant, inode state can be | 375 | * looking up inode while holding sysfs_mutex. |
376 | * determined reliably. | ||
377 | */ | 376 | */ |
378 | mutex_lock(&sysfs_mutex); | 377 | mutex_lock(&sysfs_mutex); |
379 | 378 | ||
380 | inode = ilookup5_nowait(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test, | 379 | inode = ilookup5(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test, |
381 | parent_sd); | 380 | parent_sd); |
381 | if (inode) { | ||
382 | WARN_ON(inode->i_state & I_NEW); | ||
382 | 383 | ||
383 | if (inode && !(inode->i_state & I_NEW)) { | ||
384 | /* parent inode available */ | 384 | /* parent inode available */ |
385 | acxt->parent_inode = inode; | 385 | acxt->parent_inode = inode; |
386 | 386 | ||
@@ -393,8 +393,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, | |||
393 | mutex_lock(&inode->i_mutex); | 393 | mutex_lock(&inode->i_mutex); |
394 | mutex_lock(&sysfs_mutex); | 394 | mutex_lock(&sysfs_mutex); |
395 | } | 395 | } |
396 | } else | 396 | } |
397 | iput(inode); | ||
398 | } | 397 | } |
399 | 398 | ||
400 | /** | 399 | /** |