unsigned int len;
unsigned int type;
u64 ino;
- bool is_whiteout;
struct list_head l_node;
struct rb_node node;
+ bool is_whiteout;
+ bool is_cursor;
char name[];
};
p->type = d_type;
p->ino = ino;
p->is_whiteout = false;
+ p->is_cursor = false;
}
return p;
mutex_lock(&dir->d_inode->i_mutex);
list_for_each_entry(p, rdd->list, l_node) {
- if (!p->name)
+ if (p->is_cursor)
continue;
if (p->type != DT_CHR)
}
out:
return err;
-
}
static void ovl_seek_cursor(struct ovl_dir_file *od, loff_t pos)
loff_t off = 0;
list_for_each_entry(p, &od->cache->entries, l_node) {
- if (!p->name)
+ if (p->is_cursor)
continue;
if (off >= pos)
break;
p = list_entry(od->cursor.l_node.next, struct ovl_cache_entry, l_node);
/* Skip cursors */
- if (p->name) {
+ if (!p->is_cursor) {
if (!p->is_whiteout) {
if (!dir_emit(ctx, p->name, p->len, p->ino, p->type))
break;
if (!od->is_upper && ovl_path_type(dentry) == OVL_PATH_MERGE) {
struct inode *inode = file_inode(file);
- realfile = od->upperfile;
+ realfile =lockless_dereference(od->upperfile);
if (!realfile) {
struct path upperpath;
ovl_path_upper(dentry, &upperpath);
realfile = ovl_path_open(&upperpath, O_RDONLY);
+ smp_mb__before_spinlock();
mutex_lock(&inode->i_mutex);
if (!od->upperfile) {
if (IS_ERR(realfile)) {
od->realfile = realfile;
od->is_real = (type != OVL_PATH_MERGE);
od->is_upper = (type != OVL_PATH_LOWER);
+ od->cursor.is_cursor = true;
file->private_data = od;
return 0;
{
struct ovl_cache_entry *p;
- mutex_lock_nested(&upper->d_inode->i_mutex, I_MUTEX_PARENT);
+ mutex_lock_nested(&upper->d_inode->i_mutex, I_MUTEX_CHILD);
list_for_each_entry(p, list, l_node) {
struct dentry *dentry;