Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 377461
b: refs/heads/master
c: 605c912
h: refs/heads/master
i:
  377459: 5eed688
v: v3
  • Loading branch information
Artem Bityutskiy authored and Al Viro committed Jun 29, 2013
1 parent 9f2d2a2 commit 600bcae
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 33f1a63ae84dfd9ad298cf275b8f1887043ced36
refs/heads/master: 605c912bb843c024b1ed173dc427cd5c08e5d54d
30 changes: 27 additions & 3 deletions trunk/fs/ubifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,24 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
*/
return 0;

if (file->f_version == 0) {
/*
* The file was seek'ed, which means that @file->private_data
* is now invalid. This may also be just the first
* 'ubifs_readdir()' invocation, in which case
* @file->private_data is NULL, and the below code is
* basically a no-op.
*/
kfree(file->private_data);
file->private_data = NULL;
}

/*
* 'generic_file_llseek()' unconditionally sets @file->f_version to
* zero, and we use this for detecting whether the file was seek'ed.
*/
file->f_version = 1;

/* File positions 0 and 1 correspond to "." and ".." */
if (pos == 0) {
ubifs_assert(!file->private_data);
Expand Down Expand Up @@ -438,6 +456,14 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
file->f_pos = pos = key_hash_flash(c, &dent->key);
file->private_data = dent;
cond_resched();

if (file->f_version == 0)
/*
* The file was seek'ed meanwhile, lets return and start
* reading direntries from the new position on the next
* invocation.
*/
return 0;
}

out:
Expand All @@ -448,15 +474,13 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)

kfree(file->private_data);
file->private_data = NULL;
/* 2 is a special value indicating that there are no more direntries */
file->f_pos = 2;
return 0;
}

/* If a directory is seeked, we have to free saved readdir() state */
static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence)
{
kfree(file->private_data);
file->private_data = NULL;
return generic_file_llseek(file, offset, whence);
}

Expand Down

0 comments on commit 600bcae

Please sign in to comment.