diff options
author | Jan Kara <jack@suse.cz> | 2010-10-20 12:28:46 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2011-01-06 11:03:55 -0500 |
commit | d664b6af609ecf5e7dcedf92f0bf188e3a29b3e0 (patch) | |
tree | 865eb1db44abdceefea52e46117af61051b610e8 /fs/udf | |
parent | 49521de119d326d04fb3736ab827e12e1de966d0 (diff) |
udf: Move handling of uniqueID into a helper function and protect it by a s_alloc_mutex
uniqueID handling has been duplicated in three places. Move it into a common
helper. Since we modify an LVID buffer with uniqueID update, we take
sbi->s_alloc_mutex to protect agaist other modifications of the structure.
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/ialloc.c | 21 | ||||
-rw-r--r-- | fs/udf/namei.c | 51 | ||||
-rw-r--r-- | fs/udf/super.c | 27 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 1 |
4 files changed, 47 insertions, 53 deletions
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 75d9304d0dc3..6fb7e0adcda0 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
@@ -92,28 +92,19 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) | |||
92 | return NULL; | 92 | return NULL; |
93 | } | 93 | } |
94 | 94 | ||
95 | mutex_lock(&sbi->s_alloc_mutex); | ||
96 | if (sbi->s_lvid_bh) { | 95 | if (sbi->s_lvid_bh) { |
97 | struct logicalVolIntegrityDesc *lvid = | 96 | struct logicalVolIntegrityDescImpUse *lvidiu; |
98 | (struct logicalVolIntegrityDesc *) | 97 | |
99 | sbi->s_lvid_bh->b_data; | 98 | iinfo->i_unique = lvid_get_unique_id(sb); |
100 | struct logicalVolIntegrityDescImpUse *lvidiu = | 99 | mutex_lock(&sbi->s_alloc_mutex); |
101 | udf_sb_lvidiu(sbi); | 100 | lvidiu = udf_sb_lvidiu(sbi); |
102 | struct logicalVolHeaderDesc *lvhd; | ||
103 | uint64_t uniqueID; | ||
104 | lvhd = (struct logicalVolHeaderDesc *) | ||
105 | (lvid->logicalVolContentsUse); | ||
106 | if (S_ISDIR(mode)) | 101 | if (S_ISDIR(mode)) |
107 | le32_add_cpu(&lvidiu->numDirs, 1); | 102 | le32_add_cpu(&lvidiu->numDirs, 1); |
108 | else | 103 | else |
109 | le32_add_cpu(&lvidiu->numFiles, 1); | 104 | le32_add_cpu(&lvidiu->numFiles, 1); |
110 | iinfo->i_unique = uniqueID = le64_to_cpu(lvhd->uniqueID); | ||
111 | if (!(++uniqueID & 0x00000000FFFFFFFFUL)) | ||
112 | uniqueID += 16; | ||
113 | lvhd->uniqueID = cpu_to_le64(uniqueID); | ||
114 | udf_updated_lvid(sb); | 105 | udf_updated_lvid(sb); |
106 | mutex_unlock(&sbi->s_alloc_mutex); | ||
115 | } | 107 | } |
116 | mutex_unlock(&sbi->s_alloc_mutex); | ||
117 | 108 | ||
118 | inode_init_owner(inode, dir, mode); | 109 | inode_init_owner(inode, dir, mode); |
119 | 110 | ||
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 6d8dc02baebb..701fcda18415 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -890,8 +890,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
890 | int block; | 890 | int block; |
891 | unsigned char *name = NULL; | 891 | unsigned char *name = NULL; |
892 | int namelen; | 892 | int namelen; |
893 | struct buffer_head *bh; | ||
894 | struct udf_inode_info *iinfo; | 893 | struct udf_inode_info *iinfo; |
894 | struct super_block *sb = dir->i_sb; | ||
895 | 895 | ||
896 | lock_kernel(); | 896 | lock_kernel(); |
897 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); | 897 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); |
@@ -912,7 +912,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
912 | struct kernel_lb_addr eloc; | 912 | struct kernel_lb_addr eloc; |
913 | uint32_t bsize; | 913 | uint32_t bsize; |
914 | 914 | ||
915 | block = udf_new_block(inode->i_sb, inode, | 915 | block = udf_new_block(sb, inode, |
916 | iinfo->i_location.partitionReferenceNum, | 916 | iinfo->i_location.partitionReferenceNum, |
917 | iinfo->i_location.logicalBlockNum, &err); | 917 | iinfo->i_location.logicalBlockNum, &err); |
918 | if (!block) | 918 | if (!block) |
@@ -923,17 +923,17 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
923 | eloc.logicalBlockNum = block; | 923 | eloc.logicalBlockNum = block; |
924 | eloc.partitionReferenceNum = | 924 | eloc.partitionReferenceNum = |
925 | iinfo->i_location.partitionReferenceNum; | 925 | iinfo->i_location.partitionReferenceNum; |
926 | bsize = inode->i_sb->s_blocksize; | 926 | bsize = sb->s_blocksize; |
927 | iinfo->i_lenExtents = bsize; | 927 | iinfo->i_lenExtents = bsize; |
928 | udf_add_aext(inode, &epos, &eloc, bsize, 0); | 928 | udf_add_aext(inode, &epos, &eloc, bsize, 0); |
929 | brelse(epos.bh); | 929 | brelse(epos.bh); |
930 | 930 | ||
931 | block = udf_get_pblock(inode->i_sb, block, | 931 | block = udf_get_pblock(sb, block, |
932 | iinfo->i_location.partitionReferenceNum, | 932 | iinfo->i_location.partitionReferenceNum, |
933 | 0); | 933 | 0); |
934 | epos.bh = udf_tgetblk(inode->i_sb, block); | 934 | epos.bh = udf_tgetblk(sb, block); |
935 | lock_buffer(epos.bh); | 935 | lock_buffer(epos.bh); |
936 | memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize); | 936 | memset(epos.bh->b_data, 0x00, bsize); |
937 | set_buffer_uptodate(epos.bh); | 937 | set_buffer_uptodate(epos.bh); |
938 | unlock_buffer(epos.bh); | 938 | unlock_buffer(epos.bh); |
939 | mark_buffer_dirty_inode(epos.bh, inode); | 939 | mark_buffer_dirty_inode(epos.bh, inode); |
@@ -941,7 +941,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
941 | } else | 941 | } else |
942 | ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr; | 942 | ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr; |
943 | 943 | ||
944 | eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode); | 944 | eoffset = sb->s_blocksize - udf_ext0_offset(inode); |
945 | pc = (struct pathComponent *)ea; | 945 | pc = (struct pathComponent *)ea; |
946 | 946 | ||
947 | if (*symname == '/') { | 947 | if (*symname == '/') { |
@@ -981,7 +981,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
981 | } | 981 | } |
982 | 982 | ||
983 | if (pc->componentType == 5) { | 983 | if (pc->componentType == 5) { |
984 | namelen = udf_put_filename(inode->i_sb, compstart, name, | 984 | namelen = udf_put_filename(sb, compstart, name, |
985 | symname - compstart); | 985 | symname - compstart); |
986 | if (!namelen) | 986 | if (!namelen) |
987 | goto out_no_entry; | 987 | goto out_no_entry; |
@@ -1015,23 +1015,11 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
1015 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 1015 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
1016 | if (!fi) | 1016 | if (!fi) |
1017 | goto out_no_entry; | 1017 | goto out_no_entry; |
1018 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 1018 | cfi.icb.extLength = cpu_to_le32(sb->s_blocksize); |
1019 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | 1019 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); |
1020 | bh = UDF_SB(inode->i_sb)->s_lvid_bh; | 1020 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { |
1021 | if (bh) { | ||
1022 | struct logicalVolIntegrityDesc *lvid = | ||
1023 | (struct logicalVolIntegrityDesc *)bh->b_data; | ||
1024 | struct logicalVolHeaderDesc *lvhd; | ||
1025 | uint64_t uniqueID; | ||
1026 | lvhd = (struct logicalVolHeaderDesc *) | ||
1027 | lvid->logicalVolContentsUse; | ||
1028 | uniqueID = le64_to_cpu(lvhd->uniqueID); | ||
1029 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | 1021 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
1030 | cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); | 1022 | cpu_to_le32(lvid_get_unique_id(sb)); |
1031 | if (!(++uniqueID & 0x00000000FFFFFFFFUL)) | ||
1032 | uniqueID += 16; | ||
1033 | lvhd->uniqueID = cpu_to_le64(uniqueID); | ||
1034 | mark_buffer_dirty(bh); | ||
1035 | } | 1023 | } |
1036 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 1024 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
1037 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1025 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
@@ -1060,7 +1048,6 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1060 | struct udf_fileident_bh fibh; | 1048 | struct udf_fileident_bh fibh; |
1061 | struct fileIdentDesc cfi, *fi; | 1049 | struct fileIdentDesc cfi, *fi; |
1062 | int err; | 1050 | int err; |
1063 | struct buffer_head *bh; | ||
1064 | 1051 | ||
1065 | lock_kernel(); | 1052 | lock_kernel(); |
1066 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { | 1053 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { |
@@ -1075,21 +1062,9 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1075 | } | 1062 | } |
1076 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | 1063 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); |
1077 | cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location); | 1064 | cfi.icb.extLocation = cpu_to_lelb(UDF_I(inode)->i_location); |
1078 | bh = UDF_SB(inode->i_sb)->s_lvid_bh; | 1065 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { |
1079 | if (bh) { | ||
1080 | struct logicalVolIntegrityDesc *lvid = | ||
1081 | (struct logicalVolIntegrityDesc *)bh->b_data; | ||
1082 | struct logicalVolHeaderDesc *lvhd; | ||
1083 | uint64_t uniqueID; | ||
1084 | lvhd = (struct logicalVolHeaderDesc *) | ||
1085 | (lvid->logicalVolContentsUse); | ||
1086 | uniqueID = le64_to_cpu(lvhd->uniqueID); | ||
1087 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | 1066 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = |
1088 | cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); | 1067 | cpu_to_le32(lvid_get_unique_id(inode->i_sb)); |
1089 | if (!(++uniqueID & 0x00000000FFFFFFFFUL)) | ||
1090 | uniqueID += 16; | ||
1091 | lvhd->uniqueID = cpu_to_le64(uniqueID); | ||
1092 | mark_buffer_dirty(bh); | ||
1093 | } | 1068 | } |
1094 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 1069 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
1095 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1070 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
diff --git a/fs/udf/super.c b/fs/udf/super.c index f99ff5dbd741..948e1aca0f34 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -1823,6 +1823,33 @@ static void udf_close_lvid(struct super_block *sb) | |||
1823 | sbi->s_lvid_dirty = 0; | 1823 | sbi->s_lvid_dirty = 0; |
1824 | } | 1824 | } |
1825 | 1825 | ||
1826 | u64 lvid_get_unique_id(struct super_block *sb) | ||
1827 | { | ||
1828 | struct buffer_head *bh; | ||
1829 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1830 | struct logicalVolIntegrityDesc *lvid; | ||
1831 | struct logicalVolHeaderDesc *lvhd; | ||
1832 | u64 uniqueID; | ||
1833 | u64 ret; | ||
1834 | |||
1835 | bh = sbi->s_lvid_bh; | ||
1836 | if (!bh) | ||
1837 | return 0; | ||
1838 | |||
1839 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | ||
1840 | lvhd = (struct logicalVolHeaderDesc *)lvid->logicalVolContentsUse; | ||
1841 | |||
1842 | mutex_lock(&sbi->s_alloc_mutex); | ||
1843 | ret = uniqueID = le64_to_cpu(lvhd->uniqueID); | ||
1844 | if (!(++uniqueID & 0xFFFFFFFF)) | ||
1845 | uniqueID += 16; | ||
1846 | lvhd->uniqueID = cpu_to_le64(uniqueID); | ||
1847 | mutex_unlock(&sbi->s_alloc_mutex); | ||
1848 | mark_buffer_dirty(bh); | ||
1849 | |||
1850 | return ret; | ||
1851 | } | ||
1852 | |||
1826 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) | 1853 | static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) |
1827 | { | 1854 | { |
1828 | int i; | 1855 | int i; |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index f25e57e8a777..eba48209f9f3 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -125,6 +125,7 @@ static inline void udf_updated_lvid(struct super_block *sb) | |||
125 | sb->s_dirt = 1; | 125 | sb->s_dirt = 1; |
126 | UDF_SB(sb)->s_lvid_dirty = 1; | 126 | UDF_SB(sb)->s_lvid_dirty = 1; |
127 | } | 127 | } |
128 | extern u64 lvid_get_unique_id(struct super_block *sb); | ||
128 | 129 | ||
129 | /* namei.c */ | 130 | /* namei.c */ |
130 | extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, | 131 | extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, |