diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 17:45:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 17:45:52 -0500 |
commit | 7c955fca3e1d8132982148267d9efcafae849bb6 (patch) | |
tree | dd55cc5fd36e36d5c6150a0e34ec798d03b1327e /fs/udf/super.c | |
parent | e9688f6acad8cb1f2e8d7abb2de06a6a5c9cbcf2 (diff) | |
parent | a4264b3f4049ae7aeeb0017f8158119e22fa354f (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-udf-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-udf-2.6:
UDF: Close small mem leak in udf_find_entry()
udf: Fix directory corruption after extent merging
udf: Protect udf_file_aio_write from possible races
udf: Remove unnecessary bkl usages
udf: Use of s_alloc_mutex to serialize udf_relocate_blocks() execution
udf: Replace bkl with the UDF_I(inode)->i_data_sem for protect udf_inode_info struct
udf: Remove BKL from free space counting functions
udf: Call udf_add_free_space() for more blocks at once in udf_free_blocks()
udf: Remove BKL from udf_put_super() and udf_remount_fs()
udf: Protect default inode credentials by rwlock
udf: Protect all modifications of LVID with s_alloc_mutex
udf: Move handling of uniqueID into a helper function and protect it by a s_alloc_mutex
udf: Remove BKL from udf_update_inode
udf: Convert UDF_SB(sb)->s_flags to use bitops
fs/udf: Add printf format/argument verification
fs/udf: Use vzalloc
(Evil merge: this also removes the BKL dependency from the Kconfig file)
Diffstat (limited to 'fs/udf/super.c')
-rw-r--r-- | fs/udf/super.c | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index b539d53320fb..7b27b063ff6d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <linux/stat.h> | 48 | #include <linux/stat.h> |
49 | #include <linux/cdrom.h> | 49 | #include <linux/cdrom.h> |
50 | #include <linux/nls.h> | 50 | #include <linux/nls.h> |
51 | #include <linux/smp_lock.h> | ||
52 | #include <linux/buffer_head.h> | 51 | #include <linux/buffer_head.h> |
53 | #include <linux/vfs.h> | 52 | #include <linux/vfs.h> |
54 | #include <linux/vmalloc.h> | 53 | #include <linux/vmalloc.h> |
@@ -135,6 +134,7 @@ static struct inode *udf_alloc_inode(struct super_block *sb) | |||
135 | ei->i_next_alloc_block = 0; | 134 | ei->i_next_alloc_block = 0; |
136 | ei->i_next_alloc_goal = 0; | 135 | ei->i_next_alloc_goal = 0; |
137 | ei->i_strat4096 = 0; | 136 | ei->i_strat4096 = 0; |
137 | init_rwsem(&ei->i_data_sem); | ||
138 | 138 | ||
139 | return &ei->vfs_inode; | 139 | return &ei->vfs_inode; |
140 | } | 140 | } |
@@ -574,13 +574,14 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
574 | if (!udf_parse_options(options, &uopt, true)) | 574 | if (!udf_parse_options(options, &uopt, true)) |
575 | return -EINVAL; | 575 | return -EINVAL; |
576 | 576 | ||
577 | lock_kernel(); | 577 | write_lock(&sbi->s_cred_lock); |
578 | sbi->s_flags = uopt.flags; | 578 | sbi->s_flags = uopt.flags; |
579 | sbi->s_uid = uopt.uid; | 579 | sbi->s_uid = uopt.uid; |
580 | sbi->s_gid = uopt.gid; | 580 | sbi->s_gid = uopt.gid; |
581 | sbi->s_umask = uopt.umask; | 581 | sbi->s_umask = uopt.umask; |
582 | sbi->s_fmode = uopt.fmode; | 582 | sbi->s_fmode = uopt.fmode; |
583 | sbi->s_dmode = uopt.dmode; | 583 | sbi->s_dmode = uopt.dmode; |
584 | write_unlock(&sbi->s_cred_lock); | ||
584 | 585 | ||
585 | if (sbi->s_lvid_bh) { | 586 | if (sbi->s_lvid_bh) { |
586 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); | 587 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); |
@@ -597,7 +598,6 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
597 | udf_open_lvid(sb); | 598 | udf_open_lvid(sb); |
598 | 599 | ||
599 | out_unlock: | 600 | out_unlock: |
600 | unlock_kernel(); | ||
601 | return error; | 601 | return error; |
602 | } | 602 | } |
603 | 603 | ||
@@ -966,9 +966,9 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
966 | (sizeof(struct buffer_head *) * nr_groups); | 966 | (sizeof(struct buffer_head *) * nr_groups); |
967 | 967 | ||
968 | if (size <= PAGE_SIZE) | 968 | if (size <= PAGE_SIZE) |
969 | bitmap = kmalloc(size, GFP_KERNEL); | 969 | bitmap = kzalloc(size, GFP_KERNEL); |
970 | else | 970 | else |
971 | bitmap = vmalloc(size); /* TODO: get rid of vmalloc */ | 971 | bitmap = vzalloc(size); /* TODO: get rid of vzalloc */ |
972 | 972 | ||
973 | if (bitmap == NULL) { | 973 | if (bitmap == NULL) { |
974 | udf_error(sb, __func__, | 974 | udf_error(sb, __func__, |
@@ -977,7 +977,6 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
977 | return NULL; | 977 | return NULL; |
978 | } | 978 | } |
979 | 979 | ||
980 | memset(bitmap, 0x00, size); | ||
981 | bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); | 980 | bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); |
982 | bitmap->s_nr_groups = nr_groups; | 981 | bitmap->s_nr_groups = nr_groups; |
983 | return bitmap; | 982 | return bitmap; |
@@ -1781,6 +1780,8 @@ static void udf_open_lvid(struct super_block *sb) | |||
1781 | 1780 | ||
1782 | if (!bh) | 1781 | if (!bh) |
1783 | return; | 1782 | return; |
1783 | |||
1784 | mutex_lock(&sbi->s_alloc_mutex); | ||
1784 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1785 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1785 | lvidiu = udf_sb_lvidiu(sbi); | 1786 | lvidiu = udf_sb_lvidiu(sbi); |
1786 | 1787 | ||
@@ -1797,6 +1798,7 @@ static void udf_open_lvid(struct super_block *sb) | |||
1797 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | 1798 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
1798 | mark_buffer_dirty(bh); | 1799 | mark_buffer_dirty(bh); |
1799 | sbi->s_lvid_dirty = 0; | 1800 | sbi->s_lvid_dirty = 0; |
1801 | mutex_unlock(&sbi->s_alloc_mutex); | ||
1800 | } | 1802 | } |
1801 | 1803 | ||
1802 | static void udf_close_lvid(struct super_block *sb) | 1804 | static void udf_close_lvid(struct super_block *sb) |
@@ -1809,6 +1811,7 @@ static void udf_close_lvid(struct super_block *sb) | |||
1809 | if (!bh) | 1811 | if (!bh) |
1810 | return; | 1812 | return; |
1811 | 1813 | ||
1814 | mutex_lock(&sbi->s_alloc_mutex); | ||
1812 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1815 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1813 | lvidiu = udf_sb_lvidiu(sbi); | 1816 | lvidiu = udf_sb_lvidiu(sbi); |
1814 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1817 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
@@ -1829,6 +1832,34 @@ static void udf_close_lvid(struct super_block *sb) | |||
1829 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | 1832 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); |
1830 | mark_buffer_dirty(bh); | 1833 | mark_buffer_dirty(bh); |
1831 | sbi->s_lvid_dirty = 0; | 1834 | sbi->s_lvid_dirty = 0; |
1835 | mutex_unlock(&sbi->s_alloc_mutex); | ||
1836 | } | ||
1837 | |||
1838 | u64 lvid_get_unique_id(struct super_block *sb) | ||
1839 | { | ||
1840 | struct buffer_head *bh; | ||
1841 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1842 | struct logicalVolIntegrityDesc *lvid; | ||
1843 | struct logicalVolHeaderDesc *lvhd; | ||
1844 | u64 uniqueID; | ||
1845 | u64 ret; | ||
1846 | |||
1847 | bh = sbi->s_lvid_bh; | ||
1848 | if (!bh) | ||
1849 | return 0; | ||
1850 | |||
1851 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | ||
1852 | lvhd = (struct logicalVolHeaderDesc *)lvid->logicalVolContentsUse; | ||
1853 | |||
1854 | mutex_lock(&sbi->s_alloc_mutex); | ||
1855 | ret = uniqueID = le64_to_cpu(lvhd->uniqueID); | ||
1856 | if (!(++uniqueID & 0xFFFFFFFF)) | ||
1857 | uniqueID += 16; | ||
1858 | lvhd->uniqueID = cpu_to_le64(uniqueID); | ||
1859 | mutex_unlock(&sbi->s_alloc_mutex); | ||
1860 | mark_buffer_dirty(bh); | ||
1861 | |||
1862 | return ret; | ||
1832 | } | 1863 | } |
1833 | 1864 | ||
1834 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | 1865 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) |
@@ -1886,8 +1917,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1886 | struct kernel_lb_addr rootdir, fileset; | 1917 | struct kernel_lb_addr rootdir, fileset; |
1887 | struct udf_sb_info *sbi; | 1918 | struct udf_sb_info *sbi; |
1888 | 1919 | ||
1889 | lock_kernel(); | ||
1890 | |||
1891 | uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); | 1920 | uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); |
1892 | uopt.uid = -1; | 1921 | uopt.uid = -1; |
1893 | uopt.gid = -1; | 1922 | uopt.gid = -1; |
@@ -1896,10 +1925,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1896 | uopt.dmode = UDF_INVALID_MODE; | 1925 | uopt.dmode = UDF_INVALID_MODE; |
1897 | 1926 | ||
1898 | sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL); | 1927 | sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL); |
1899 | if (!sbi) { | 1928 | if (!sbi) |
1900 | unlock_kernel(); | ||
1901 | return -ENOMEM; | 1929 | return -ENOMEM; |
1902 | } | ||
1903 | 1930 | ||
1904 | sb->s_fs_info = sbi; | 1931 | sb->s_fs_info = sbi; |
1905 | 1932 | ||
@@ -1936,6 +1963,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1936 | sbi->s_fmode = uopt.fmode; | 1963 | sbi->s_fmode = uopt.fmode; |
1937 | sbi->s_dmode = uopt.dmode; | 1964 | sbi->s_dmode = uopt.dmode; |
1938 | sbi->s_nls_map = uopt.nls_map; | 1965 | sbi->s_nls_map = uopt.nls_map; |
1966 | rwlock_init(&sbi->s_cred_lock); | ||
1939 | 1967 | ||
1940 | if (uopt.session == 0xFFFFFFFF) | 1968 | if (uopt.session == 0xFFFFFFFF) |
1941 | sbi->s_session = udf_get_last_session(sb); | 1969 | sbi->s_session = udf_get_last_session(sb); |
@@ -2045,7 +2073,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
2045 | goto error_out; | 2073 | goto error_out; |
2046 | } | 2074 | } |
2047 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 2075 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
2048 | unlock_kernel(); | ||
2049 | return 0; | 2076 | return 0; |
2050 | 2077 | ||
2051 | error_out: | 2078 | error_out: |
@@ -2066,7 +2093,6 @@ error_out: | |||
2066 | kfree(sbi); | 2093 | kfree(sbi); |
2067 | sb->s_fs_info = NULL; | 2094 | sb->s_fs_info = NULL; |
2068 | 2095 | ||
2069 | unlock_kernel(); | ||
2070 | return -EINVAL; | 2096 | return -EINVAL; |
2071 | } | 2097 | } |
2072 | 2098 | ||
@@ -2105,8 +2131,6 @@ static void udf_put_super(struct super_block *sb) | |||
2105 | 2131 | ||
2106 | sbi = UDF_SB(sb); | 2132 | sbi = UDF_SB(sb); |
2107 | 2133 | ||
2108 | lock_kernel(); | ||
2109 | |||
2110 | if (sbi->s_vat_inode) | 2134 | if (sbi->s_vat_inode) |
2111 | iput(sbi->s_vat_inode); | 2135 | iput(sbi->s_vat_inode); |
2112 | if (sbi->s_partitions) | 2136 | if (sbi->s_partitions) |
@@ -2122,8 +2146,6 @@ static void udf_put_super(struct super_block *sb) | |||
2122 | kfree(sbi->s_partmaps); | 2146 | kfree(sbi->s_partmaps); |
2123 | kfree(sb->s_fs_info); | 2147 | kfree(sb->s_fs_info); |
2124 | sb->s_fs_info = NULL; | 2148 | sb->s_fs_info = NULL; |
2125 | |||
2126 | unlock_kernel(); | ||
2127 | } | 2149 | } |
2128 | 2150 | ||
2129 | static int udf_sync_fs(struct super_block *sb, int wait) | 2151 | static int udf_sync_fs(struct super_block *sb, int wait) |
@@ -2186,8 +2208,6 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2186 | uint16_t ident; | 2208 | uint16_t ident; |
2187 | struct spaceBitmapDesc *bm; | 2209 | struct spaceBitmapDesc *bm; |
2188 | 2210 | ||
2189 | lock_kernel(); | ||
2190 | |||
2191 | loc.logicalBlockNum = bitmap->s_extPosition; | 2211 | loc.logicalBlockNum = bitmap->s_extPosition; |
2192 | loc.partitionReferenceNum = UDF_SB(sb)->s_partition; | 2212 | loc.partitionReferenceNum = UDF_SB(sb)->s_partition; |
2193 | bh = udf_read_ptagged(sb, &loc, 0, &ident); | 2213 | bh = udf_read_ptagged(sb, &loc, 0, &ident); |
@@ -2224,10 +2244,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb, | |||
2224 | } | 2244 | } |
2225 | } | 2245 | } |
2226 | brelse(bh); | 2246 | brelse(bh); |
2227 | |||
2228 | out: | 2247 | out: |
2229 | unlock_kernel(); | ||
2230 | |||
2231 | return accum; | 2248 | return accum; |
2232 | } | 2249 | } |
2233 | 2250 | ||
@@ -2240,8 +2257,7 @@ static unsigned int udf_count_free_table(struct super_block *sb, | |||
2240 | int8_t etype; | 2257 | int8_t etype; |
2241 | struct extent_position epos; | 2258 | struct extent_position epos; |
2242 | 2259 | ||
2243 | lock_kernel(); | 2260 | mutex_lock(&UDF_SB(sb)->s_alloc_mutex); |
2244 | |||
2245 | epos.block = UDF_I(table)->i_location; | 2261 | epos.block = UDF_I(table)->i_location; |
2246 | epos.offset = sizeof(struct unallocSpaceEntry); | 2262 | epos.offset = sizeof(struct unallocSpaceEntry); |
2247 | epos.bh = NULL; | 2263 | epos.bh = NULL; |
@@ -2250,8 +2266,7 @@ static unsigned int udf_count_free_table(struct super_block *sb, | |||
2250 | accum += (elen >> table->i_sb->s_blocksize_bits); | 2266 | accum += (elen >> table->i_sb->s_blocksize_bits); |
2251 | 2267 | ||
2252 | brelse(epos.bh); | 2268 | brelse(epos.bh); |
2253 | 2269 | mutex_unlock(&UDF_SB(sb)->s_alloc_mutex); | |
2254 | unlock_kernel(); | ||
2255 | 2270 | ||
2256 | return accum; | 2271 | return accum; |
2257 | } | 2272 | } |