Loading fs/ubifs/dir.c +16 −41 Original line number Original line Diff line number Diff line Loading @@ -346,19 +346,18 @@ static unsigned int vfs_dent_type(uint8_t type) * This means that UBIFS cannot support NFS which requires full * This means that UBIFS cannot support NFS which requires full * 'seekdir()'/'telldir()' support. * 'seekdir()'/'telldir()' support. */ */ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) static int ubifs_readdir(struct file *file, struct dir_context *ctx) { { int err, over = 0; int err; loff_t pos = file->f_pos; struct qstr nm; struct qstr nm; union ubifs_key key; union ubifs_key key; struct ubifs_dent_node *dent; struct ubifs_dent_node *dent; struct inode *dir = file_inode(file); struct inode *dir = file_inode(file); struct ubifs_info *c = dir->i_sb->s_fs_info; struct ubifs_info *c = dir->i_sb->s_fs_info; dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, pos); dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos); if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2) if (ctx->pos > UBIFS_S_KEY_HASH_MASK || ctx->pos == 2) /* /* * The directory was seek'ed to a senseless position or there * The directory was seek'ed to a senseless position or there * are no more entries. * are no more entries. Loading @@ -384,19 +383,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) file->f_version = 1; file->f_version = 1; /* File positions 0 and 1 correspond to "." and ".." */ /* File positions 0 and 1 correspond to "." and ".." */ if (pos == 0) { if (ctx->pos < 2) { ubifs_assert(!file->private_data); over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR); if (over) return 0; file->f_pos = pos = 1; } if (pos == 1) { ubifs_assert(!file->private_data); ubifs_assert(!file->private_data); over = filldir(dirent, "..", 2, 1, if (!dir_emit_dots(file, ctx)) parent_ino(file->f_path.dentry), DT_DIR); if (over) return 0; return 0; /* Find the first entry in TNC and save it */ /* Find the first entry in TNC and save it */ Loading @@ -408,7 +397,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) goto out; goto out; } } file->f_pos = pos = key_hash_flash(c, &dent->key); ctx->pos = key_hash_flash(c, &dent->key); file->private_data = dent; file->private_data = dent; } } Loading @@ -416,16 +405,16 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) if (!dent) { if (!dent) { /* /* * The directory was seek'ed to and is now readdir'ed. * The directory was seek'ed to and is now readdir'ed. * Find the entry corresponding to @pos or the closest one. * Find the entry corresponding to @ctx->pos or the closest one. */ */ dent_key_init_hash(c, &key, dir->i_ino, pos); dent_key_init_hash(c, &key, dir->i_ino, ctx->pos); nm.name = NULL; nm.name = NULL; dent = ubifs_tnc_next_ent(c, &key, &nm); dent = ubifs_tnc_next_ent(c, &key, &nm); if (IS_ERR(dent)) { if (IS_ERR(dent)) { err = PTR_ERR(dent); err = PTR_ERR(dent); goto out; goto out; } } file->f_pos = pos = key_hash_flash(c, &dent->key); ctx->pos = key_hash_flash(c, &dent->key); file->private_data = dent; file->private_data = dent; } } Loading @@ -437,10 +426,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) ubifs_inode(dir)->creat_sqnum); ubifs_inode(dir)->creat_sqnum); nm.len = le16_to_cpu(dent->nlen); nm.len = le16_to_cpu(dent->nlen); over = filldir(dirent, dent->name, nm.len, pos, if (!dir_emit(ctx, dent->name, nm.len, le64_to_cpu(dent->inum), le64_to_cpu(dent->inum), vfs_dent_type(dent->type)); vfs_dent_type(dent->type))) if (over) return 0; return 0; /* Switch to the next entry */ /* Switch to the next entry */ Loading @@ -453,17 +441,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) } } kfree(file->private_data); kfree(file->private_data); file->f_pos = pos = key_hash_flash(c, &dent->key); ctx->pos = key_hash_flash(c, &dent->key); file->private_data = dent; file->private_data = dent; cond_resched(); 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: out: Loading @@ -475,15 +455,10 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) kfree(file->private_data); kfree(file->private_data); file->private_data = NULL; file->private_data = NULL; /* 2 is a special value indicating that there are no more direntries */ /* 2 is a special value indicating that there are no more direntries */ file->f_pos = 2; ctx->pos = 2; return 0; return 0; } } static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence) { return generic_file_llseek(file, offset, whence); } /* Free saved readdir() state when the directory is closed */ /* Free saved readdir() state when the directory is closed */ static int ubifs_dir_release(struct inode *dir, struct file *file) static int ubifs_dir_release(struct inode *dir, struct file *file) { { Loading Loading @@ -1201,10 +1176,10 @@ const struct inode_operations ubifs_dir_inode_operations = { }; }; const struct file_operations ubifs_dir_operations = { const struct file_operations ubifs_dir_operations = { .llseek = ubifs_dir_llseek, .llseek = generic_file_llseek, .release = ubifs_dir_release, .release = ubifs_dir_release, .read = generic_read_dir, .read = generic_read_dir, .readdir = ubifs_readdir, .iterate = ubifs_readdir, .fsync = ubifs_fsync, .fsync = ubifs_fsync, .unlocked_ioctl = ubifs_ioctl, .unlocked_ioctl = ubifs_ioctl, #ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT Loading Loading
fs/ubifs/dir.c +16 −41 Original line number Original line Diff line number Diff line Loading @@ -346,19 +346,18 @@ static unsigned int vfs_dent_type(uint8_t type) * This means that UBIFS cannot support NFS which requires full * This means that UBIFS cannot support NFS which requires full * 'seekdir()'/'telldir()' support. * 'seekdir()'/'telldir()' support. */ */ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) static int ubifs_readdir(struct file *file, struct dir_context *ctx) { { int err, over = 0; int err; loff_t pos = file->f_pos; struct qstr nm; struct qstr nm; union ubifs_key key; union ubifs_key key; struct ubifs_dent_node *dent; struct ubifs_dent_node *dent; struct inode *dir = file_inode(file); struct inode *dir = file_inode(file); struct ubifs_info *c = dir->i_sb->s_fs_info; struct ubifs_info *c = dir->i_sb->s_fs_info; dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, pos); dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos); if (pos > UBIFS_S_KEY_HASH_MASK || pos == 2) if (ctx->pos > UBIFS_S_KEY_HASH_MASK || ctx->pos == 2) /* /* * The directory was seek'ed to a senseless position or there * The directory was seek'ed to a senseless position or there * are no more entries. * are no more entries. Loading @@ -384,19 +383,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) file->f_version = 1; file->f_version = 1; /* File positions 0 and 1 correspond to "." and ".." */ /* File positions 0 and 1 correspond to "." and ".." */ if (pos == 0) { if (ctx->pos < 2) { ubifs_assert(!file->private_data); over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR); if (over) return 0; file->f_pos = pos = 1; } if (pos == 1) { ubifs_assert(!file->private_data); ubifs_assert(!file->private_data); over = filldir(dirent, "..", 2, 1, if (!dir_emit_dots(file, ctx)) parent_ino(file->f_path.dentry), DT_DIR); if (over) return 0; return 0; /* Find the first entry in TNC and save it */ /* Find the first entry in TNC and save it */ Loading @@ -408,7 +397,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) goto out; goto out; } } file->f_pos = pos = key_hash_flash(c, &dent->key); ctx->pos = key_hash_flash(c, &dent->key); file->private_data = dent; file->private_data = dent; } } Loading @@ -416,16 +405,16 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) if (!dent) { if (!dent) { /* /* * The directory was seek'ed to and is now readdir'ed. * The directory was seek'ed to and is now readdir'ed. * Find the entry corresponding to @pos or the closest one. * Find the entry corresponding to @ctx->pos or the closest one. */ */ dent_key_init_hash(c, &key, dir->i_ino, pos); dent_key_init_hash(c, &key, dir->i_ino, ctx->pos); nm.name = NULL; nm.name = NULL; dent = ubifs_tnc_next_ent(c, &key, &nm); dent = ubifs_tnc_next_ent(c, &key, &nm); if (IS_ERR(dent)) { if (IS_ERR(dent)) { err = PTR_ERR(dent); err = PTR_ERR(dent); goto out; goto out; } } file->f_pos = pos = key_hash_flash(c, &dent->key); ctx->pos = key_hash_flash(c, &dent->key); file->private_data = dent; file->private_data = dent; } } Loading @@ -437,10 +426,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) ubifs_inode(dir)->creat_sqnum); ubifs_inode(dir)->creat_sqnum); nm.len = le16_to_cpu(dent->nlen); nm.len = le16_to_cpu(dent->nlen); over = filldir(dirent, dent->name, nm.len, pos, if (!dir_emit(ctx, dent->name, nm.len, le64_to_cpu(dent->inum), le64_to_cpu(dent->inum), vfs_dent_type(dent->type)); vfs_dent_type(dent->type))) if (over) return 0; return 0; /* Switch to the next entry */ /* Switch to the next entry */ Loading @@ -453,17 +441,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) } } kfree(file->private_data); kfree(file->private_data); file->f_pos = pos = key_hash_flash(c, &dent->key); ctx->pos = key_hash_flash(c, &dent->key); file->private_data = dent; file->private_data = dent; cond_resched(); 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: out: Loading @@ -475,15 +455,10 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) kfree(file->private_data); kfree(file->private_data); file->private_data = NULL; file->private_data = NULL; /* 2 is a special value indicating that there are no more direntries */ /* 2 is a special value indicating that there are no more direntries */ file->f_pos = 2; ctx->pos = 2; return 0; return 0; } } static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence) { return generic_file_llseek(file, offset, whence); } /* Free saved readdir() state when the directory is closed */ /* Free saved readdir() state when the directory is closed */ static int ubifs_dir_release(struct inode *dir, struct file *file) static int ubifs_dir_release(struct inode *dir, struct file *file) { { Loading Loading @@ -1201,10 +1176,10 @@ const struct inode_operations ubifs_dir_inode_operations = { }; }; const struct file_operations ubifs_dir_operations = { const struct file_operations ubifs_dir_operations = { .llseek = ubifs_dir_llseek, .llseek = generic_file_llseek, .release = ubifs_dir_release, .release = ubifs_dir_release, .read = generic_read_dir, .read = generic_read_dir, .readdir = ubifs_readdir, .iterate = ubifs_readdir, .fsync = ubifs_fsync, .fsync = ubifs_fsync, .unlocked_ioctl = ubifs_ioctl, .unlocked_ioctl = ubifs_ioctl, #ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT Loading