patch-2.4.6 linux/fs/udf/dir.c
Next file: linux/fs/udf/directory.c
Previous file: linux/fs/udf/crc.c
Back to the patch index
Back to the overall index
- Lines: 186
- Date:
Mon Jun 11 19:15:27 2001
- Orig file:
v2.4.5/linux/fs/udf/dir.c
- Orig date:
Fri Feb 9 11:29:44 2001
diff -u --recursive --new-file v2.4.5/linux/fs/udf/dir.c linux/fs/udf/dir.c
@@ -7,7 +7,7 @@
* CONTACTS
* E-mail regarding any portion of the Linux UDF file system should be
* directed to the development team mailing list (run by majordomo):
- * linux_udf@hootie.lvld.hp.com
+ * linux_udf@hpesjro.fc.hp.com
*
* COPYRIGHT
* This file is distributed under the terms of the GNU General Public
@@ -49,10 +49,10 @@
/* readdir and lookup functions */
struct file_operations udf_dir_operations = {
- read: generic_read_dir,
- readdir: udf_readdir,
- ioctl: udf_ioctl,
- fsync: udf_sync_file,
+ read: generic_read_dir,
+ readdir: udf_readdir,
+ ioctl: udf_ioctl,
+ fsync: udf_fsync_file,
};
/*
@@ -88,8 +88,9 @@
if ( filp->f_pos == 0 )
{
- if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR))
+ if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0)
return 0;
+ filp->f_pos ++;
}
result = do_udf_readdir(dir, filp, filldir, dirent);
@@ -104,19 +105,21 @@
struct FileIdentDesc *fi=NULL;
struct FileIdentDesc cfi;
int block, iblock;
- loff_t nf_pos = filp->f_pos;
+ loff_t nf_pos = filp->f_pos - 1;
int flen;
char fname[255];
char *nameptr;
Uint16 liu;
Uint8 lfi;
loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
- struct buffer_head * bh = NULL;
+ struct buffer_head * bh = NULL, * tmp, * bha[16];
lb_addr bloc, eloc;
Uint32 extoffset, elen, offset;
+ int i, num;
+ unsigned int dt_type;
if (nf_pos >= size)
- return 1;
+ return 0;
if (nf_pos == 0)
nf_pos = (udf_ext0_offset(dir) >> 2);
@@ -125,6 +128,7 @@
if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
&bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
{
+ offset >>= dir->i_sb->s_blocksize_bits;
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{
@@ -139,18 +143,40 @@
else
{
udf_release_data(bh);
- return 0;
+ return -ENOENT;
}
if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
{
udf_release_data(bh);
- return 0;
+ return -EIO;
+ }
+
+ if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9))-1)))
+ {
+ i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
+ if (i+offset > (elen >> dir->i_sb->s_blocksize_bits))
+ i = (elen >> dir->i_sb->s_blocksize_bits)-offset;
+ for (num=0; i>0; i--)
+ {
+ block = udf_get_lb_pblock(dir->i_sb, eloc, offset+i);
+ tmp = udf_tgetblk(dir->i_sb, block, dir->i_sb->s_blocksize);
+ if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
+ bha[num++] = tmp;
+ else
+ brelse(tmp);
+ }
+ if (num)
+ {
+ ll_rw_block(READA, num, bha);
+ for (i=0; i<num; i++)
+ brelse(bha[i]);
+ }
}
while ( nf_pos < size )
{
- filp->f_pos = nf_pos;
+ filp->f_pos = nf_pos + 1;
fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
@@ -160,7 +186,7 @@
udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh);
udf_release_data(bh);
- return 1;
+ return -ENOENT;
}
liu = le16_to_cpu(cfi.lengthOfImpUse);
@@ -196,44 +222,39 @@
continue;
}
- iblock = udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0);
-
- if (!lfi) /* parent directory */
- {
- if (filldir(dirent, "..", 2, filp->f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR))
+ if ( cfi.fileCharacteristics & FILE_PARENT )
+ {
+ iblock = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(filp->f_dentry->d_parent->d_inode), 0);
+ flen = 2;
+ memcpy(fname, "..", flen);
+ dt_type = DT_DIR;
+ }
+ else
+ {
+ iblock = udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0);
+ flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
+ dt_type = DT_UNKNOWN;
+ }
+
+ if (flen)
+ {
+ if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0)
{
if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh);
udf_release_data(bh);
- return 1;
- }
- }
- else
- {
- if ((flen = udf_get_filename(nameptr, fname, lfi)))
- {
- if (filldir(dirent, fname, flen, filp->f_pos, iblock, DT_UNKNOWN))
- {
- if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
- return 1; /* halt enum */
- }
+ return 0;
}
}
} /* end while */
- filp->f_pos = nf_pos;
+ filp->f_pos = nf_pos + 1;
if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh);
udf_release_data(fibh.sbh);
udf_release_data(bh);
- if ( filp->f_pos >= size)
- return 1;
- else
- return 0;
+ return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)