summaryrefslogtreecommitdiffstats
path: root/fs/configfs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-04-20 19:50:05 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-05-09 11:41:13 -0400
commita01b3007ffb9be0180e744f0d15b130b0a76a29f (patch)
tree5ccfce3fe8e64828e99303133278c9d075817503 /fs/configfs
parent884be175351e73c515303118150f195dd611787c (diff)
configfs_readdir(): make safe under shared lock
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/configfs')
-rw-r--r--fs/configfs/dir.c20
1 files changed, 7 insertions, 13 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 48929c408e04..56fb26127fef 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -1633,11 +1633,9 @@ static int configfs_readdir(struct file *file, struct dir_context *ctx)
1633 1633
1634 if (!dir_emit_dots(file, ctx)) 1634 if (!dir_emit_dots(file, ctx))
1635 return 0; 1635 return 0;
1636 if (ctx->pos == 2) { 1636 spin_lock(&configfs_dirent_lock);
1637 spin_lock(&configfs_dirent_lock); 1637 if (ctx->pos == 2)
1638 list_move(q, &parent_sd->s_children); 1638 list_move(q, &parent_sd->s_children);
1639 spin_unlock(&configfs_dirent_lock);
1640 }
1641 for (p = q->next; p != &parent_sd->s_children; p = p->next) { 1639 for (p = q->next; p != &parent_sd->s_children; p = p->next) {
1642 struct configfs_dirent *next; 1640 struct configfs_dirent *next;
1643 const char *name; 1641 const char *name;
@@ -1648,9 +1646,6 @@ static int configfs_readdir(struct file *file, struct dir_context *ctx)
1648 if (!next->s_element) 1646 if (!next->s_element)
1649 continue; 1647 continue;
1650 1648
1651 name = configfs_get_name(next);
1652 len = strlen(name);
1653
1654 /* 1649 /*
1655 * We'll have a dentry and an inode for 1650 * We'll have a dentry and an inode for
1656 * PINNED items and for open attribute 1651 * PINNED items and for open attribute
@@ -1664,7 +1659,6 @@ static int configfs_readdir(struct file *file, struct dir_context *ctx)
1664 * they close it. Beyond that, we don't 1659 * they close it. Beyond that, we don't
1665 * care. 1660 * care.
1666 */ 1661 */
1667 spin_lock(&configfs_dirent_lock);
1668 dentry = next->s_dentry; 1662 dentry = next->s_dentry;
1669 if (dentry) 1663 if (dentry)
1670 inode = d_inode(dentry); 1664 inode = d_inode(dentry);
@@ -1674,15 +1668,18 @@ static int configfs_readdir(struct file *file, struct dir_context *ctx)
1674 if (!inode) 1668 if (!inode)
1675 ino = iunique(sb, 2); 1669 ino = iunique(sb, 2);
1676 1670
1671 name = configfs_get_name(next);
1672 len = strlen(name);
1673
1677 if (!dir_emit(ctx, name, len, ino, dt_type(next))) 1674 if (!dir_emit(ctx, name, len, ino, dt_type(next)))
1678 return 0; 1675 return 0;
1679 1676
1680 spin_lock(&configfs_dirent_lock); 1677 spin_lock(&configfs_dirent_lock);
1681 list_move(q, p); 1678 list_move(q, p);
1682 spin_unlock(&configfs_dirent_lock);
1683 p = q; 1679 p = q;
1684 ctx->pos++; 1680 ctx->pos++;
1685 } 1681 }
1682 spin_unlock(&configfs_dirent_lock);
1686 return 0; 1683 return 0;
1687} 1684}
1688 1685
@@ -1690,7 +1687,6 @@ static loff_t configfs_dir_lseek(struct file *file, loff_t offset, int whence)
1690{ 1687{
1691 struct dentry * dentry = file->f_path.dentry; 1688 struct dentry * dentry = file->f_path.dentry;
1692 1689
1693 inode_lock(d_inode(dentry));
1694 switch (whence) { 1690 switch (whence) {
1695 case 1: 1691 case 1:
1696 offset += file->f_pos; 1692 offset += file->f_pos;
@@ -1698,7 +1694,6 @@ static loff_t configfs_dir_lseek(struct file *file, loff_t offset, int whence)
1698 if (offset >= 0) 1694 if (offset >= 0)
1699 break; 1695 break;
1700 default: 1696 default:
1701 inode_unlock(d_inode(dentry));
1702 return -EINVAL; 1697 return -EINVAL;
1703 } 1698 }
1704 if (offset != file->f_pos) { 1699 if (offset != file->f_pos) {
@@ -1724,7 +1719,6 @@ static loff_t configfs_dir_lseek(struct file *file, loff_t offset, int whence)
1724 spin_unlock(&configfs_dirent_lock); 1719 spin_unlock(&configfs_dirent_lock);
1725 } 1720 }
1726 } 1721 }
1727 inode_unlock(d_inode(dentry));
1728 return offset; 1722 return offset;
1729} 1723}
1730 1724
@@ -1733,7 +1727,7 @@ const struct file_operations configfs_dir_operations = {
1733 .release = configfs_dir_close, 1727 .release = configfs_dir_close,
1734 .llseek = configfs_dir_lseek, 1728 .llseek = configfs_dir_lseek,
1735 .read = generic_read_dir, 1729 .read = generic_read_dir,
1736 .iterate = configfs_readdir, 1730 .iterate_shared = configfs_readdir,
1737}; 1731};
1738 1732
1739/** 1733/**