aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2010-10-20 12:28:46 -0400
committerJan Kara <jack@suse.cz>2011-01-06 11:03:55 -0500
commitd664b6af609ecf5e7dcedf92f0bf188e3a29b3e0 (patch)
tree865eb1db44abdceefea52e46117af61051b610e8 /fs/udf
parent49521de119d326d04fb3736ab827e12e1de966d0 (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.c21
-rw-r--r--fs/udf/namei.c51
-rw-r--r--fs/udf/super.c27
-rw-r--r--fs/udf/udfdecl.h1
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
1826u64 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
1826static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) 1853static 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}
128extern u64 lvid_get_unique_id(struct super_block *sb);
128 129
129/* namei.c */ 130/* namei.c */
130extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, 131extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,