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

bcachefs: Convert split_devs() to darray

Bit of cleanup & modernization: also moving this code to util.c, it'll
be used by userspace as well.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>

+58 -48
+1
fs/bcachefs/darray.h
··· 20 20 #define DARRAY(_type) DARRAY_PREALLOCATED(_type, 0) 21 21 22 22 typedef DARRAY(char) darray_char; 23 + typedef DARRAY(char *) darray_str; 23 24 24 25 int __bch2_darray_resize(darray_char *, size_t, size_t, gfp_t); 25 26
+20 -48
fs/bcachefs/fs.c
··· 1624 1624 return c ?: ERR_PTR(-ENOENT); 1625 1625 } 1626 1626 1627 - static char **split_devs(const char *_dev_name, unsigned *nr) 1628 - { 1629 - char *dev_name = NULL, **devs = NULL, *s; 1630 - size_t i = 0, nr_devs = 0; 1631 - 1632 - dev_name = kstrdup(_dev_name, GFP_KERNEL); 1633 - if (!dev_name) 1634 - return NULL; 1635 - 1636 - for (s = dev_name; s; s = strchr(s + 1, ':')) 1637 - nr_devs++; 1638 - 1639 - devs = kcalloc(nr_devs + 1, sizeof(const char *), GFP_KERNEL); 1640 - if (!devs) { 1641 - kfree(dev_name); 1642 - return NULL; 1643 - } 1644 - 1645 - while ((s = strsep(&dev_name, ":"))) 1646 - devs[i++] = s; 1647 - 1648 - *nr = nr_devs; 1649 - return devs; 1650 - } 1651 - 1652 1627 static int bch2_remount(struct super_block *sb, int *flags, char *data) 1653 1628 { 1654 1629 struct bch_fs *c = sb->s_fs_info; ··· 1776 1801 return -EBUSY; 1777 1802 } 1778 1803 1804 + typedef DARRAY(struct bch_fs *) darray_fs; 1805 + 1779 1806 static int bch2_test_super(struct super_block *s, void *data) 1780 1807 { 1781 1808 struct bch_fs *c = s->s_fs_info; 1782 - struct bch_fs **devs = data; 1783 - unsigned i; 1809 + darray_fs *d = data; 1784 1810 1785 1811 if (!c) 1786 1812 return false; 1787 1813 1788 - for (i = 0; devs[i]; i++) 1789 - if (c != devs[i]) 1814 + darray_for_each(*d, i) 1815 + if (c != *i) 1790 1816 return false; 1791 1817 return true; 1792 1818 } ··· 1799 1823 struct super_block *sb; 1800 1824 struct inode *vinode; 1801 1825 struct bch_opts opts = bch2_opts_empty(); 1802 - char **devs; 1803 - struct bch_fs **devs_to_fs = NULL; 1804 - unsigned nr_devs; 1805 1826 int ret; 1806 1827 1807 1828 opt_set(opts, read_only, (flags & SB_RDONLY) != 0); ··· 1810 1837 if (!dev_name || strlen(dev_name) == 0) 1811 1838 return ERR_PTR(-EINVAL); 1812 1839 1813 - devs = split_devs(dev_name, &nr_devs); 1814 - if (!devs) 1815 - return ERR_PTR(-ENOMEM); 1840 + darray_str devs; 1841 + ret = bch2_split_devs(dev_name, &devs); 1842 + if (ret) 1843 + return ERR_PTR(ret); 1816 1844 1817 - devs_to_fs = kcalloc(nr_devs + 1, sizeof(void *), GFP_KERNEL); 1818 - if (!devs_to_fs) { 1819 - sb = ERR_PTR(-ENOMEM); 1820 - goto got_sb; 1845 + darray_fs devs_to_fs = {}; 1846 + darray_for_each(devs, i) { 1847 + ret = darray_push(&devs_to_fs, bch2_path_to_fs(*i)); 1848 + if (ret) { 1849 + sb = ERR_PTR(ret); 1850 + goto got_sb; 1851 + } 1821 1852 } 1822 1853 1823 - for (unsigned i = 0; i < nr_devs; i++) 1824 - devs_to_fs[i] = bch2_path_to_fs(devs[i]); 1825 - 1826 - sb = sget(fs_type, bch2_test_super, bch2_noset_super, 1827 - flags|SB_NOSEC, devs_to_fs); 1854 + sb = sget(fs_type, bch2_test_super, bch2_noset_super, flags|SB_NOSEC, &devs_to_fs); 1828 1855 if (!IS_ERR(sb)) 1829 1856 goto got_sb; 1830 1857 1831 - c = bch2_fs_open(devs, nr_devs, opts); 1858 + c = bch2_fs_open(devs.data, devs.nr, opts); 1832 1859 if (IS_ERR(c)) { 1833 1860 sb = ERR_CAST(c); 1834 1861 goto got_sb; ··· 1848 1875 if (IS_ERR(sb)) 1849 1876 bch2_fs_stop(c); 1850 1877 got_sb: 1851 - kfree(devs_to_fs); 1852 - kfree(devs[0]); 1853 - kfree(devs); 1878 + darray_exit(&devs_to_fs); 1879 + bch2_darray_str_exit(&devs); 1854 1880 1855 1881 if (IS_ERR(sb)) { 1856 1882 ret = PTR_ERR(sb);
+34
fs/bcachefs/util.c
··· 1174 1174 1175 1175 return ret; 1176 1176 } 1177 + 1178 + void bch2_darray_str_exit(darray_str *d) 1179 + { 1180 + darray_for_each(*d, i) 1181 + kfree(*i); 1182 + darray_exit(d); 1183 + } 1184 + 1185 + int bch2_split_devs(const char *_dev_name, darray_str *ret) 1186 + { 1187 + darray_init(ret); 1188 + 1189 + char *dev_name = kstrdup(_dev_name, GFP_KERNEL), *s = dev_name; 1190 + if (!dev_name) 1191 + return -ENOMEM; 1192 + 1193 + while ((s = strsep(&dev_name, ":"))) { 1194 + char *p = kstrdup(s, GFP_KERNEL); 1195 + if (!p) 1196 + goto err; 1197 + 1198 + if (darray_push(ret, p)) { 1199 + kfree(p); 1200 + goto err; 1201 + } 1202 + } 1203 + 1204 + kfree(dev_name); 1205 + return 0; 1206 + err: 1207 + bch2_darray_str_exit(ret); 1208 + kfree(dev_name); 1209 + return -ENOMEM; 1210 + }
+3
fs/bcachefs/util.h
··· 863 863 return l.len == r.len && !memcmp(l.name, r.name, l.len); 864 864 } 865 865 866 + void bch2_darray_str_exit(darray_str *); 867 + int bch2_split_devs(const char *, darray_str *); 868 + 866 869 #endif /* _BCACHEFS_UTIL_H */