diff options
Diffstat (limited to 'fs/udf/dir.c')
-rw-r--r-- | fs/udf/dir.c | 141 |
1 files changed, 69 insertions, 72 deletions
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 9e3b9f97ddb..8d8643ada19 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -36,80 +36,20 @@ #include "udf_i.h" #include "udf_sb.h" -/* Prototypes for file operations */ -static int udf_readdir(struct file *, void *, filldir_t); -static int do_udf_readdir(struct inode *, struct file *, filldir_t, void *); - -/* readdir and lookup functions */ - -const struct file_operations udf_dir_operations = { - .read = generic_read_dir, - .readdir = udf_readdir, - .ioctl = udf_ioctl, - .fsync = udf_fsync_file, -}; - -/* - * udf_readdir - * - * PURPOSE - * Read a directory entry. - * - * DESCRIPTION - * Optional - sys_getdents() will return -ENOTDIR if this routine is not - * available. - * - * Refer to sys_getdents() in fs/readdir.c - * sys_getdents() -> . - * - * PRE-CONDITIONS - * filp Pointer to directory file. - * buf Pointer to directory entry buffer. - * filldir Pointer to filldir function. - * - * POST-CONDITIONS - * <return> >=0 on success. - * - * HISTORY - * July 1, 1997 - Andrew E. Mileski - * Written, tested, and released. - */ - -int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) -{ - struct inode *dir = filp->f_path.dentry->d_inode; - int result; - - lock_kernel(); - - if (filp->f_pos == 0) { - if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) { - unlock_kernel(); - return 0; - } - filp->f_pos++; - } - - result = do_udf_readdir(dir, filp, filldir, dirent); - unlock_kernel(); - return result; -} - -static int -do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir, - void *dirent) +static int do_udf_readdir(struct inode *dir, struct file *filp, + filldir_t filldir, void *dirent) { struct udf_fileident_bh fibh; struct fileIdentDesc *fi = NULL; struct fileIdentDesc cfi; int block, iblock; - loff_t nf_pos = filp->f_pos - 1; + loff_t nf_pos = (filp->f_pos - 1) << 2; int flen; char fname[UDF_NAME_LEN]; char *nameptr; uint16_t liu; uint8_t lfi; - loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; + loff_t size = udf_ext0_offset(dir) + dir->i_size; struct buffer_head *tmp, *bha[16]; kernel_lb_addr eloc; uint32_t elen; @@ -117,23 +57,26 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir, int i, num; unsigned int dt_type; struct extent_position epos = { NULL, 0, {0, 0} }; + struct udf_inode_info *iinfo; if (nf_pos >= size) return 0; if (nf_pos == 0) - nf_pos = (udf_ext0_offset(dir) >> 2); + nf_pos = udf_ext0_offset(dir); - fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; - if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) { + fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); + iinfo = UDF_I(dir); + if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { fibh.sbh = fibh.ebh = NULL; - } else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), + } else if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) { block = udf_get_lb_pblock(dir->i_sb, eloc, offset); if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { - if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) + if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) epos.offset -= sizeof(short_ad); - else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) + else if (iinfo->i_alloc_type == + ICBTAG_FLAG_AD_LONG) epos.offset -= sizeof(long_ad); } else { offset = 0; @@ -168,7 +111,7 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir, } while (nf_pos < size) { - filp->f_pos = nf_pos + 1; + filp->f_pos = (nf_pos >> 2) + 1; fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset); @@ -235,7 +178,7 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir, } } /* end while */ - filp->f_pos = nf_pos + 1; + filp->f_pos = (nf_pos >> 2) + 1; if (fibh.sbh != fibh.ebh) brelse(fibh.ebh); @@ -244,3 +187,57 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir, return 0; } + +/* + * udf_readdir + * + * PURPOSE + * Read a directory entry. + * + * DESCRIPTION + * Optional - sys_getdents() will return -ENOTDIR if this routine is not + * available. + * + * Refer to sys_getdents() in fs/readdir.c + * sys_getdents() -> . + * + * PRE-CONDITIONS + * filp Pointer to directory file. + * buf Pointer to directory entry buffer. + * filldir Pointer to filldir function. + * + * POST-CONDITIONS + * <return> >=0 on success. + * + * HISTORY + * July 1, 1997 - Andrew E. Mileski + * Written, tested, and released. + */ + +static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct inode *dir = filp->f_path.dentry->d_inode; + int result; + + lock_kernel(); + + if (filp->f_pos == 0) { + if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) { + unlock_kernel(); + return 0; + } + filp->f_pos++; + } + + result = do_udf_readdir(dir, filp, filldir, dirent); + unlock_kernel(); + return result; +} + +/* readdir and lookup functions */ +const struct file_operations udf_dir_operations = { + .read = generic_read_dir, + .readdir = udf_readdir, + .ioctl = udf_ioctl, + .fsync = udf_fsync_file, +}; |