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.c60
1 files changed, 24 insertions, 36 deletions
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 79bab9fe120c..9e3b9f97ddbc 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/*
@@ -83,8 +83,7 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
83 lock_kernel(); 83 lock_kernel();
84 84
85 if (filp->f_pos == 0) { 85 if (filp->f_pos == 0) {
86 if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 86 if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) {
87 0) {
88 unlock_kernel(); 87 unlock_kernel();
89 return 0; 88 return 0;
90 } 89 }
@@ -93,7 +92,7 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
93 92
94 result = do_udf_readdir(dir, filp, filldir, dirent); 93 result = do_udf_readdir(dir, filp, filldir, dirent);
95 unlock_kernel(); 94 unlock_kernel();
96 return result; 95 return result;
97} 96}
98 97
99static int 98static int
@@ -125,21 +124,20 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
125 if (nf_pos == 0) 124 if (nf_pos == 0)
126 nf_pos = (udf_ext0_offset(dir) >> 2); 125 nf_pos = (udf_ext0_offset(dir) >> 2);
127 126
128 fibh.soffset = fibh.eoffset = 127 fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
129 (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; 128 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
130 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
131 fibh.sbh = fibh.ebh = NULL; 129 fibh.sbh = fibh.ebh = NULL;
132 else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), 130 } else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
133 &epos, &eloc, &elen, 131 &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
134 &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
135 block = udf_get_lb_pblock(dir->i_sb, eloc, offset); 132 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
136 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { 133 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
137 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) 134 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
138 epos.offset -= sizeof(short_ad); 135 epos.offset -= sizeof(short_ad);
139 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) 136 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
140 epos.offset -= sizeof(long_ad); 137 epos.offset -= sizeof(long_ad);
141 } else 138 } else {
142 offset = 0; 139 offset = 0;
140 }
143 141
144 if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) { 142 if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) {
145 brelse(epos.bh); 143 brelse(epos.bh);
@@ -149,15 +147,11 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
149 if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) { 147 if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) {
150 i = 16 >> (dir->i_sb->s_blocksize_bits - 9); 148 i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
151 if (i + offset > (elen >> dir->i_sb->s_blocksize_bits)) 149 if (i + offset > (elen >> dir->i_sb->s_blocksize_bits))
152 i = (elen >> dir->i_sb->s_blocksize_bits) - 150 i = (elen >> dir->i_sb->s_blocksize_bits) - offset;
153 offset;
154 for (num = 0; i > 0; i--) { 151 for (num = 0; i > 0; i--) {
155 block = 152 block = udf_get_lb_pblock(dir->i_sb, eloc, offset + i);
156 udf_get_lb_pblock(dir->i_sb, eloc,
157 offset + i);
158 tmp = udf_tgetblk(dir->i_sb, block); 153 tmp = udf_tgetblk(dir->i_sb, block);
159 if (tmp && !buffer_uptodate(tmp) 154 if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
160 && !buffer_locked(tmp))
161 bha[num++] = tmp; 155 bha[num++] = tmp;
162 else 156 else
163 brelse(tmp); 157 brelse(tmp);
@@ -178,7 +172,6 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
178 172
179 fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, 173 fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc,
180 &elen, &offset); 174 &elen, &offset);
181
182 if (!fi) { 175 if (!fi) {
183 if (fibh.sbh != fibh.ebh) 176 if (fibh.sbh != fibh.ebh)
184 brelse(fibh.ebh); 177 brelse(fibh.ebh);
@@ -190,19 +183,16 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
190 liu = le16_to_cpu(cfi.lengthOfImpUse); 183 liu = le16_to_cpu(cfi.lengthOfImpUse);
191 lfi = cfi.lengthFileIdent; 184 lfi = cfi.lengthFileIdent;
192 185
193 if (fibh.sbh == fibh.ebh) 186 if (fibh.sbh == fibh.ebh) {
194 nameptr = fi->fileIdent + liu; 187 nameptr = fi->fileIdent + liu;
195 else { 188 } else {
196 int poffset; /* Unpaded ending offset */ 189 int poffset; /* Unpaded ending offset */
197 190
198 poffset = 191 poffset = fibh.soffset + sizeof(struct fileIdentDesc) + liu + lfi;
199 fibh.soffset + sizeof(struct fileIdentDesc) + liu +
200 lfi;
201 192
202 if (poffset >= lfi) 193 if (poffset >= lfi) {
203 nameptr = 194 nameptr = (char *)(fibh.ebh->b_data + poffset - lfi);
204 (char *)(fibh.ebh->b_data + poffset - lfi); 195 } else {
205 else {
206 nameptr = fname; 196 nameptr = fname;
207 memcpy(nameptr, fi->fileIdent + liu, 197 memcpy(nameptr, fi->fileIdent + liu,
208 lfi - poffset); 198 lfi - poffset);
@@ -235,17 +225,15 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
235 } 225 }
236 226
237 if (flen) { 227 if (flen) {
238 if (filldir 228 if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) {
239 (dirent, fname, flen, filp->f_pos, iblock,
240 dt_type) < 0) {
241 if (fibh.sbh != fibh.ebh) 229 if (fibh.sbh != fibh.ebh)
242 brelse(fibh.ebh); 230 brelse(fibh.ebh);
243 brelse(fibh.sbh); 231 brelse(fibh.sbh);
244 brelse(epos.bh); 232 brelse(epos.bh);
245 return 0; 233 return 0;
246 } 234 }
247 } 235 }
248 } /* end while */ 236 } /* end while */
249 237
250 filp->f_pos = nf_pos + 1; 238 filp->f_pos = nf_pos + 1;
251 239