~ubuntu-branches/ubuntu/wily/linux-ti-omap4/wily

« back to all changes in this revision

Viewing changes to fs/ubifs/dir.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati
  • Date: 2013-07-11 18:35:20 UTC
  • Revision ID: package-import@ubuntu.com-20130711183520-htnf1x4y5r11hndr
Tags: 3.5.0-229.42
* Release Tracking Bug
  - LP: #1199276

[ Paolo Pisati ]

* [Config] CONFIG_ATH9K_LEGACY_RATE_CONTROL is not set

Show diffs side-by-side

added added

removed removed

Lines of Context:
349
349
static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
350
350
{
351
351
        int err, over = 0;
 
352
        loff_t pos = file->f_pos;
352
353
        struct qstr nm;
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;
357
358
 
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);
359
360
 
360
 
        if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2)
 
361
        if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2)
361
362
                /*
362
363
                 * The directory was seek'ed to a senseless position or there
363
364
                 * are no more entries.
364
365
                 */
365
366
                return 0;
366
367
 
 
368
        if (file->f_version == 0) {
 
369
                /*
 
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
 
374
                 * basically a no-op.
 
375
                 */
 
376
                kfree(file->private_data);
 
377
                file->private_data = NULL;
 
378
        }
 
379
 
 
380
        /*
 
381
         * 'generic_file_llseek()' unconditionally sets @file->f_version to
 
382
         * zero, and we use this for detecting whether the file was seek'ed.
 
383
         */
 
384
        file->f_version = 1;
 
385
 
367
386
        /* File positions 0 and 1 correspond to "." and ".." */
368
 
        if (file->f_pos == 0) {
 
387
        if (pos == 0) {
369
388
                ubifs_assert(!file->private_data);
370
389
                over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR);
371
390
                if (over)
372
391
                        return 0;
373
 
                file->f_pos = 1;
 
392
                file->f_pos = pos = 1;
374
393
        }
375
394
 
376
 
        if (file->f_pos == 1) {
 
395
        if (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);
389
408
                        goto out;
390
409
                }
391
410
 
392
 
                file->f_pos = key_hash_flash(c, &dent->key);
 
411
                file->f_pos = pos = key_hash_flash(c, &dent->key);
393
412
                file->private_data = dent;
394
413
        }
395
414
 
397
416
        if (!dent) {
398
417
                /*
399
418
                 * The directory was seek'ed to and is now readdir'ed.
400
 
                 * Find the entry corresponding to @file->f_pos or the
401
 
                 * closest one.
 
419
                 * Find the entry corresponding to @pos or the closest one.
402
420
                 */
403
 
                dent_key_init_hash(c, &key, dir->i_ino, file->f_pos);
 
421
                dent_key_init_hash(c, &key, dir->i_ino, pos);
404
422
                nm.name = NULL;
405
423
                dent = ubifs_tnc_next_ent(c, &key, &nm);
406
424
                if (IS_ERR(dent)) {
407
425
                        err = PTR_ERR(dent);
408
426
                        goto out;
409
427
                }
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;
412
430
        }
413
431
 
419
437
                             ubifs_inode(dir)->creat_sqnum);
420
438
 
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));
425
443
                if (over)
435
453
                }
436
454
 
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;
440
458
                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;
441
467
        }
442
468
 
443
469
out:
448
474
 
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 */
451
478
        file->f_pos = 2;
452
479
        return 0;
453
480
}
454
481
 
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)
457
483
{
458
 
        kfree(file->private_data);
459
 
        file->private_data = NULL;
460
484
        return generic_file_llseek(file, offset, origin);
461
485
}
462
486