diff options
Diffstat (limited to 'fs/udf/dir.c')
-rw-r--r-- | fs/udf/dir.c | 132 |
1 files changed, 63 insertions, 69 deletions
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index e45f86b5e7b0..79bab9fe120c 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -43,10 +43,10 @@ static int do_udf_readdir(struct inode *, struct file *, filldir_t, void *); | |||
43 | /* readdir and lookup functions */ | 43 | /* readdir and lookup functions */ |
44 | 44 | ||
45 | const struct file_operations udf_dir_operations = { | 45 | const struct file_operations udf_dir_operations = { |
46 | .read = generic_read_dir, | 46 | .read = generic_read_dir, |
47 | .readdir = udf_readdir, | 47 | .readdir = udf_readdir, |
48 | .ioctl = udf_ioctl, | 48 | .ioctl = udf_ioctl, |
49 | .fsync = udf_fsync_file, | 49 | .fsync = udf_fsync_file, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | /* | 52 | /* |
@@ -82,26 +82,26 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
82 | 82 | ||
83 | lock_kernel(); | 83 | lock_kernel(); |
84 | 84 | ||
85 | if ( filp->f_pos == 0 ) | 85 | if (filp->f_pos == 0) { |
86 | { | 86 | if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < |
87 | if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) | 87 | 0) { |
88 | { | ||
89 | unlock_kernel(); | 88 | unlock_kernel(); |
90 | return 0; | 89 | return 0; |
91 | } | 90 | } |
92 | filp->f_pos ++; | 91 | filp->f_pos++; |
93 | } | 92 | } |
94 | 93 | ||
95 | result = do_udf_readdir(dir, filp, filldir, dirent); | 94 | result = do_udf_readdir(dir, filp, filldir, dirent); |
96 | unlock_kernel(); | 95 | unlock_kernel(); |
97 | return result; | 96 | return result; |
98 | } | 97 | } |
99 | 98 | ||
100 | static int | 99 | static int |
101 | do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *dirent) | 100 | do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir, |
101 | void *dirent) | ||
102 | { | 102 | { |
103 | struct udf_fileident_bh fibh; | 103 | struct udf_fileident_bh fibh; |
104 | struct fileIdentDesc *fi=NULL; | 104 | struct fileIdentDesc *fi = NULL; |
105 | struct fileIdentDesc cfi; | 105 | struct fileIdentDesc cfi; |
106 | int block, iblock; | 106 | int block, iblock; |
107 | loff_t nf_pos = filp->f_pos - 1; | 107 | loff_t nf_pos = filp->f_pos - 1; |
@@ -117,7 +117,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
117 | sector_t offset; | 117 | sector_t offset; |
118 | int i, num; | 118 | int i, num; |
119 | unsigned int dt_type; | 119 | unsigned int dt_type; |
120 | struct extent_position epos = { NULL, 0, {0, 0}}; | 120 | struct extent_position epos = { NULL, 0, {0, 0} }; |
121 | 121 | ||
122 | if (nf_pos >= size) | 122 | if (nf_pos >= size) |
123 | return 0; | 123 | return 0; |
@@ -125,65 +125,61 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
125 | if (nf_pos == 0) | 125 | if (nf_pos == 0) |
126 | nf_pos = (udf_ext0_offset(dir) >> 2); | 126 | nf_pos = (udf_ext0_offset(dir) >> 2); |
127 | 127 | ||
128 | fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; | 128 | fibh.soffset = fibh.eoffset = |
129 | (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; | ||
129 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) | 130 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) |
130 | fibh.sbh = fibh.ebh = NULL; | 131 | fibh.sbh = fibh.ebh = NULL; |
131 | else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), | 132 | else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), |
132 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) | 133 | &epos, &eloc, &elen, |
133 | { | 134 | &offset) == (EXT_RECORDED_ALLOCATED >> 30)) { |
134 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 135 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
135 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) | 136 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { |
136 | { | ||
137 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) | 137 | if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) |
138 | epos.offset -= sizeof(short_ad); | 138 | epos.offset -= sizeof(short_ad); |
139 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) | 139 | else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) |
140 | epos.offset -= sizeof(long_ad); | 140 | epos.offset -= sizeof(long_ad); |
141 | } | 141 | } else |
142 | else | ||
143 | offset = 0; | 142 | offset = 0; |
144 | 143 | ||
145 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) | 144 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) { |
146 | { | ||
147 | brelse(epos.bh); | 145 | brelse(epos.bh); |
148 | return -EIO; | 146 | return -EIO; |
149 | } | 147 | } |
150 | 148 | ||
151 | if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1))) | 149 | if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) { |
152 | { | ||
153 | i = 16 >> (dir->i_sb->s_blocksize_bits - 9); | 150 | i = 16 >> (dir->i_sb->s_blocksize_bits - 9); |
154 | if (i+offset > (elen >> dir->i_sb->s_blocksize_bits)) | 151 | if (i + offset > (elen >> dir->i_sb->s_blocksize_bits)) |
155 | i = (elen >> dir->i_sb->s_blocksize_bits)-offset; | 152 | i = (elen >> dir->i_sb->s_blocksize_bits) - |
156 | for (num=0; i>0; i--) | 153 | offset; |
157 | { | 154 | for (num = 0; i > 0; i--) { |
158 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset+i); | 155 | block = |
156 | udf_get_lb_pblock(dir->i_sb, eloc, | ||
157 | offset + i); | ||
159 | tmp = udf_tgetblk(dir->i_sb, block); | 158 | tmp = udf_tgetblk(dir->i_sb, block); |
160 | if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) | 159 | if (tmp && !buffer_uptodate(tmp) |
160 | && !buffer_locked(tmp)) | ||
161 | bha[num++] = tmp; | 161 | bha[num++] = tmp; |
162 | else | 162 | else |
163 | brelse(tmp); | 163 | brelse(tmp); |
164 | } | 164 | } |
165 | if (num) | 165 | if (num) { |
166 | { | ||
167 | ll_rw_block(READA, num, bha); | 166 | ll_rw_block(READA, num, bha); |
168 | for (i=0; i<num; i++) | 167 | for (i = 0; i < num; i++) |
169 | brelse(bha[i]); | 168 | brelse(bha[i]); |
170 | } | 169 | } |
171 | } | 170 | } |
172 | } | 171 | } else { |
173 | else | ||
174 | { | ||
175 | brelse(epos.bh); | 172 | brelse(epos.bh); |
176 | return -ENOENT; | 173 | return -ENOENT; |
177 | } | 174 | } |
178 | 175 | ||
179 | while ( nf_pos < size ) | 176 | while (nf_pos < size) { |
180 | { | ||
181 | filp->f_pos = nf_pos + 1; | 177 | filp->f_pos = nf_pos + 1; |
182 | 178 | ||
183 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset); | 179 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, |
180 | &elen, &offset); | ||
184 | 181 | ||
185 | if (!fi) | 182 | if (!fi) { |
186 | { | ||
187 | if (fibh.sbh != fibh.ebh) | 183 | if (fibh.sbh != fibh.ebh) |
188 | brelse(fibh.ebh); | 184 | brelse(fibh.ebh); |
189 | brelse(fibh.sbh); | 185 | brelse(fibh.sbh); |
@@ -196,43 +192,41 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
196 | 192 | ||
197 | if (fibh.sbh == fibh.ebh) | 193 | if (fibh.sbh == fibh.ebh) |
198 | nameptr = fi->fileIdent + liu; | 194 | nameptr = fi->fileIdent + liu; |
199 | else | 195 | else { |
200 | { | ||
201 | int poffset; /* Unpaded ending offset */ | 196 | int poffset; /* Unpaded ending offset */ |
202 | 197 | ||
203 | poffset = fibh.soffset + sizeof(struct fileIdentDesc) + liu + lfi; | 198 | poffset = |
199 | fibh.soffset + sizeof(struct fileIdentDesc) + liu + | ||
200 | lfi; | ||
204 | 201 | ||
205 | if (poffset >= lfi) | 202 | if (poffset >= lfi) |
206 | nameptr = (char *)(fibh.ebh->b_data + poffset - lfi); | 203 | nameptr = |
207 | else | 204 | (char *)(fibh.ebh->b_data + poffset - lfi); |
208 | { | 205 | else { |
209 | nameptr = fname; | 206 | nameptr = fname; |
210 | memcpy(nameptr, fi->fileIdent + liu, lfi - poffset); | 207 | memcpy(nameptr, fi->fileIdent + liu, |
211 | memcpy(nameptr + lfi - poffset, fibh.ebh->b_data, poffset); | 208 | lfi - poffset); |
209 | memcpy(nameptr + lfi - poffset, | ||
210 | fibh.ebh->b_data, poffset); | ||
212 | } | 211 | } |
213 | } | 212 | } |
214 | 213 | ||
215 | if ( (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 ) | 214 | if ((cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { |
216 | { | 215 | if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE)) |
217 | if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE) ) | ||
218 | continue; | 216 | continue; |
219 | } | 217 | } |
220 | 218 | ||
221 | if ( (cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0 ) | 219 | if ((cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) { |
222 | { | 220 | if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE)) |
223 | if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) ) | ||
224 | continue; | 221 | continue; |
225 | } | 222 | } |
226 | 223 | ||
227 | if ( cfi.fileCharacteristics & FID_FILE_CHAR_PARENT ) | 224 | if (cfi.fileCharacteristics & FID_FILE_CHAR_PARENT) { |
228 | { | ||
229 | iblock = parent_ino(filp->f_path.dentry); | 225 | iblock = parent_ino(filp->f_path.dentry); |
230 | flen = 2; | 226 | flen = 2; |
231 | memcpy(fname, "..", flen); | 227 | memcpy(fname, "..", flen); |
232 | dt_type = DT_DIR; | 228 | dt_type = DT_DIR; |
233 | } | 229 | } else { |
234 | else | ||
235 | { | ||
236 | kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation); | 230 | kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation); |
237 | 231 | ||
238 | iblock = udf_get_lb_pblock(dir->i_sb, tloc, 0); | 232 | iblock = udf_get_lb_pblock(dir->i_sb, tloc, 0); |
@@ -240,18 +234,18 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
240 | dt_type = DT_UNKNOWN; | 234 | dt_type = DT_UNKNOWN; |
241 | } | 235 | } |
242 | 236 | ||
243 | if (flen) | 237 | if (flen) { |
244 | { | 238 | if (filldir |
245 | if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) | 239 | (dirent, fname, flen, filp->f_pos, iblock, |
246 | { | 240 | dt_type) < 0) { |
247 | if (fibh.sbh != fibh.ebh) | 241 | if (fibh.sbh != fibh.ebh) |
248 | brelse(fibh.ebh); | 242 | brelse(fibh.ebh); |
249 | brelse(fibh.sbh); | 243 | brelse(fibh.sbh); |
250 | brelse(epos.bh); | 244 | brelse(epos.bh); |
251 | return 0; | 245 | return 0; |
252 | } | 246 | } |
253 | } | 247 | } |
254 | } /* end while */ | 248 | } /* end while */ |
255 | 249 | ||
256 | filp->f_pos = nf_pos + 1; | 250 | filp->f_pos = nf_pos + 1; |
257 | 251 | ||