Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hypfs: don't pin dentries twice

hypfs dentries end up with refcount 2 when they are not busy.
Refcount 1 is enough to keep them pinned, and going that way
allows to simplify things nicely:
* don't need to drop an extra reference before the
call of kill_litter_super() in ->kill_sb(); all we need
there is to reset the cleanup list - everything on it will
be taken out automatically.
* we can make use of simple_recursive_removal() on
tree rebuilds; just make sure that only children of root
end up in the cleanup list and hypfs_delete_tree() becomes
much simpler

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 781716cd 57db9d42

+10 -31
+10 -31
arch/s390/hypfs/inode.c
··· 61 61 62 62 static void hypfs_add_dentry(struct dentry *dentry) 63 63 { 64 - dentry->d_fsdata = hypfs_last_dentry; 65 - hypfs_last_dentry = dentry; 66 - } 67 - 68 - static void hypfs_remove(struct dentry *dentry) 69 - { 70 - struct dentry *parent; 71 - 72 - parent = dentry->d_parent; 73 - inode_lock(d_inode(parent)); 74 - if (simple_positive(dentry)) { 75 - if (d_is_dir(dentry)) 76 - simple_rmdir(d_inode(parent), dentry); 77 - else 78 - simple_unlink(d_inode(parent), dentry); 64 + if (IS_ROOT(dentry->d_parent)) { 65 + dentry->d_fsdata = hypfs_last_dentry; 66 + hypfs_last_dentry = dentry; 79 67 } 80 - d_drop(dentry); 81 - dput(dentry); 82 - inode_unlock(d_inode(parent)); 83 68 } 84 69 85 - static void hypfs_delete_tree(struct dentry *root) 70 + static void hypfs_delete_tree(void) 86 71 { 87 72 while (hypfs_last_dentry) { 88 - struct dentry *next_dentry; 89 - next_dentry = hypfs_last_dentry->d_fsdata; 90 - hypfs_remove(hypfs_last_dentry); 73 + struct dentry *next_dentry = hypfs_last_dentry->d_fsdata; 74 + simple_recursive_removal(hypfs_last_dentry, NULL); 91 75 hypfs_last_dentry = next_dentry; 92 76 } 93 77 } ··· 168 184 rc = -EBUSY; 169 185 goto out; 170 186 } 171 - hypfs_delete_tree(sb->s_root); 187 + hypfs_delete_tree(); 172 188 if (machine_is_vm()) 173 189 rc = hypfs_vm_create_files(sb->s_root); 174 190 else 175 191 rc = hypfs_diag_create_files(sb->s_root); 176 192 if (rc) { 177 193 pr_err("Updating the hypfs tree failed\n"); 178 - hypfs_delete_tree(sb->s_root); 194 + hypfs_delete_tree(); 179 195 goto out; 180 196 } 181 197 hypfs_update_update(sb); ··· 310 326 { 311 327 struct hypfs_sb_info *sb_info = sb->s_fs_info; 312 328 313 - if (sb->s_root) 314 - hypfs_delete_tree(sb->s_root); 315 - if (sb_info && sb_info->update_file) 316 - hypfs_remove(sb_info->update_file); 317 - kfree(sb->s_fs_info); 318 - sb->s_fs_info = NULL; 329 + hypfs_last_dentry = NULL; 319 330 kill_litter_super(sb); 331 + kfree(sb_info); 320 332 } 321 333 322 334 static struct dentry *hypfs_create_file(struct dentry *parent, const char *name, ··· 347 367 BUG(); 348 368 inode->i_private = data; 349 369 d_instantiate(dentry, inode); 350 - dget(dentry); 351 370 fail: 352 371 inode_unlock(d_inode(parent)); 353 372 return dentry;