aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/dir.c')
-rw-r--r--fs/udf/dir.c132
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
45const struct file_operations udf_dir_operations = { 45const 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
100static int 99static int
101do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *dirent) 100do_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