aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-11 17:45:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-11 17:45:52 -0500
commit7c955fca3e1d8132982148267d9efcafae849bb6 (patch)
treedd55cc5fd36e36d5c6150a0e34ec798d03b1327e /fs/udf/super.c
parente9688f6acad8cb1f2e8d7abb2de06a6a5c9cbcf2 (diff)
parenta4264b3f4049ae7aeeb0017f8158119e22fa354f (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.c67
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
599out_unlock: 600out_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
1802static void udf_close_lvid(struct super_block *sb) 1804static 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
1838u64 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
1834static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) 1865static 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
2051error_out: 2078error_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
2129static int udf_sync_fs(struct super_block *sb, int wait) 2151static 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
2228out: 2247out:
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}