aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/namei.c
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/namei.c
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/namei.c')
-rw-r--r--fs/udf/namei.c51
1 files changed, 13 insertions, 38 deletions
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)