|
@@ -49,7 +49,7 @@
|
|
|
|
|
|
|
|
|
static struct dentry * vxfs_lookup(struct inode *, struct dentry *, unsigned int);
|
|
|
-static int vxfs_readdir(struct file *, void *, filldir_t);
|
|
|
+static int vxfs_readdir(struct file *, struct dir_context *);
|
|
|
|
|
|
const struct inode_operations vxfs_dir_inode_ops = {
|
|
|
.lookup = vxfs_lookup,
|
|
@@ -58,7 +58,7 @@ const struct inode_operations vxfs_dir_inode_ops = {
|
|
|
const struct file_operations vxfs_dir_operations = {
|
|
|
.llseek = generic_file_llseek,
|
|
|
.read = generic_read_dir,
|
|
|
- .readdir = vxfs_readdir,
|
|
|
+ .iterate = vxfs_readdir,
|
|
|
};
|
|
|
|
|
|
|
|
@@ -235,7 +235,7 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags)
|
|
|
* Zero.
|
|
|
*/
|
|
|
static int
|
|
|
-vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
|
|
|
+vxfs_readdir(struct file *fp, struct dir_context *ctx)
|
|
|
{
|
|
|
struct inode *ip = file_inode(fp);
|
|
|
struct super_block *sbp = ip->i_sb;
|
|
@@ -243,20 +243,17 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
|
|
|
u_long page, npages, block, pblocks, nblocks, offset;
|
|
|
loff_t pos;
|
|
|
|
|
|
- switch ((long)fp->f_pos) {
|
|
|
- case 0:
|
|
|
- if (filler(retp, ".", 1, fp->f_pos, ip->i_ino, DT_DIR) < 0)
|
|
|
- goto out;
|
|
|
- fp->f_pos++;
|
|
|
- /* fallthrough */
|
|
|
- case 1:
|
|
|
- if (filler(retp, "..", 2, fp->f_pos, VXFS_INO(ip)->vii_dotdot, DT_DIR) < 0)
|
|
|
- goto out;
|
|
|
- fp->f_pos++;
|
|
|
- /* fallthrough */
|
|
|
+ if (ctx->pos == 0) {
|
|
|
+ if (!dir_emit_dot(fp, ctx))
|
|
|
+ return 0;
|
|
|
+ ctx->pos = 1;
|
|
|
}
|
|
|
-
|
|
|
- pos = fp->f_pos - 2;
|
|
|
+ if (ctx->pos == 1) {
|
|
|
+ if (!dir_emit(ctx, "..", 2, VXFS_INO(ip)->vii_dotdot, DT_DIR))
|
|
|
+ return 0;
|
|
|
+ ctx->pos = 2;
|
|
|
+ }
|
|
|
+ pos = ctx->pos - 2;
|
|
|
|
|
|
if (pos > VXFS_DIRROUND(ip->i_size))
|
|
|
return 0;
|
|
@@ -270,16 +267,16 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
|
|
|
block = (u_long)(pos >> sbp->s_blocksize_bits) % pblocks;
|
|
|
|
|
|
for (; page < npages; page++, block = 0) {
|
|
|
- caddr_t kaddr;
|
|
|
+ char *kaddr;
|
|
|
struct page *pp;
|
|
|
|
|
|
pp = vxfs_get_page(ip->i_mapping, page);
|
|
|
if (IS_ERR(pp))
|
|
|
continue;
|
|
|
- kaddr = (caddr_t)page_address(pp);
|
|
|
+ kaddr = (char *)page_address(pp);
|
|
|
|
|
|
for (; block <= nblocks && block <= pblocks; block++) {
|
|
|
- caddr_t baddr, limit;
|
|
|
+ char *baddr, *limit;
|
|
|
struct vxfs_dirblk *dbp;
|
|
|
struct vxfs_direct *de;
|
|
|
|
|
@@ -292,21 +289,18 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
|
|
|
(kaddr + offset) :
|
|
|
(baddr + VXFS_DIRBLKOV(dbp)));
|
|
|
|
|
|
- for (; (caddr_t)de <= limit; de = vxfs_next_entry(de)) {
|
|
|
- int over;
|
|
|
-
|
|
|
+ for (; (char *)de <= limit; de = vxfs_next_entry(de)) {
|
|
|
if (!de->d_reclen)
|
|
|
break;
|
|
|
if (!de->d_ino)
|
|
|
continue;
|
|
|
|
|
|
- offset = (caddr_t)de - kaddr;
|
|
|
- over = filler(retp, de->d_name, de->d_namelen,
|
|
|
- ((page << PAGE_CACHE_SHIFT) | offset) + 2,
|
|
|
- de->d_ino, DT_UNKNOWN);
|
|
|
- if (over) {
|
|
|
+ offset = (char *)de - kaddr;
|
|
|
+ ctx->pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
|
|
|
+ if (!dir_emit(ctx, de->d_name, de->d_namelen,
|
|
|
+ de->d_ino, DT_UNKNOWN)) {
|
|
|
vxfs_put_page(pp);
|
|
|
- goto done;
|
|
|
+ return 0;
|
|
|
}
|
|
|
}
|
|
|
offset = 0;
|
|
@@ -314,9 +308,6 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
|
|
|
vxfs_put_page(pp);
|
|
|
offset = 0;
|
|
|
}
|
|
|
-
|
|
|
-done:
|
|
|
- fp->f_pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
|
|
|
-out:
|
|
|
+ ctx->pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
|
|
|
return 0;
|
|
|
}
|