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-for-5.3' of git://git.infradead.org/users/hch/configfs

Pull configfs fixes from Christoph Hellwig:
"Late configfs fixes from Al that fix pretty nasty removal vs attribute
access races"

* tag 'configfs-for-5.3' of git://git.infradead.org/users/hch/configfs:
configfs: provide exclusion between IO and removals
configfs: new object reprsenting tree fragments
configfs_register_group() shouldn't be (and isn't) called in rmdirable parts
configfs: stash the data we need into configfs_buffer at open time

+255 -173
+13 -2
fs/configfs/configfs_internal.h
··· 20 20 #include <linux/list.h> 21 21 #include <linux/spinlock.h> 22 22 23 + struct configfs_fragment { 24 + atomic_t frag_count; 25 + struct rw_semaphore frag_sem; 26 + bool frag_dead; 27 + }; 28 + 29 + void put_fragment(struct configfs_fragment *); 30 + struct configfs_fragment *get_fragment(struct configfs_fragment *); 31 + 23 32 struct configfs_dirent { 24 33 atomic_t s_count; 25 34 int s_dependent_count; ··· 43 34 #ifdef CONFIG_LOCKDEP 44 35 int s_depth; 45 36 #endif 37 + struct configfs_fragment *s_frag; 46 38 }; 47 39 48 40 #define CONFIGFS_ROOT 0x0001 ··· 71 61 extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); 72 62 extern int configfs_create_bin_file(struct config_item *, 73 63 const struct configfs_bin_attribute *); 74 - extern int configfs_make_dirent(struct configfs_dirent *, 75 - struct dentry *, void *, umode_t, int); 64 + extern int configfs_make_dirent(struct configfs_dirent *, struct dentry *, 65 + void *, umode_t, int, struct configfs_fragment *); 76 66 extern int configfs_dirent_is_ready(struct configfs_dirent *); 77 67 78 68 extern void configfs_hash_and_remove(struct dentry * dir, const char * name); ··· 147 137 { 148 138 if (!(sd->s_type & CONFIGFS_ROOT)) { 149 139 kfree(sd->s_iattr); 140 + put_fragment(sd->s_frag); 150 141 kmem_cache_free(configfs_dir_cachep, sd); 151 142 } 152 143 }
+104 -33
fs/configfs/dir.c
··· 151 151 152 152 #endif /* CONFIG_LOCKDEP */ 153 153 154 + static struct configfs_fragment *new_fragment(void) 155 + { 156 + struct configfs_fragment *p; 157 + 158 + p = kmalloc(sizeof(struct configfs_fragment), GFP_KERNEL); 159 + if (p) { 160 + atomic_set(&p->frag_count, 1); 161 + init_rwsem(&p->frag_sem); 162 + p->frag_dead = false; 163 + } 164 + return p; 165 + } 166 + 167 + void put_fragment(struct configfs_fragment *frag) 168 + { 169 + if (frag && atomic_dec_and_test(&frag->frag_count)) 170 + kfree(frag); 171 + } 172 + 173 + struct configfs_fragment *get_fragment(struct configfs_fragment *frag) 174 + { 175 + if (likely(frag)) 176 + atomic_inc(&frag->frag_count); 177 + return frag; 178 + } 179 + 154 180 /* 155 181 * Allocates a new configfs_dirent and links it to the parent configfs_dirent 156 182 */ 157 183 static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *parent_sd, 158 - void *element, int type) 184 + void *element, int type, 185 + struct configfs_fragment *frag) 159 186 { 160 187 struct configfs_dirent * sd; 161 188 ··· 202 175 kmem_cache_free(configfs_dir_cachep, sd); 203 176 return ERR_PTR(-ENOENT); 204 177 } 178 + sd->s_frag = get_fragment(frag); 205 179 list_add(&sd->s_sibling, &parent_sd->s_children); 206 180 spin_unlock(&configfs_dirent_lock); 207 181 ··· 237 209 238 210 int configfs_make_dirent(struct configfs_dirent * parent_sd, 239 211 struct dentry * dentry, void * element, 240 - umode_t mode, int type) 212 + umode_t mode, int type, struct configfs_fragment *frag) 241 213 { 242 214 struct configfs_dirent * sd; 243 215 244 - sd = configfs_new_dirent(parent_sd, element, type); 216 + sd = configfs_new_dirent(parent_sd, element, type, frag); 245 217 if (IS_ERR(sd)) 246 218 return PTR_ERR(sd); 247 219 ··· 288 260 * until it is validated by configfs_dir_set_ready() 289 261 */ 290 262 291 - static int configfs_create_dir(struct config_item *item, struct dentry *dentry) 263 + static int configfs_create_dir(struct config_item *item, struct dentry *dentry, 264 + struct configfs_fragment *frag) 292 265 { 293 266 int error; 294 267 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; ··· 302 273 return error; 303 274 304 275 error = configfs_make_dirent(p->d_fsdata, dentry, item, mode, 305 - CONFIGFS_DIR | CONFIGFS_USET_CREATING); 276 + CONFIGFS_DIR | CONFIGFS_USET_CREATING, 277 + frag); 306 278 if (unlikely(error)) 307 279 return error; 308 280 ··· 368 338 { 369 339 int err = 0; 370 340 umode_t mode = S_IFLNK | S_IRWXUGO; 341 + struct configfs_dirent *p = parent->d_fsdata; 371 342 372 - err = configfs_make_dirent(parent->d_fsdata, dentry, sl, mode, 373 - CONFIGFS_ITEM_LINK); 343 + err = configfs_make_dirent(p, dentry, sl, mode, 344 + CONFIGFS_ITEM_LINK, p->s_frag); 374 345 if (!err) { 375 346 err = configfs_create(dentry, mode, init_symlink); 376 347 if (err) { ··· 630 599 631 600 static int configfs_attach_group(struct config_item *parent_item, 632 601 struct config_item *item, 633 - struct dentry *dentry); 602 + struct dentry *dentry, 603 + struct configfs_fragment *frag); 634 604 static void configfs_detach_group(struct config_item *item); 635 605 636 606 static void detach_groups(struct config_group *group) ··· 679 647 * try using vfs_mkdir. Just a thought. 680 648 */ 681 649 static int create_default_group(struct config_group *parent_group, 682 - struct config_group *group) 650 + struct config_group *group, 651 + struct configfs_fragment *frag) 683 652 { 684 653 int ret; 685 654 struct configfs_dirent *sd; ··· 696 663 d_add(child, NULL); 697 664 698 665 ret = configfs_attach_group(&parent_group->cg_item, 699 - &group->cg_item, child); 666 + &group->cg_item, child, frag); 700 667 if (!ret) { 701 668 sd = child->d_fsdata; 702 669 sd->s_type |= CONFIGFS_USET_DEFAULT; ··· 710 677 return ret; 711 678 } 712 679 713 - static int populate_groups(struct config_group *group) 680 + static int populate_groups(struct config_group *group, 681 + struct configfs_fragment *frag) 714 682 { 715 683 struct config_group *new_group; 716 684 int ret = 0; 717 685 718 686 list_for_each_entry(new_group, &group->default_groups, group_entry) { 719 - ret = create_default_group(group, new_group); 687 + ret = create_default_group(group, new_group, frag); 720 688 if (ret) { 721 689 detach_groups(group); 722 690 break; ··· 831 797 */ 832 798 static int configfs_attach_item(struct config_item *parent_item, 833 799 struct config_item *item, 834 - struct dentry *dentry) 800 + struct dentry *dentry, 801 + struct configfs_fragment *frag) 835 802 { 836 803 int ret; 837 804 838 - ret = configfs_create_dir(item, dentry); 805 + ret = configfs_create_dir(item, dentry, frag); 839 806 if (!ret) { 840 807 ret = populate_attrs(item); 841 808 if (ret) { ··· 866 831 867 832 static int configfs_attach_group(struct config_item *parent_item, 868 833 struct config_item *item, 869 - struct dentry *dentry) 834 + struct dentry *dentry, 835 + struct configfs_fragment *frag) 870 836 { 871 837 int ret; 872 838 struct configfs_dirent *sd; 873 839 874 - ret = configfs_attach_item(parent_item, item, dentry); 840 + ret = configfs_attach_item(parent_item, item, dentry, frag); 875 841 if (!ret) { 876 842 sd = dentry->d_fsdata; 877 843 sd->s_type |= CONFIGFS_USET_DIR; ··· 888 852 */ 889 853 inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD); 890 854 configfs_adjust_dir_dirent_depth_before_populate(sd); 891 - ret = populate_groups(to_config_group(item)); 855 + ret = populate_groups(to_config_group(item), frag); 892 856 if (ret) { 893 857 configfs_detach_item(item); 894 858 d_inode(dentry)->i_flags |= S_DEAD; ··· 1283 1247 struct configfs_dirent *sd; 1284 1248 const struct config_item_type *type; 1285 1249 struct module *subsys_owner = NULL, *new_item_owner = NULL; 1250 + struct configfs_fragment *frag; 1286 1251 char *name; 1287 1252 1288 1253 sd = dentry->d_parent->d_fsdata; ··· 1299 1262 1300 1263 if (!(sd->s_type & CONFIGFS_USET_DIR)) { 1301 1264 ret = -EPERM; 1265 + goto out; 1266 + } 1267 + 1268 + frag = new_fragment(); 1269 + if (!frag) { 1270 + ret = -ENOMEM; 1302 1271 goto out; 1303 1272 } 1304 1273 ··· 1410 1367 spin_unlock(&configfs_dirent_lock); 1411 1368 1412 1369 if (group) 1413 - ret = configfs_attach_group(parent_item, item, dentry); 1370 + ret = configfs_attach_group(parent_item, item, dentry, frag); 1414 1371 else 1415 - ret = configfs_attach_item(parent_item, item, dentry); 1372 + ret = configfs_attach_item(parent_item, item, dentry, frag); 1416 1373 1417 1374 spin_lock(&configfs_dirent_lock); 1418 1375 sd->s_type &= ~CONFIGFS_USET_IN_MKDIR; ··· 1449 1406 * reference. 1450 1407 */ 1451 1408 config_item_put(parent_item); 1409 + put_fragment(frag); 1452 1410 1453 1411 out: 1454 1412 return ret; ··· 1461 1417 struct config_item *item; 1462 1418 struct configfs_subsystem *subsys; 1463 1419 struct configfs_dirent *sd; 1420 + struct configfs_fragment *frag; 1464 1421 struct module *subsys_owner = NULL, *dead_item_owner = NULL; 1465 1422 int ret; 1466 1423 ··· 1518 1473 dput(wait); 1519 1474 } 1520 1475 } while (ret == -EAGAIN); 1476 + 1477 + frag = sd->s_frag; 1478 + if (down_write_killable(&frag->frag_sem)) { 1479 + spin_lock(&configfs_dirent_lock); 1480 + configfs_detach_rollback(dentry); 1481 + spin_unlock(&configfs_dirent_lock); 1482 + return -EINTR; 1483 + } 1484 + frag->frag_dead = true; 1485 + up_write(&frag->frag_sem); 1521 1486 1522 1487 /* Get a working ref for the duration of this function */ 1523 1488 item = configfs_get_config_item(dentry); ··· 1629 1574 */ 1630 1575 err = -ENOENT; 1631 1576 if (configfs_dirent_is_ready(parent_sd)) { 1632 - file->private_data = configfs_new_dirent(parent_sd, NULL, 0); 1577 + file->private_data = configfs_new_dirent(parent_sd, NULL, 0, NULL); 1633 1578 if (IS_ERR(file->private_data)) 1634 1579 err = PTR_ERR(file->private_data); 1635 1580 else ··· 1787 1732 { 1788 1733 struct configfs_subsystem *subsys = parent_group->cg_subsys; 1789 1734 struct dentry *parent; 1735 + struct configfs_fragment *frag; 1790 1736 int ret; 1737 + 1738 + frag = new_fragment(); 1739 + if (!frag) 1740 + return -ENOMEM; 1791 1741 1792 1742 mutex_lock(&subsys->su_mutex); 1793 1743 link_group(parent_group, group); ··· 1801 1741 parent = parent_group->cg_item.ci_dentry; 1802 1742 1803 1743 inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); 1804 - ret = create_default_group(parent_group, group); 1744 + ret = create_default_group(parent_group, group, frag); 1805 1745 if (ret) 1806 1746 goto err_out; 1807 1747 ··· 1809 1749 configfs_dir_set_ready(group->cg_item.ci_dentry->d_fsdata); 1810 1750 spin_unlock(&configfs_dirent_lock); 1811 1751 inode_unlock(d_inode(parent)); 1752 + put_fragment(frag); 1812 1753 return 0; 1813 1754 err_out: 1814 1755 inode_unlock(d_inode(parent)); 1815 1756 mutex_lock(&subsys->su_mutex); 1816 1757 unlink_group(group); 1817 1758 mutex_unlock(&subsys->su_mutex); 1759 + put_fragment(frag); 1818 1760 return ret; 1819 1761 } 1820 1762 EXPORT_SYMBOL(configfs_register_group); ··· 1832 1770 struct configfs_subsystem *subsys = group->cg_subsys; 1833 1771 struct dentry *dentry = group->cg_item.ci_dentry; 1834 1772 struct dentry *parent = group->cg_item.ci_parent->ci_dentry; 1773 + struct configfs_dirent *sd = dentry->d_fsdata; 1774 + struct configfs_fragment *frag = sd->s_frag; 1835 1775 1836 - mutex_lock(&subsys->su_mutex); 1837 - if (!group->cg_item.ci_parent->ci_group) { 1838 - /* 1839 - * The parent has already been unlinked and detached 1840 - * due to a rmdir. 1841 - */ 1842 - goto unlink_group; 1843 - } 1844 - mutex_unlock(&subsys->su_mutex); 1776 + down_write(&frag->frag_sem); 1777 + frag->frag_dead = true; 1778 + up_write(&frag->frag_sem); 1845 1779 1846 1780 inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); 1847 1781 spin_lock(&configfs_dirent_lock); ··· 1854 1796 dput(dentry); 1855 1797 1856 1798 mutex_lock(&subsys->su_mutex); 1857 - unlink_group: 1858 1799 unlink_group(group); 1859 1800 mutex_unlock(&subsys->su_mutex); 1860 1801 } ··· 1910 1853 struct dentry *dentry; 1911 1854 struct dentry *root; 1912 1855 struct configfs_dirent *sd; 1856 + struct configfs_fragment *frag; 1857 + 1858 + frag = new_fragment(); 1859 + if (!frag) 1860 + return -ENOMEM; 1913 1861 1914 1862 root = configfs_pin_fs(); 1915 - if (IS_ERR(root)) 1863 + if (IS_ERR(root)) { 1864 + put_fragment(frag); 1916 1865 return PTR_ERR(root); 1866 + } 1917 1867 1918 1868 if (!group->cg_item.ci_name) 1919 1869 group->cg_item.ci_name = group->cg_item.ci_namebuf; ··· 1936 1872 d_add(dentry, NULL); 1937 1873 1938 1874 err = configfs_attach_group(sd->s_element, &group->cg_item, 1939 - dentry); 1875 + dentry, frag); 1940 1876 if (err) { 1941 1877 BUG_ON(d_inode(dentry)); 1942 1878 d_drop(dentry); ··· 1954 1890 unlink_group(group); 1955 1891 configfs_release_fs(); 1956 1892 } 1893 + put_fragment(frag); 1957 1894 1958 1895 return err; 1959 1896 } ··· 1964 1899 struct config_group *group = &subsys->su_group; 1965 1900 struct dentry *dentry = group->cg_item.ci_dentry; 1966 1901 struct dentry *root = dentry->d_sb->s_root; 1902 + struct configfs_dirent *sd = dentry->d_fsdata; 1903 + struct configfs_fragment *frag = sd->s_frag; 1967 1904 1968 1905 if (dentry->d_parent != root) { 1969 1906 pr_err("Tried to unregister non-subsystem!\n"); 1970 1907 return; 1971 1908 } 1909 + 1910 + down_write(&frag->frag_sem); 1911 + frag->frag_dead = true; 1912 + up_write(&frag->frag_sem); 1972 1913 1973 1914 inode_lock_nested(d_inode(root), 1974 1915 I_MUTEX_PARENT);
+138 -138
fs/configfs/file.c
··· 39 39 bool write_in_progress; 40 40 char *bin_buffer; 41 41 int bin_buffer_size; 42 + int cb_max_size; 43 + struct config_item *item; 44 + struct module *owner; 45 + union { 46 + struct configfs_attribute *attr; 47 + struct configfs_bin_attribute *bin_attr; 48 + }; 42 49 }; 43 50 44 - 45 - /** 46 - * fill_read_buffer - allocate and fill buffer from item. 47 - * @dentry: dentry pointer. 48 - * @buffer: data buffer for file. 49 - * 50 - * Allocate @buffer->page, if it hasn't been already, then call the 51 - * config_item's show() method to fill the buffer with this attribute's 52 - * data. 53 - * This is called only once, on the file's first read. 54 - */ 55 - static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buffer) 51 + static inline struct configfs_fragment *to_frag(struct file *file) 56 52 { 57 - struct configfs_attribute * attr = to_attr(dentry); 58 - struct config_item * item = to_item(dentry->d_parent); 59 - int ret = 0; 60 - ssize_t count; 53 + struct configfs_dirent *sd = file->f_path.dentry->d_fsdata; 54 + 55 + return sd->s_frag; 56 + } 57 + 58 + static int fill_read_buffer(struct file *file, struct configfs_buffer *buffer) 59 + { 60 + struct configfs_fragment *frag = to_frag(file); 61 + ssize_t count = -ENOENT; 61 62 62 63 if (!buffer->page) 63 64 buffer->page = (char *) get_zeroed_page(GFP_KERNEL); 64 65 if (!buffer->page) 65 66 return -ENOMEM; 66 67 67 - count = attr->show(item, buffer->page); 68 + down_read(&frag->frag_sem); 69 + if (!frag->frag_dead) 70 + count = buffer->attr->show(buffer->item, buffer->page); 71 + up_read(&frag->frag_sem); 68 72 69 - BUG_ON(count > (ssize_t)SIMPLE_ATTR_SIZE); 70 - if (count >= 0) { 71 - buffer->needs_read_fill = 0; 72 - buffer->count = count; 73 - } else 74 - ret = count; 75 - return ret; 73 + if (count < 0) 74 + return count; 75 + if (WARN_ON_ONCE(count > (ssize_t)SIMPLE_ATTR_SIZE)) 76 + return -EIO; 77 + buffer->needs_read_fill = 0; 78 + buffer->count = count; 79 + return 0; 76 80 } 77 81 78 82 /** ··· 101 97 static ssize_t 102 98 configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) 103 99 { 104 - struct configfs_buffer * buffer = file->private_data; 100 + struct configfs_buffer *buffer = file->private_data; 105 101 ssize_t retval = 0; 106 102 107 103 mutex_lock(&buffer->mutex); 108 104 if (buffer->needs_read_fill) { 109 - if ((retval = fill_read_buffer(file->f_path.dentry,buffer))) 105 + retval = fill_read_buffer(file, buffer); 106 + if (retval) 110 107 goto out; 111 108 } 112 109 pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", ··· 143 138 configfs_read_bin_file(struct file *file, char __user *buf, 144 139 size_t count, loff_t *ppos) 145 140 { 141 + struct configfs_fragment *frag = to_frag(file); 146 142 struct configfs_buffer *buffer = file->private_data; 147 - struct dentry *dentry = file->f_path.dentry; 148 - struct config_item *item = to_item(dentry->d_parent); 149 - struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); 150 143 ssize_t retval = 0; 151 144 ssize_t len = min_t(size_t, count, PAGE_SIZE); 152 145 ··· 159 156 160 157 if (buffer->needs_read_fill) { 161 158 /* perform first read with buf == NULL to get extent */ 162 - len = bin_attr->read(item, NULL, 0); 159 + down_read(&frag->frag_sem); 160 + if (!frag->frag_dead) 161 + len = buffer->bin_attr->read(buffer->item, NULL, 0); 162 + else 163 + len = -ENOENT; 164 + up_read(&frag->frag_sem); 163 165 if (len <= 0) { 164 166 retval = len; 165 167 goto out; 166 168 } 167 169 168 170 /* do not exceed the maximum value */ 169 - if (bin_attr->cb_max_size && len > bin_attr->cb_max_size) { 171 + if (buffer->cb_max_size && len > buffer->cb_max_size) { 170 172 retval = -EFBIG; 171 173 goto out; 172 174 } ··· 184 176 buffer->bin_buffer_size = len; 185 177 186 178 /* perform second read to fill buffer */ 187 - len = bin_attr->read(item, buffer->bin_buffer, len); 179 + down_read(&frag->frag_sem); 180 + if (!frag->frag_dead) 181 + len = buffer->bin_attr->read(buffer->item, 182 + buffer->bin_buffer, len); 183 + else 184 + len = -ENOENT; 185 + up_read(&frag->frag_sem); 188 186 if (len < 0) { 189 187 retval = len; 190 188 vfree(buffer->bin_buffer); ··· 240 226 return error ? -EFAULT : count; 241 227 } 242 228 243 - 244 - /** 245 - * flush_write_buffer - push buffer to config_item. 246 - * @dentry: dentry to the attribute 247 - * @buffer: data buffer for file. 248 - * @count: number of bytes 249 - * 250 - * Get the correct pointers for the config_item and the attribute we're 251 - * dealing with, then call the store() method for the attribute, 252 - * passing the buffer that we acquired in fill_write_buffer(). 253 - */ 254 - 255 229 static int 256 - flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size_t count) 230 + flush_write_buffer(struct file *file, struct configfs_buffer *buffer, size_t count) 257 231 { 258 - struct configfs_attribute * attr = to_attr(dentry); 259 - struct config_item * item = to_item(dentry->d_parent); 232 + struct configfs_fragment *frag = to_frag(file); 233 + int res = -ENOENT; 260 234 261 - return attr->store(item, buffer->page, count); 235 + down_read(&frag->frag_sem); 236 + if (!frag->frag_dead) 237 + res = buffer->attr->store(buffer->item, buffer->page, count); 238 + up_read(&frag->frag_sem); 239 + return res; 262 240 } 263 241 264 242 ··· 274 268 static ssize_t 275 269 configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 276 270 { 277 - struct configfs_buffer * buffer = file->private_data; 271 + struct configfs_buffer *buffer = file->private_data; 278 272 ssize_t len; 279 273 280 274 mutex_lock(&buffer->mutex); 281 275 len = fill_write_buffer(buffer, buf, count); 282 276 if (len > 0) 283 - len = flush_write_buffer(file->f_path.dentry, buffer, len); 277 + len = flush_write_buffer(file, buffer, len); 284 278 if (len > 0) 285 279 *ppos += len; 286 280 mutex_unlock(&buffer->mutex); ··· 305 299 size_t count, loff_t *ppos) 306 300 { 307 301 struct configfs_buffer *buffer = file->private_data; 308 - struct dentry *dentry = file->f_path.dentry; 309 - struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); 310 302 void *tbuf = NULL; 311 303 ssize_t len; 312 304 ··· 320 316 /* buffer grows? */ 321 317 if (*ppos + count > buffer->bin_buffer_size) { 322 318 323 - if (bin_attr->cb_max_size && 324 - *ppos + count > bin_attr->cb_max_size) { 319 + if (buffer->cb_max_size && 320 + *ppos + count > buffer->cb_max_size) { 325 321 len = -EFBIG; 326 322 goto out; 327 323 } ··· 353 349 return len; 354 350 } 355 351 356 - static int check_perm(struct inode * inode, struct file * file, int type) 352 + static int __configfs_open_file(struct inode *inode, struct file *file, int type) 357 353 { 358 - struct config_item *item = configfs_get_config_item(file->f_path.dentry->d_parent); 359 - struct configfs_attribute * attr = to_attr(file->f_path.dentry); 360 - struct configfs_bin_attribute *bin_attr = NULL; 361 - struct configfs_buffer * buffer; 362 - struct configfs_item_operations * ops = NULL; 363 - int error = 0; 354 + struct dentry *dentry = file->f_path.dentry; 355 + struct configfs_fragment *frag = to_frag(file); 356 + struct configfs_attribute *attr; 357 + struct configfs_buffer *buffer; 358 + int error; 364 359 365 - if (!item || !attr) 366 - goto Einval; 360 + error = -ENOMEM; 361 + buffer = kzalloc(sizeof(struct configfs_buffer), GFP_KERNEL); 362 + if (!buffer) 363 + goto out; 367 364 368 - if (type & CONFIGFS_ITEM_BIN_ATTR) 369 - bin_attr = to_bin_attr(file->f_path.dentry); 365 + error = -ENOENT; 366 + down_read(&frag->frag_sem); 367 + if (unlikely(frag->frag_dead)) 368 + goto out_free_buffer; 370 369 371 - /* Grab the module reference for this attribute if we have one */ 372 - if (!try_module_get(attr->ca_owner)) { 373 - error = -ENODEV; 374 - goto Done; 370 + error = -EINVAL; 371 + buffer->item = to_item(dentry->d_parent); 372 + if (!buffer->item) 373 + goto out_free_buffer; 374 + 375 + attr = to_attr(dentry); 376 + if (!attr) 377 + goto out_put_item; 378 + 379 + if (type & CONFIGFS_ITEM_BIN_ATTR) { 380 + buffer->bin_attr = to_bin_attr(dentry); 381 + buffer->cb_max_size = buffer->bin_attr->cb_max_size; 382 + } else { 383 + buffer->attr = attr; 375 384 } 376 385 377 - if (item->ci_type) 378 - ops = item->ci_type->ct_item_ops; 379 - else 380 - goto Eaccess; 386 + buffer->owner = attr->ca_owner; 387 + /* Grab the module reference for this attribute if we have one */ 388 + error = -ENODEV; 389 + if (!try_module_get(buffer->owner)) 390 + goto out_put_item; 391 + 392 + error = -EACCES; 393 + if (!buffer->item->ci_type) 394 + goto out_put_module; 395 + 396 + buffer->ops = buffer->item->ci_type->ct_item_ops; 381 397 382 398 /* File needs write support. 383 399 * The inode's perms must say it's ok, ··· 405 381 */ 406 382 if (file->f_mode & FMODE_WRITE) { 407 383 if (!(inode->i_mode & S_IWUGO)) 408 - goto Eaccess; 409 - 384 + goto out_put_module; 410 385 if ((type & CONFIGFS_ITEM_ATTR) && !attr->store) 411 - goto Eaccess; 412 - 413 - if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->write) 414 - goto Eaccess; 386 + goto out_put_module; 387 + if ((type & CONFIGFS_ITEM_BIN_ATTR) && !buffer->bin_attr->write) 388 + goto out_put_module; 415 389 } 416 390 417 391 /* File needs read support. ··· 418 396 */ 419 397 if (file->f_mode & FMODE_READ) { 420 398 if (!(inode->i_mode & S_IRUGO)) 421 - goto Eaccess; 422 - 399 + goto out_put_module; 423 400 if ((type & CONFIGFS_ITEM_ATTR) && !attr->show) 424 - goto Eaccess; 425 - 426 - if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->read) 427 - goto Eaccess; 401 + goto out_put_module; 402 + if ((type & CONFIGFS_ITEM_BIN_ATTR) && !buffer->bin_attr->read) 403 + goto out_put_module; 428 404 } 429 405 430 - /* No error? Great, allocate a buffer for the file, and store it 431 - * it in file->private_data for easy access. 432 - */ 433 - buffer = kzalloc(sizeof(struct configfs_buffer),GFP_KERNEL); 434 - if (!buffer) { 435 - error = -ENOMEM; 436 - goto Enomem; 437 - } 438 406 mutex_init(&buffer->mutex); 439 407 buffer->needs_read_fill = 1; 440 408 buffer->read_in_progress = false; 441 409 buffer->write_in_progress = false; 442 - buffer->ops = ops; 443 410 file->private_data = buffer; 444 - goto Done; 411 + up_read(&frag->frag_sem); 412 + return 0; 445 413 446 - Einval: 447 - error = -EINVAL; 448 - goto Done; 449 - Eaccess: 450 - error = -EACCES; 451 - Enomem: 452 - module_put(attr->ca_owner); 453 - Done: 454 - if (error && item) 455 - config_item_put(item); 414 + out_put_module: 415 + module_put(buffer->owner); 416 + out_put_item: 417 + config_item_put(buffer->item); 418 + out_free_buffer: 419 + up_read(&frag->frag_sem); 420 + kfree(buffer); 421 + out: 456 422 return error; 457 423 } 458 424 459 425 static int configfs_release(struct inode *inode, struct file *filp) 460 426 { 461 - struct config_item * item = to_item(filp->f_path.dentry->d_parent); 462 - struct configfs_attribute * attr = to_attr(filp->f_path.dentry); 463 - struct module * owner = attr->ca_owner; 464 - struct configfs_buffer * buffer = filp->private_data; 427 + struct configfs_buffer *buffer = filp->private_data; 465 428 466 - if (item) 467 - config_item_put(item); 468 - /* After this point, attr should not be accessed. */ 469 - module_put(owner); 470 - 471 - if (buffer) { 472 - if (buffer->page) 473 - free_page((unsigned long)buffer->page); 474 - mutex_destroy(&buffer->mutex); 475 - kfree(buffer); 476 - } 429 + module_put(buffer->owner); 430 + if (buffer->page) 431 + free_page((unsigned long)buffer->page); 432 + mutex_destroy(&buffer->mutex); 433 + kfree(buffer); 477 434 return 0; 478 435 } 479 436 480 437 static int configfs_open_file(struct inode *inode, struct file *filp) 481 438 { 482 - return check_perm(inode, filp, CONFIGFS_ITEM_ATTR); 439 + return __configfs_open_file(inode, filp, CONFIGFS_ITEM_ATTR); 483 440 } 484 441 485 442 static int configfs_open_bin_file(struct inode *inode, struct file *filp) 486 443 { 487 - return check_perm(inode, filp, CONFIGFS_ITEM_BIN_ATTR); 444 + return __configfs_open_file(inode, filp, CONFIGFS_ITEM_BIN_ATTR); 488 445 } 489 446 490 - static int configfs_release_bin_file(struct inode *inode, struct file *filp) 447 + static int configfs_release_bin_file(struct inode *inode, struct file *file) 491 448 { 492 - struct configfs_buffer *buffer = filp->private_data; 493 - struct dentry *dentry = filp->f_path.dentry; 494 - struct config_item *item = to_item(dentry->d_parent); 495 - struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); 496 - ssize_t len = 0; 497 - int ret; 449 + struct configfs_buffer *buffer = file->private_data; 498 450 499 451 buffer->read_in_progress = false; 500 452 501 453 if (buffer->write_in_progress) { 454 + struct configfs_fragment *frag = to_frag(file); 502 455 buffer->write_in_progress = false; 503 456 504 - len = bin_attr->write(item, buffer->bin_buffer, 505 - buffer->bin_buffer_size); 506 - 457 + down_read(&frag->frag_sem); 458 + if (!frag->frag_dead) { 459 + /* result of ->release() is ignored */ 460 + buffer->bin_attr->write(buffer->item, 461 + buffer->bin_buffer, 462 + buffer->bin_buffer_size); 463 + } 464 + up_read(&frag->frag_sem); 507 465 /* vfree on NULL is safe */ 508 466 vfree(buffer->bin_buffer); 509 467 buffer->bin_buffer = NULL; ··· 491 489 buffer->needs_read_fill = 1; 492 490 } 493 491 494 - ret = configfs_release(inode, filp); 495 - if (len < 0) 496 - return len; 497 - return ret; 492 + configfs_release(inode, file); 493 + return 0; 498 494 } 499 495 500 496 ··· 527 527 528 528 inode_lock_nested(d_inode(dir), I_MUTEX_NORMAL); 529 529 error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode, 530 - CONFIGFS_ITEM_ATTR); 530 + CONFIGFS_ITEM_ATTR, parent_sd->s_frag); 531 531 inode_unlock(d_inode(dir)); 532 532 533 533 return error; ··· 549 549 550 550 inode_lock_nested(dir->d_inode, I_MUTEX_NORMAL); 551 551 error = configfs_make_dirent(parent_sd, NULL, (void *) bin_attr, mode, 552 - CONFIGFS_ITEM_BIN_ATTR); 552 + CONFIGFS_ITEM_BIN_ATTR, parent_sd->s_frag); 553 553 inode_unlock(dir->d_inode); 554 554 555 555 return error;