aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-22 16:31:14 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:56:58 -0400
commit1bbae9f818609959b8ffc0bf61ba8026a7059426 (patch)
treecc6b89a0b534db005cbe469d134eac4b6d1f91ee
parent76f582a8f60a94c116e0b92d07c9047410274b20 (diff)
[readdir] convert afs
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/afs/dir.c99
1 files changed, 37 insertions, 62 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 7a465ed04444..34494fbead0a 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -22,7 +22,7 @@
22static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, 22static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
23 unsigned int flags); 23 unsigned int flags);
24static int afs_dir_open(struct inode *inode, struct file *file); 24static int afs_dir_open(struct inode *inode, struct file *file);
25static int afs_readdir(struct file *file, void *dirent, filldir_t filldir); 25static int afs_readdir(struct file *file, struct dir_context *ctx);
26static int afs_d_revalidate(struct dentry *dentry, unsigned int flags); 26static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
27static int afs_d_delete(const struct dentry *dentry); 27static int afs_d_delete(const struct dentry *dentry);
28static void afs_d_release(struct dentry *dentry); 28static void afs_d_release(struct dentry *dentry);
@@ -43,7 +43,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
43const struct file_operations afs_dir_file_operations = { 43const struct file_operations afs_dir_file_operations = {
44 .open = afs_dir_open, 44 .open = afs_dir_open,
45 .release = afs_release, 45 .release = afs_release,
46 .readdir = afs_readdir, 46 .iterate = afs_readdir,
47 .lock = afs_lock, 47 .lock = afs_lock,
48 .llseek = generic_file_llseek, 48 .llseek = generic_file_llseek,
49}; 49};
@@ -119,9 +119,9 @@ struct afs_dir_page {
119}; 119};
120 120
121struct afs_lookup_cookie { 121struct afs_lookup_cookie {
122 struct dir_context ctx;
122 struct afs_fid fid; 123 struct afs_fid fid;
123 const char *name; 124 struct qstr name;
124 size_t nlen;
125 int found; 125 int found;
126}; 126};
127 127
@@ -228,20 +228,18 @@ static int afs_dir_open(struct inode *inode, struct file *file)
228/* 228/*
229 * deal with one block in an AFS directory 229 * deal with one block in an AFS directory
230 */ 230 */
231static int afs_dir_iterate_block(unsigned *fpos, 231static int afs_dir_iterate_block(struct dir_context *ctx,
232 union afs_dir_block *block, 232 union afs_dir_block *block,
233 unsigned blkoff, 233 unsigned blkoff)
234 void *cookie,
235 filldir_t filldir)
236{ 234{
237 union afs_dirent *dire; 235 union afs_dirent *dire;
238 unsigned offset, next, curr; 236 unsigned offset, next, curr;
239 size_t nlen; 237 size_t nlen;
240 int tmp, ret; 238 int tmp;
241 239
242 _enter("%u,%x,%p,,",*fpos,blkoff,block); 240 _enter("%u,%x,%p,,",(unsigned)ctx->pos,blkoff,block);
243 241
244 curr = (*fpos - blkoff) / sizeof(union afs_dirent); 242 curr = (ctx->pos - blkoff) / sizeof(union afs_dirent);
245 243
246 /* walk through the block, an entry at a time */ 244 /* walk through the block, an entry at a time */
247 for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries; 245 for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries;
@@ -256,7 +254,7 @@ static int afs_dir_iterate_block(unsigned *fpos,
256 _debug("ENT[%Zu.%u]: unused", 254 _debug("ENT[%Zu.%u]: unused",
257 blkoff / sizeof(union afs_dir_block), offset); 255 blkoff / sizeof(union afs_dir_block), offset);
258 if (offset >= curr) 256 if (offset >= curr)
259 *fpos = blkoff + 257 ctx->pos = blkoff +
260 next * sizeof(union afs_dirent); 258 next * sizeof(union afs_dirent);
261 continue; 259 continue;
262 } 260 }
@@ -302,19 +300,15 @@ static int afs_dir_iterate_block(unsigned *fpos,
302 continue; 300 continue;
303 301
304 /* found the next entry */ 302 /* found the next entry */
305 ret = filldir(cookie, 303 if (!dir_emit(ctx, dire->u.name, nlen,
306 dire->u.name,
307 nlen,
308 blkoff + offset * sizeof(union afs_dirent),
309 ntohl(dire->u.vnode), 304 ntohl(dire->u.vnode),
310 filldir == afs_lookup_filldir ? 305 ctx->actor == afs_lookup_filldir ?
311 ntohl(dire->u.unique) : DT_UNKNOWN); 306 ntohl(dire->u.unique) : DT_UNKNOWN)) {
312 if (ret < 0) {
313 _leave(" = 0 [full]"); 307 _leave(" = 0 [full]");
314 return 0; 308 return 0;
315 } 309 }
316 310
317 *fpos = blkoff + next * sizeof(union afs_dirent); 311 ctx->pos = blkoff + next * sizeof(union afs_dirent);
318 } 312 }
319 313
320 _leave(" = 1 [more]"); 314 _leave(" = 1 [more]");
@@ -324,8 +318,8 @@ static int afs_dir_iterate_block(unsigned *fpos,
324/* 318/*
325 * iterate through the data blob that lists the contents of an AFS directory 319 * iterate through the data blob that lists the contents of an AFS directory
326 */ 320 */
327static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, 321static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
328 filldir_t filldir, struct key *key) 322 struct key *key)
329{ 323{
330 union afs_dir_block *dblock; 324 union afs_dir_block *dblock;
331 struct afs_dir_page *dbuf; 325 struct afs_dir_page *dbuf;
@@ -333,7 +327,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
333 unsigned blkoff, limit; 327 unsigned blkoff, limit;
334 int ret; 328 int ret;
335 329
336 _enter("{%lu},%u,,", dir->i_ino, *fpos); 330 _enter("{%lu},%u,,", dir->i_ino, (unsigned)ctx->pos);
337 331
338 if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dir)->flags)) { 332 if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dir)->flags)) {
339 _leave(" = -ESTALE"); 333 _leave(" = -ESTALE");
@@ -341,13 +335,13 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
341 } 335 }
342 336
343 /* round the file position up to the next entry boundary */ 337 /* round the file position up to the next entry boundary */
344 *fpos += sizeof(union afs_dirent) - 1; 338 ctx->pos += sizeof(union afs_dirent) - 1;
345 *fpos &= ~(sizeof(union afs_dirent) - 1); 339 ctx->pos &= ~(sizeof(union afs_dirent) - 1);
346 340
347 /* walk through the blocks in sequence */ 341 /* walk through the blocks in sequence */
348 ret = 0; 342 ret = 0;
349 while (*fpos < dir->i_size) { 343 while (ctx->pos < dir->i_size) {
350 blkoff = *fpos & ~(sizeof(union afs_dir_block) - 1); 344 blkoff = ctx->pos & ~(sizeof(union afs_dir_block) - 1);
351 345
352 /* fetch the appropriate page from the directory */ 346 /* fetch the appropriate page from the directory */
353 page = afs_dir_get_page(dir, blkoff / PAGE_SIZE, key); 347 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 do { 358 do {
365 dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) / 359 dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) /
366 sizeof(union afs_dir_block)]; 360 sizeof(union afs_dir_block)];
367 ret = afs_dir_iterate_block(fpos, dblock, blkoff, 361 ret = afs_dir_iterate_block(ctx, dblock, blkoff);
368 cookie, filldir);
369 if (ret != 1) { 362 if (ret != 1) {
370 afs_dir_put_page(page); 363 afs_dir_put_page(page);
371 goto out; 364 goto out;
@@ -373,7 +366,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
373 366
374 blkoff += sizeof(union afs_dir_block); 367 blkoff += sizeof(union afs_dir_block);
375 368
376 } while (*fpos < dir->i_size && blkoff < limit); 369 } while (ctx->pos < dir->i_size && blkoff < limit);
377 370
378 afs_dir_put_page(page); 371 afs_dir_put_page(page);
379 ret = 0; 372 ret = 0;
@@ -387,23 +380,10 @@ out:
387/* 380/*
388 * read an AFS directory 381 * read an AFS directory
389 */ 382 */
390static int afs_readdir(struct file *file, void *cookie, filldir_t filldir) 383static int afs_readdir(struct file *file, struct dir_context *ctx)
391{ 384{
392 unsigned fpos; 385 return afs_dir_iterate(file_inode(file),
393 int ret; 386 ctx, file->private_data);
394
395 _enter("{%Ld,{%lu}}",
396 file->f_pos, file_inode(file)->i_ino);
397
398 ASSERT(file->private_data != NULL);
399
400 fpos = file->f_pos;
401 ret = afs_dir_iterate(file_inode(file), &fpos,
402 cookie, filldir, file->private_data);
403 file->f_pos = fpos;
404
405 _leave(" = %d", ret);
406 return ret;
407} 387}
408 388
409/* 389/*
@@ -416,15 +396,16 @@ static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
416{ 396{
417 struct afs_lookup_cookie *cookie = _cookie; 397 struct afs_lookup_cookie *cookie = _cookie;
418 398
419 _enter("{%s,%Zu},%s,%u,,%llu,%u", 399 _enter("{%s,%u},%s,%u,,%llu,%u",
420 cookie->name, cookie->nlen, name, nlen, 400 cookie->name.name, cookie->name.len, name, nlen,
421 (unsigned long long) ino, dtype); 401 (unsigned long long) ino, dtype);
422 402
423 /* insanity checks first */ 403 /* insanity checks first */
424 BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048); 404 BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
425 BUILD_BUG_ON(sizeof(union afs_dirent) != 32); 405 BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
426 406
427 if (cookie->nlen != nlen || memcmp(cookie->name, name, nlen) != 0) { 407 if (cookie->name.len != nlen ||
408 memcmp(cookie->name.name, name, nlen) != 0) {
428 _leave(" = 0 [no]"); 409 _leave(" = 0 [no]");
429 return 0; 410 return 0;
430 } 411 }
@@ -444,24 +425,18 @@ static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
444static int afs_do_lookup(struct inode *dir, struct dentry *dentry, 425static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
445 struct afs_fid *fid, struct key *key) 426 struct afs_fid *fid, struct key *key)
446{ 427{
447 struct afs_lookup_cookie cookie; 428 struct afs_super_info *as = dir->i_sb->s_fs_info;
448 struct afs_super_info *as; 429 struct afs_lookup_cookie cookie = {
449 unsigned fpos; 430 .ctx.actor = afs_lookup_filldir,
431 .name = dentry->d_name,
432 .fid.vid = as->volume->vid
433 };
450 int ret; 434 int ret;
451 435
452 _enter("{%lu},%p{%s},", dir->i_ino, dentry, dentry->d_name.name); 436 _enter("{%lu},%p{%s},", dir->i_ino, dentry, dentry->d_name.name);
453 437
454 as = dir->i_sb->s_fs_info;
455
456 /* search the directory */ 438 /* search the directory */
457 cookie.name = dentry->d_name.name; 439 ret = afs_dir_iterate(dir, &cookie.ctx, key);
458 cookie.nlen = dentry->d_name.len;
459 cookie.fid.vid = as->volume->vid;
460 cookie.found = 0;
461
462 fpos = 0;
463 ret = afs_dir_iterate(dir, &fpos, &cookie, afs_lookup_filldir,
464 key);
465 if (ret < 0) { 440 if (ret < 0) {
466 _leave(" = %d [iter]", ret); 441 _leave(" = %d [iter]", ret);
467 return ret; 442 return ret;