Commit 1bbae9f8 authored by Al Viro's avatar Al Viro

[readdir] convert afs

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 76f582a8
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags); unsigned int flags);
static int afs_dir_open(struct inode *inode, struct file *file); static int afs_dir_open(struct inode *inode, struct file *file);
static int afs_readdir(struct file *file, void *dirent, filldir_t filldir); static int afs_readdir(struct file *file, struct dir_context *ctx);
static int afs_d_revalidate(struct dentry *dentry, unsigned int flags); static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
static int afs_d_delete(const struct dentry *dentry); static int afs_d_delete(const struct dentry *dentry);
static void afs_d_release(struct dentry *dentry); static void afs_d_release(struct dentry *dentry);
...@@ -43,7 +43,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -43,7 +43,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
const struct file_operations afs_dir_file_operations = { const struct file_operations afs_dir_file_operations = {
.open = afs_dir_open, .open = afs_dir_open,
.release = afs_release, .release = afs_release,
.readdir = afs_readdir, .iterate = afs_readdir,
.lock = afs_lock, .lock = afs_lock,
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
}; };
...@@ -119,9 +119,9 @@ struct afs_dir_page { ...@@ -119,9 +119,9 @@ struct afs_dir_page {
}; };
struct afs_lookup_cookie { struct afs_lookup_cookie {
struct dir_context ctx;
struct afs_fid fid; struct afs_fid fid;
const char *name; struct qstr name;
size_t nlen;
int found; int found;
}; };
...@@ -228,20 +228,18 @@ static int afs_dir_open(struct inode *inode, struct file *file) ...@@ -228,20 +228,18 @@ static int afs_dir_open(struct inode *inode, struct file *file)
/* /*
* deal with one block in an AFS directory * deal with one block in an AFS directory
*/ */
static int afs_dir_iterate_block(unsigned *fpos, static int afs_dir_iterate_block(struct dir_context *ctx,
union afs_dir_block *block, union afs_dir_block *block,
unsigned blkoff, unsigned blkoff)
void *cookie,
filldir_t filldir)
{ {
union afs_dirent *dire; union afs_dirent *dire;
unsigned offset, next, curr; unsigned offset, next, curr;
size_t nlen; size_t nlen;
int tmp, ret; int tmp;
_enter("%u,%x,%p,,",*fpos,blkoff,block); _enter("%u,%x,%p,,",(unsigned)ctx->pos,blkoff,block);
curr = (*fpos - blkoff) / sizeof(union afs_dirent); curr = (ctx->pos - blkoff) / sizeof(union afs_dirent);
/* walk through the block, an entry at a time */ /* walk through the block, an entry at a time */
for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries; for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries;
...@@ -256,7 +254,7 @@ static int afs_dir_iterate_block(unsigned *fpos, ...@@ -256,7 +254,7 @@ static int afs_dir_iterate_block(unsigned *fpos,
_debug("ENT[%Zu.%u]: unused", _debug("ENT[%Zu.%u]: unused",
blkoff / sizeof(union afs_dir_block), offset); blkoff / sizeof(union afs_dir_block), offset);
if (offset >= curr) if (offset >= curr)
*fpos = blkoff + ctx->pos = blkoff +
next * sizeof(union afs_dirent); next * sizeof(union afs_dirent);
continue; continue;
} }
...@@ -302,19 +300,15 @@ static int afs_dir_iterate_block(unsigned *fpos, ...@@ -302,19 +300,15 @@ static int afs_dir_iterate_block(unsigned *fpos,
continue; continue;
/* found the next entry */ /* found the next entry */
ret = filldir(cookie, if (!dir_emit(ctx, dire->u.name, nlen,
dire->u.name,
nlen,
blkoff + offset * sizeof(union afs_dirent),
ntohl(dire->u.vnode), ntohl(dire->u.vnode),
filldir == afs_lookup_filldir ? ctx->actor == afs_lookup_filldir ?
ntohl(dire->u.unique) : DT_UNKNOWN); ntohl(dire->u.unique) : DT_UNKNOWN)) {
if (ret < 0) {
_leave(" = 0 [full]"); _leave(" = 0 [full]");
return 0; return 0;
} }
*fpos = blkoff + next * sizeof(union afs_dirent); ctx->pos = blkoff + next * sizeof(union afs_dirent);
} }
_leave(" = 1 [more]"); _leave(" = 1 [more]");
...@@ -324,8 +318,8 @@ static int afs_dir_iterate_block(unsigned *fpos, ...@@ -324,8 +318,8 @@ static int afs_dir_iterate_block(unsigned *fpos,
/* /*
* iterate through the data blob that lists the contents of an AFS directory * iterate through the data blob that lists the contents of an AFS directory
*/ */
static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
filldir_t filldir, struct key *key) struct key *key)
{ {
union afs_dir_block *dblock; union afs_dir_block *dblock;
struct afs_dir_page *dbuf; struct afs_dir_page *dbuf;
...@@ -333,7 +327,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, ...@@ -333,7 +327,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
unsigned blkoff, limit; unsigned blkoff, limit;
int ret; int ret;
_enter("{%lu},%u,,", dir->i_ino, *fpos); _enter("{%lu},%u,,", dir->i_ino, (unsigned)ctx->pos);
if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dir)->flags)) { if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dir)->flags)) {
_leave(" = -ESTALE"); _leave(" = -ESTALE");
...@@ -341,13 +335,13 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, ...@@ -341,13 +335,13 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
} }
/* round the file position up to the next entry boundary */ /* round the file position up to the next entry boundary */
*fpos += sizeof(union afs_dirent) - 1; ctx->pos += sizeof(union afs_dirent) - 1;
*fpos &= ~(sizeof(union afs_dirent) - 1); ctx->pos &= ~(sizeof(union afs_dirent) - 1);
/* walk through the blocks in sequence */ /* walk through the blocks in sequence */
ret = 0; ret = 0;
while (*fpos < dir->i_size) { while (ctx->pos < dir->i_size) {
blkoff = *fpos & ~(sizeof(union afs_dir_block) - 1); blkoff = ctx->pos & ~(sizeof(union afs_dir_block) - 1);
/* fetch the appropriate page from the directory */ /* fetch the appropriate page from the directory */
page = afs_dir_get_page(dir, blkoff / PAGE_SIZE, key); page = afs_dir_get_page(dir, blkoff / PAGE_SIZE, key);
...@@ -364,8 +358,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, ...@@ -364,8 +358,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
do { do {
dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) / dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) /
sizeof(union afs_dir_block)]; sizeof(union afs_dir_block)];
ret = afs_dir_iterate_block(fpos, dblock, blkoff, ret = afs_dir_iterate_block(ctx, dblock, blkoff);
cookie, filldir);
if (ret != 1) { if (ret != 1) {
afs_dir_put_page(page); afs_dir_put_page(page);
goto out; goto out;
...@@ -373,7 +366,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, ...@@ -373,7 +366,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
blkoff += sizeof(union afs_dir_block); blkoff += sizeof(union afs_dir_block);
} while (*fpos < dir->i_size && blkoff < limit); } while (ctx->pos < dir->i_size && blkoff < limit);
afs_dir_put_page(page); afs_dir_put_page(page);
ret = 0; ret = 0;
...@@ -387,23 +380,10 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, ...@@ -387,23 +380,10 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
/* /*
* read an AFS directory * read an AFS directory
*/ */
static int afs_readdir(struct file *file, void *cookie, filldir_t filldir) static int afs_readdir(struct file *file, struct dir_context *ctx)
{ {
unsigned fpos; return afs_dir_iterate(file_inode(file),
int ret; ctx, file->private_data);
_enter("{%Ld,{%lu}}",
file->f_pos, file_inode(file)->i_ino);
ASSERT(file->private_data != NULL);
fpos = file->f_pos;
ret = afs_dir_iterate(file_inode(file), &fpos,
cookie, filldir, file->private_data);
file->f_pos = fpos;
_leave(" = %d", ret);
return ret;
} }
/* /*
...@@ -416,15 +396,16 @@ static int afs_lookup_filldir(void *_cookie, const char *name, int nlen, ...@@ -416,15 +396,16 @@ static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
{ {
struct afs_lookup_cookie *cookie = _cookie; struct afs_lookup_cookie *cookie = _cookie;
_enter("{%s,%Zu},%s,%u,,%llu,%u", _enter("{%s,%u},%s,%u,,%llu,%u",
cookie->name, cookie->nlen, name, nlen, cookie->name.name, cookie->name.len, name, nlen,
(unsigned long long) ino, dtype); (unsigned long long) ino, dtype);
/* insanity checks first */ /* insanity checks first */
BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048); BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
BUILD_BUG_ON(sizeof(union afs_dirent) != 32); BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
if (cookie->nlen != nlen || memcmp(cookie->name, name, nlen) != 0) { if (cookie->name.len != nlen ||
memcmp(cookie->name.name, name, nlen) != 0) {
_leave(" = 0 [no]"); _leave(" = 0 [no]");
return 0; return 0;
} }
...@@ -444,24 +425,18 @@ static int afs_lookup_filldir(void *_cookie, const char *name, int nlen, ...@@ -444,24 +425,18 @@ static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
static int afs_do_lookup(struct inode *dir, struct dentry *dentry, static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
struct afs_fid *fid, struct key *key) struct afs_fid *fid, struct key *key)
{ {
struct afs_lookup_cookie cookie; struct afs_super_info *as = dir->i_sb->s_fs_info;
struct afs_super_info *as; struct afs_lookup_cookie cookie = {
unsigned fpos; .ctx.actor = afs_lookup_filldir,
.name = dentry->d_name,
.fid.vid = as->volume->vid
};
int ret; int ret;
_enter("{%lu},%p{%s},", dir->i_ino, dentry, dentry->d_name.name); _enter("{%lu},%p{%s},", dir->i_ino, dentry, dentry->d_name.name);
as = dir->i_sb->s_fs_info;
/* search the directory */ /* search the directory */
cookie.name = dentry->d_name.name; ret = afs_dir_iterate(dir, &cookie.ctx, key);
cookie.nlen = dentry->d_name.len;
cookie.fid.vid = as->volume->vid;
cookie.found = 0;
fpos = 0;
ret = afs_dir_iterate(dir, &fpos, &cookie, afs_lookup_filldir,
key);
if (ret < 0) { if (ret < 0) {
_leave(" = %d [iter]", ret); _leave(" = %d [iter]", ret);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment