Skip to content

Commit 0559f63

Browse files
raven-augregkh
authored andcommitted
kernfs: fix missing kernfs_iattr_rwsem locking
When the kernfs_iattr_rwsem was introduced a case was missed. The update of the kernfs directory node child count was also protected by the kernfs_rwsem and needs to be included in the change so that the child count (and so the inode n_link attribute) does not change while holding the rwsem for read. Fixes: 9caf696 ("kernfs: Introduce separate rwsem to protect inode attributes.") Cc: stable <[email protected]> Signed-off-by: Ian Kent <[email protected]> Reviewed-By: Imran Khan <[email protected]> Acked-by: Miklos Szeredi <[email protected]> Cc: Anders Roxell <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Minchan Kim <[email protected]> Cc: Eric Sandeen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent bbaee49 commit 0559f63

File tree

1 file changed

+4
-0
lines changed

1 file changed

+4
-0
lines changed

fs/kernfs/dir.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,11 @@ static int kernfs_link_sibling(struct kernfs_node *kn)
383383
rb_insert_color(&kn->rb, &kn->parent->dir.children);
384384

385385
/* successfully added, account subdir number */
386+
down_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
386387
if (kernfs_type(kn) == KERNFS_DIR)
387388
kn->parent->dir.subdirs++;
388389
kernfs_inc_rev(kn->parent);
390+
up_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
389391

390392
return 0;
391393
}
@@ -408,9 +410,11 @@ static bool kernfs_unlink_sibling(struct kernfs_node *kn)
408410
if (RB_EMPTY_NODE(&kn->rb))
409411
return false;
410412

413+
down_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
411414
if (kernfs_type(kn) == KERNFS_DIR)
412415
kn->parent->dir.subdirs--;
413416
kernfs_inc_rev(kn->parent);
417+
up_write(&kernfs_root(kn)->kernfs_iattr_rwsem);
414418

415419
rb_erase(&kn->rb, &kn->parent->dir.children);
416420
RB_CLEAR_NODE(&kn->rb);

0 commit comments

Comments
 (0)