History

ovl: discard independent cursor in readdir()

Since the ovl_dir_cache is stable during a directory reading, the cursor of struct ovl_dir_file don't need to be an independent entry in the list of a merged directory. This patch changes *cursor* to a pointer which points to the entry in the ovl_dir_cache. After this, we don't need to check *is_cursor* either.

hujianyang committed 11 years ago

Commit 43303971 parent 6d900f51 file · +14 −24Browse files

Unified · Split

fs/overlayfs/readdir.c+14−24
@@ -24,7 +24,6 @@ struct ovl_cache_entry { · 23 unmodified lines
24 struct list_head l_node;24 struct list_head l_node;
25 struct rb_node node;25 struct rb_node node;
26 bool is_whiteout;26 bool is_whiteout;
27 bool is_cursor;
28 char name[];27 char name[];
29};28};
30 29
@@ -49,7 +48,7 @@ struct ovl_dir_file { · 18 unmodified lines
49 bool is_real;48 bool is_real;
50 bool is_upper;49 bool is_upper;
51 struct ovl_dir_cache *cache;50 struct ovl_dir_cache *cache;
52 struct ovl_cache_entry cursor;51 struct list_head *cursor;
53 struct file *realfile;52 struct file *realfile;
54 struct file *upperfile;53 struct file *upperfile;
55};54};
@@ -97,7 +96,6 @@ static struct ovl_cache_entry *ovl_cache_entry_new(struct dentry *dir, · 41 unmodified lines
97 p->type = d_type;96 p->type = d_type;
98 p->ino = ino;97 p->ino = ino;
99 p->is_whiteout = false;98 p->is_whiteout = false;
100 p->is_cursor = false;
101 99
102 if (d_type == DT_CHR) {100 if (d_type == DT_CHR) {
103 struct dentry *dentry;101 struct dentry *dentry;
@@ -196,7 +194,6 @@ static void ovl_cache_put(struct ovl_dir_file *od, struct dentry *dentry) · 92 unmodified lines
196{194{
197 struct ovl_dir_cache *cache = od->cache;195 struct ovl_dir_cache *cache = od->cache;
198 196
199 list_del_init(&od->cursor.l_node);
200 WARN_ON(cache->refcount <= 0);197 WARN_ON(cache->refcount <= 0);
201 cache->refcount--;198 cache->refcount--;
202 if (!cache->refcount) {199 if (!cache->refcount) {
@@ -254,6 +251,7 @@ static void ovl_dir_reset(struct file *file) · 51 unmodified lines
254 if (cache && ovl_dentry_version_get(dentry) != cache->version) {251 if (cache && ovl_dentry_version_get(dentry) != cache->version) {
255 ovl_cache_put(od, dentry);252 ovl_cache_put(od, dentry);
256 od->cache = NULL;253 od->cache = NULL;
254 od->cursor = NULL;
257 }255 }
258 WARN_ON(!od->is_real && !OVL_TYPE_MERGE(type));256 WARN_ON(!od->is_real && !OVL_TYPE_MERGE(type));
259 if (od->is_real && OVL_TYPE_MERGE(type))257 if (od->is_real && OVL_TYPE_MERGE(type))
@@ -295,17 +293,16 @@ static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list) · 35 unmodified lines
295 293
296static void ovl_seek_cursor(struct ovl_dir_file *od, loff_t pos)294static void ovl_seek_cursor(struct ovl_dir_file *od, loff_t pos)
297{295{
298 struct ovl_cache_entry *p;296 struct list_head *p;
299 loff_t off = 0;297 loff_t off = 0;
300 298
301 list_for_each_entry(p, &od->cache->entries, l_node) {299 list_for_each(p, &od->cache->entries) {
302 if (p->is_cursor)
303 continue;
304 if (off >= pos)300 if (off >= pos)
305 break;301 break;
306 off++;302 off++;
307 }303 }
308 list_move_tail(&od->cursor.l_node, &p->l_node);304 /* Cursor is safe since the cache is stable */
305 od->cursor = p;
309}306}
310 307
311static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry)308static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry)
@@ -344,6 +341,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) · 32 unmodified lines
344{341{
345 struct ovl_dir_file *od = file->private_data;342 struct ovl_dir_file *od = file->private_data;
346 struct dentry *dentry = file->f_path.dentry;343 struct dentry *dentry = file->f_path.dentry;
344 struct ovl_cache_entry *p;
347 345
348 if (!ctx->pos)346 if (!ctx->pos)
349 ovl_dir_reset(file);347 ovl_dir_reset(file);
@@ -362,19 +360,13 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) · 12 unmodified lines
362 ovl_seek_cursor(od, ctx->pos);360 ovl_seek_cursor(od, ctx->pos);
363 }361 }
364 362
365 while (od->cursor.l_node.next != &od->cache->entries) {363 while (od->cursor != &od->cache->entries) {
366 struct ovl_cache_entry *p;364 p = list_entry(od->cursor, struct ovl_cache_entry, l_node);
367 365 if (!p->is_whiteout)
368 p = list_entry(od->cursor.l_node.next, struct ovl_cache_entry, l_node);366 if (!dir_emit(ctx, p->name, p->len, p->ino, p->type))
369 /* Skip cursors */367 break;
370 if (!p->is_cursor) {368 od->cursor = p->l_node.next;
371 if (!p->is_whiteout) {369 ctx->pos++;
372 if (!dir_emit(ctx, p->name, p->len, p->ino, p->type))
373 break;
374 }
375 ctx->pos++;
376 }
377 list_move(&od->cursor.l_node, &p->l_node);
378 }370 }
379 return 0;371 return 0;
380}372}
@@ -493,11 +485,9 @@ static int ovl_dir_open(struct inode *inode, struct file *file) · 112 unmodified lines
493 kfree(od);485 kfree(od);
494 return PTR_ERR(realfile);486 return PTR_ERR(realfile);
495 }487 }
496 INIT_LIST_HEAD(&od->cursor.l_node);
497 od->realfile = realfile;488 od->realfile = realfile;
498 od->is_real = !OVL_TYPE_MERGE(type);489 od->is_real = !OVL_TYPE_MERGE(type);
499 od->is_upper = OVL_TYPE_UPPER(type);490 od->is_upper = OVL_TYPE_UPPER(type);
500 od->cursor.is_cursor = true;
501 file->private_data = od;491 file->private_data = od;
502 492
503 return 0;493 return 0;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t