|
@@ -346,19 +346,18 @@ static unsigned int vfs_dent_type(uint8_t type)
|
|
|
* This means that UBIFS cannot support NFS which requires full
|
|
|
* '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;
|
|
|
- loff_t pos = file->f_pos;
|
|
|
+ int err;
|
|
|
struct qstr nm;
|
|
|
union ubifs_key key;
|
|
|
struct ubifs_dent_node *dent;
|
|
|
struct inode *dir = file_inode(file);
|
|
|
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
|
|
|
* are no more entries.
|
|
@@ -384,19 +383,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
|
|
|
file->f_version = 1;
|
|
|
|
|
|
/* File positions 0 and 1 correspond to "." and ".." */
|
|
|
- if (pos == 0) {
|
|
|
- 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) {
|
|
|
+ if (ctx->pos < 2) {
|
|
|
ubifs_assert(!file->private_data);
|
|
|
- over = filldir(dirent, "..", 2, 1,
|
|
|
- parent_ino(file->f_path.dentry), DT_DIR);
|
|
|
- if (over)
|
|
|
+ if (!dir_emit_dots(file, ctx))
|
|
|
return 0;
|
|
|
|
|
|
/* Find the first entry in TNC and save it */
|
|
@@ -408,7 +397,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- file->f_pos = pos = key_hash_flash(c, &dent->key);
|
|
|
+ ctx->pos = key_hash_flash(c, &dent->key);
|
|
|
file->private_data = dent;
|
|
|
}
|
|
|
|
|
@@ -416,16 +405,16 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
|
|
|
if (!dent) {
|
|
|
/*
|
|
|
* 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;
|
|
|
dent = ubifs_tnc_next_ent(c, &key, &nm);
|
|
|
if (IS_ERR(dent)) {
|
|
|
err = PTR_ERR(dent);
|
|
|
goto out;
|
|
|
}
|
|
|
- file->f_pos = pos = key_hash_flash(c, &dent->key);
|
|
|
+ ctx->pos = key_hash_flash(c, &dent->key);
|
|
|
file->private_data = dent;
|
|
|
}
|
|
|
|
|
@@ -437,10 +426,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
|
|
|
ubifs_inode(dir)->creat_sqnum);
|
|
|
|
|
|
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),
|
|
|
- vfs_dent_type(dent->type));
|
|
|
- if (over)
|
|
|
+ vfs_dent_type(dent->type)))
|
|
|
return 0;
|
|
|
|
|
|
/* Switch to the next entry */
|
|
@@ -453,17 +441,9 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
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:
|
|
@@ -475,15 +455,10 @@ out:
|
|
|
kfree(file->private_data);
|
|
|
file->private_data = NULL;
|
|
|
/* 2 is a special value indicating that there are no more direntries */
|
|
|
- file->f_pos = 2;
|
|
|
+ ctx->pos = 2;
|
|
|
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 */
|
|
|
static int ubifs_dir_release(struct inode *dir, struct file *file)
|
|
|
{
|
|
@@ -1201,10 +1176,10 @@ const struct inode_operations ubifs_dir_inode_operations = {
|
|
|
};
|
|
|
|
|
|
const struct file_operations ubifs_dir_operations = {
|
|
|
- .llseek = ubifs_dir_llseek,
|
|
|
+ .llseek = generic_file_llseek,
|
|
|
.release = ubifs_dir_release,
|
|
|
.read = generic_read_dir,
|
|
|
- .readdir = ubifs_readdir,
|
|
|
+ .iterate = ubifs_readdir,
|
|
|
.fsync = ubifs_fsync,
|
|
|
.unlocked_ioctl = ubifs_ioctl,
|
|
|
#ifdef CONFIG_COMPAT
|