349
349
static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
351
351
int err, over = 0;
352
loff_t pos = file->f_pos;
353
354
union ubifs_key key;
354
355
struct ubifs_dent_node *dent;
355
356
struct inode *dir = file->f_path.dentry->d_inode;
356
357
struct ubifs_info *c = dir->i_sb->s_fs_info;
358
dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos);
359
dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, pos);
360
if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2)
361
if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2)
362
363
* The directory was seek'ed to a senseless position or there
363
364
* are no more entries.
368
if (file->f_version == 0) {
370
* The file was seek'ed, which means that @file->private_data
371
* is now invalid. This may also be just the first
372
* 'ubifs_readdir()' invocation, in which case
373
* @file->private_data is NULL, and the below code is
376
kfree(file->private_data);
377
file->private_data = NULL;
381
* 'generic_file_llseek()' unconditionally sets @file->f_version to
382
* zero, and we use this for detecting whether the file was seek'ed.
367
386
/* File positions 0 and 1 correspond to "." and ".." */
368
if (file->f_pos == 0) {
369
388
ubifs_assert(!file->private_data);
370
389
over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR);
392
file->f_pos = pos = 1;
376
if (file->f_pos == 1) {
377
396
ubifs_assert(!file->private_data);
378
397
over = filldir(dirent, "..", 2, 1,
379
398
parent_ino(file->f_path.dentry), DT_DIR);
399
418
* The directory was seek'ed to and is now readdir'ed.
400
* Find the entry corresponding to @file->f_pos or the
419
* Find the entry corresponding to @pos or the closest one.
403
dent_key_init_hash(c, &key, dir->i_ino, file->f_pos);
421
dent_key_init_hash(c, &key, dir->i_ino, pos);
405
423
dent = ubifs_tnc_next_ent(c, &key, &nm);
406
424
if (IS_ERR(dent)) {
407
425
err = PTR_ERR(dent);
410
file->f_pos = key_hash_flash(c, &dent->key);
428
file->f_pos = pos = key_hash_flash(c, &dent->key);
411
429
file->private_data = dent;
419
437
ubifs_inode(dir)->creat_sqnum);
421
439
nm.len = le16_to_cpu(dent->nlen);
422
over = filldir(dirent, dent->name, nm.len, file->f_pos,
440
over = filldir(dirent, dent->name, nm.len, pos,
423
441
le64_to_cpu(dent->inum),
424
442
vfs_dent_type(dent->type));
437
455
kfree(file->private_data);
438
file->f_pos = key_hash_flash(c, &dent->key);
456
file->f_pos = pos = key_hash_flash(c, &dent->key);
439
457
file->private_data = dent;
460
if (file->f_version == 0)
462
* The file was seek'ed meanwhile, lets return and start
463
* reading direntries from the new position on the next
449
475
kfree(file->private_data);
450
476
file->private_data = NULL;
477
/* 2 is a special value indicating that there are no more direntries */
455
/* If a directory is seeked, we have to free saved readdir() state */
456
482
static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int origin)
458
kfree(file->private_data);
459
file->private_data = NULL;
460
484
return generic_file_llseek(file, offset, origin);