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.

Merge tag 'configfs-5.15' of git://git.infradead.org/users/hch/configfs

Pull configfs updates from Christoph Hellwig:

- fix a race in configfs_lookup (Sishuai Gong)

- minor cleanups (me)

* tag 'configfs-5.15' of git://git.infradead.org/users/hch/configfs:
configfs: fix a race in configfs_lookup()
configfs: fold configfs_attach_attr into configfs_lookup
configfs: simplify the configfs_dirent_is_ready
configfs: return -ENAMETOOLONG earlier in configfs_lookup

+31 -56
+31 -56
fs/configfs/dir.c
··· 45 45 /* 46 46 * Set sd->s_dentry to null only when this dentry is the one 47 47 * that is going to be killed. Otherwise configfs_d_iput may 48 - * run just after configfs_attach_attr and set sd->s_dentry to 48 + * run just after configfs_lookup and set sd->s_dentry to 49 49 * NULL even it's still in use. 50 50 */ 51 51 if (sd->s_dentry == dentry) ··· 417 417 dput(dentry); 418 418 } 419 419 420 - 421 - /* attaches attribute's configfs_dirent to the dentry corresponding to the 422 - * attribute file 423 - */ 424 - static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * dentry) 425 - { 426 - struct configfs_attribute * attr = sd->s_element; 427 - struct inode *inode; 428 - 429 - spin_lock(&configfs_dirent_lock); 430 - dentry->d_fsdata = configfs_get(sd); 431 - sd->s_dentry = dentry; 432 - spin_unlock(&configfs_dirent_lock); 433 - 434 - inode = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG); 435 - if (IS_ERR(inode)) { 436 - configfs_put(sd); 437 - return PTR_ERR(inode); 438 - } 439 - if (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) { 440 - inode->i_size = 0; 441 - inode->i_fop = &configfs_bin_file_operations; 442 - } else { 443 - inode->i_size = PAGE_SIZE; 444 - inode->i_fop = &configfs_file_operations; 445 - } 446 - d_add(dentry, inode); 447 - return 0; 448 - } 449 - 450 420 static struct dentry * configfs_lookup(struct inode *dir, 451 421 struct dentry *dentry, 452 422 unsigned int flags) 453 423 { 454 424 struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata; 455 425 struct configfs_dirent * sd; 456 - int found = 0; 457 - int err; 426 + struct inode *inode = NULL; 427 + 428 + if (dentry->d_name.len > NAME_MAX) 429 + return ERR_PTR(-ENAMETOOLONG); 458 430 459 431 /* 460 432 * Fake invisibility if dir belongs to a group/default groups hierarchy ··· 436 464 * not complete their initialization, since the dentries of the 437 465 * attributes won't be instantiated. 438 466 */ 439 - err = -ENOENT; 440 467 if (!configfs_dirent_is_ready(parent_sd)) 441 - goto out; 468 + return ERR_PTR(-ENOENT); 442 469 470 + spin_lock(&configfs_dirent_lock); 443 471 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { 444 - if (sd->s_type & CONFIGFS_NOT_PINNED) { 445 - const unsigned char * name = configfs_get_name(sd); 472 + if ((sd->s_type & CONFIGFS_NOT_PINNED) && 473 + !strcmp(configfs_get_name(sd), dentry->d_name.name)) { 474 + struct configfs_attribute *attr = sd->s_element; 475 + umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG; 446 476 447 - if (strcmp(name, dentry->d_name.name)) 448 - continue; 477 + dentry->d_fsdata = configfs_get(sd); 478 + sd->s_dentry = dentry; 479 + spin_unlock(&configfs_dirent_lock); 449 480 450 - found = 1; 451 - err = configfs_attach_attr(sd, dentry); 452 - break; 481 + inode = configfs_create(dentry, mode); 482 + if (IS_ERR(inode)) { 483 + configfs_put(sd); 484 + return ERR_CAST(inode); 485 + } 486 + if (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) { 487 + inode->i_size = 0; 488 + inode->i_fop = &configfs_bin_file_operations; 489 + } else { 490 + inode->i_size = PAGE_SIZE; 491 + inode->i_fop = &configfs_file_operations; 492 + } 493 + goto done; 453 494 } 454 495 } 455 - 456 - if (!found) { 457 - /* 458 - * If it doesn't exist and it isn't a NOT_PINNED item, 459 - * it must be negative. 460 - */ 461 - if (dentry->d_name.len > NAME_MAX) 462 - return ERR_PTR(-ENAMETOOLONG); 463 - d_add(dentry, NULL); 464 - return NULL; 465 - } 466 - 467 - out: 468 - return ERR_PTR(err); 496 + spin_unlock(&configfs_dirent_lock); 497 + done: 498 + d_add(dentry, inode); 499 + return NULL; 469 500 } 470 501 471 502 /*