summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorMartin Brandenburg <martin@omnibond.com>2017-05-02 12:15:11 -0400
committerMike Marshall <hubcap@omnibond.com>2017-05-04 14:38:15 -0400
commit942835d68f6e16f2673c70791dc963c548681cb4 (patch)
tree8ed2bf9e6c291240cbc11489e7eb4628dda698d2 /fs
parentbf15ba7c1f9ad000d062968f931e80234db84a24 (diff)
orangefs: invalidate stored directory on seek
If an application seeks to a position before the point which has been read, it must want updates which have been made to the directory. So delete the copy stored in the kernel so it will be fetched again. Signed-off-by: Martin Brandenburg <martin@omnibond.com> Signed-off-by: Mike Marshall <hubcap@omnibond.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/orangefs/dir.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c
index 4cfb3e5b597e..cac601498925 100644
--- a/fs/orangefs/dir.c
+++ b/fs/orangefs/dir.c
@@ -275,6 +275,28 @@ static int orangefs_dir_fill(struct orangefs_inode_s *oi,
return 0;
}
+static loff_t orangefs_dir_llseek(struct file *file, loff_t offset,
+ int whence)
+{
+ struct orangefs_dir *od = file->private_data;
+ /*
+ * Delete the stored data so userspace sees new directory
+ * entries.
+ */
+ if (!whence && offset < od->end) {
+ struct orangefs_dir_part *part = od->part;
+ while (part) {
+ struct orangefs_dir_part *next = part->next;
+ vfree(part);
+ part = next;
+ }
+ od->token = ORANGEFS_ITERATE_START;
+ od->part = NULL;
+ od->end = 1 << PART_SHIFT;
+ }
+ return default_llseek(file, offset, whence);
+}
+
static int orangefs_dir_iterate(struct file *file,
struct dir_context *ctx)
{
@@ -371,7 +393,7 @@ static int orangefs_dir_release(struct inode *inode, struct file *file)
}
const struct file_operations orangefs_dir_operations = {
- .llseek = default_llseek,
+ .llseek = orangefs_dir_llseek,
.read = generic_read_dir,
.iterate = orangefs_dir_iterate,
.open = orangefs_dir_open,