aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs/dir.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-16 01:14:46 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:56:25 -0400
commit01122e06885f4aa220e7a7a31ce25e4876d159f2 (patch)
tree976117358c5dd0fdebb67ade2fbd86ea9fe696fd /fs/ubifs/dir.c
parent5add2ee198723c3fec3ce4a7d77de298344f6ba8 (diff)
[readdir] convert ubifs
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ubifs/dir.c')
-rw-r--r--fs/ubifs/dir.c57
1 files changed, 16 insertions, 41 deletions
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 605af512aec2..6b4947f75af7 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -346,19 +346,18 @@ static unsigned int vfs_dent_type(uint8_t type)
346 * This means that UBIFS cannot support NFS which requires full 346 * This means that UBIFS cannot support NFS which requires full
347 * 'seekdir()'/'telldir()' support. 347 * 'seekdir()'/'telldir()' support.
348 */ 348 */
349static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) 349static int ubifs_readdir(struct file *file, struct dir_context *ctx)
350{ 350{
351 int err, over = 0; 351 int err;
352 loff_t pos = file->f_pos;
353 struct qstr nm; 352 struct qstr nm;
354 union ubifs_key key; 353 union ubifs_key key;
355 struct ubifs_dent_node *dent; 354 struct ubifs_dent_node *dent;
356 struct inode *dir = file_inode(file); 355 struct inode *dir = file_inode(file);
357 struct ubifs_info *c = dir->i_sb->s_fs_info; 356 struct ubifs_info *c = dir->i_sb->s_fs_info;
358 357
359 dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, pos); 358 dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos);
360 359
361 if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2) 360 if (ctx->pos > UBIFS_S_KEY_HASH_MASK || ctx->pos == 2)
362 /* 361 /*
363 * The directory was seek'ed to a senseless position or there 362 * The directory was seek'ed to a senseless position or there
364 * are no more entries. 363 * are no more entries.
@@ -384,19 +383,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
384 file->f_version = 1; 383 file->f_version = 1;
385 384
386 /* File positions 0 and 1 correspond to "." and ".." */ 385 /* File positions 0 and 1 correspond to "." and ".." */
387 if (pos == 0) { 386 if (ctx->pos < 2) {
388 ubifs_assert(!file->private_data);
389 over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR);
390 if (over)
391 return 0;
392 file->f_pos = pos = 1;
393 }
394
395 if (pos == 1) {
396 ubifs_assert(!file->private_data); 387 ubifs_assert(!file->private_data);
397 over = filldir(dirent, "..", 2, 1, 388 if (!dir_emit_dots(file, ctx))
398 parent_ino(file->f_path.dentry), DT_DIR);
399 if (over)
400 return 0; 389 return 0;
401 390
402 /* Find the first entry in TNC and save it */ 391 /* Find the first entry in TNC and save it */
@@ -408,7 +397,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
408 goto out; 397 goto out;
409 } 398 }
410 399
411 file->f_pos = pos = key_hash_flash(c, &dent->key); 400 ctx->pos = key_hash_flash(c, &dent->key);
412 file->private_data = dent; 401 file->private_data = dent;
413 } 402 }
414 403
@@ -416,16 +405,16 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
416 if (!dent) { 405 if (!dent) {
417 /* 406 /*
418 * The directory was seek'ed to and is now readdir'ed. 407 * The directory was seek'ed to and is now readdir'ed.
419 * Find the entry corresponding to @pos or the closest one. 408 * Find the entry corresponding to @ctx->pos or the closest one.
420 */ 409 */
421 dent_key_init_hash(c, &key, dir->i_ino, pos); 410 dent_key_init_hash(c, &key, dir->i_ino, ctx->pos);
422 nm.name = NULL; 411 nm.name = NULL;
423 dent = ubifs_tnc_next_ent(c, &key, &nm); 412 dent = ubifs_tnc_next_ent(c, &key, &nm);
424 if (IS_ERR(dent)) { 413 if (IS_ERR(dent)) {
425 err = PTR_ERR(dent); 414 err = PTR_ERR(dent);
426 goto out; 415 goto out;
427 } 416 }
428 file->f_pos = pos = key_hash_flash(c, &dent->key); 417 ctx->pos = key_hash_flash(c, &dent->key);
429 file->private_data = dent; 418 file->private_data = dent;
430 } 419 }
431 420
@@ -437,10 +426,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
437 ubifs_inode(dir)->creat_sqnum); 426 ubifs_inode(dir)->creat_sqnum);
438 427
439 nm.len = le16_to_cpu(dent->nlen); 428 nm.len = le16_to_cpu(dent->nlen);
440 over = filldir(dirent, dent->name, nm.len, pos, 429 if (!dir_emit(ctx, dent->name, nm.len,
441 le64_to_cpu(dent->inum), 430 le64_to_cpu(dent->inum),
442 vfs_dent_type(dent->type)); 431 vfs_dent_type(dent->type)))
443 if (over)
444 return 0; 432 return 0;
445 433
446 /* Switch to the next entry */ 434 /* Switch to the next entry */
@@ -453,17 +441,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
453 } 441 }
454 442
455 kfree(file->private_data); 443 kfree(file->private_data);
456 file->f_pos = pos = key_hash_flash(c, &dent->key); 444 ctx->pos = key_hash_flash(c, &dent->key);
457 file->private_data = dent; 445 file->private_data = dent;
458 cond_resched(); 446 cond_resched();
459
460 if (file->f_version == 0)
461 /*
462 * The file was seek'ed meanwhile, lets return and start
463 * reading direntries from the new position on the next
464 * invocation.
465 */
466 return 0;
467 } 447 }
468 448
469out: 449out:
@@ -475,15 +455,10 @@ out:
475 kfree(file->private_data); 455 kfree(file->private_data);
476 file->private_data = NULL; 456 file->private_data = NULL;
477 /* 2 is a special value indicating that there are no more direntries */ 457 /* 2 is a special value indicating that there are no more direntries */
478 file->f_pos = 2; 458 ctx->pos = 2;
479 return 0; 459 return 0;
480} 460}
481 461
482static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence)
483{
484 return generic_file_llseek(file, offset, whence);
485}
486
487/* Free saved readdir() state when the directory is closed */ 462/* Free saved readdir() state when the directory is closed */
488static int ubifs_dir_release(struct inode *dir, struct file *file) 463static int ubifs_dir_release(struct inode *dir, struct file *file)
489{ 464{
@@ -1201,10 +1176,10 @@ const struct inode_operations ubifs_dir_inode_operations = {
1201}; 1176};
1202 1177
1203const struct file_operations ubifs_dir_operations = { 1178const struct file_operations ubifs_dir_operations = {
1204 .llseek = ubifs_dir_llseek, 1179 .llseek = generic_file_llseek,
1205 .release = ubifs_dir_release, 1180 .release = ubifs_dir_release,
1206 .read = generic_read_dir, 1181 .read = generic_read_dir,
1207 .readdir = ubifs_readdir, 1182 .iterate = ubifs_readdir,
1208 .fsync = ubifs_fsync, 1183 .fsync = ubifs_fsync,
1209 .unlocked_ioctl = ubifs_ioctl, 1184 .unlocked_ioctl = ubifs_ioctl,
1210#ifdef CONFIG_COMPAT 1185#ifdef CONFIG_COMPAT