summaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-02 09:28:37 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-02 09:28:37 -0700
commit63580e51bb3e7ec459501165884e5f815a7a9322 (patch)
tree2130de984dda95996bc7922734feb465a13fca70 /fs/ubifs
parent7747bd4bceb3079572695d3942294a6c7b265557 (diff)
parentac6614b76478e68173ccf7ad4e9e98035cc9c21d (diff)
downloadop-kernel-dev-63580e51bb3e7ec459501165884e5f815a7a9322.zip
op-kernel-dev-63580e51bb3e7ec459501165884e5f815a7a9322.tar.gz
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull VFS patches (part 1) from Al Viro: "The major change in this pile is ->readdir() replacement with ->iterate(), dealing with ->f_pos races in ->readdir() instances for good. There's a lot more, but I'd prefer to split the pull request into several stages and this is the first obvious cutoff point." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (67 commits) [readdir] constify ->actor [readdir] ->readdir() is gone [readdir] convert ecryptfs [readdir] convert coda [readdir] convert ocfs2 [readdir] convert fatfs [readdir] convert xfs [readdir] convert btrfs [readdir] convert hostfs [readdir] convert afs [readdir] convert ncpfs [readdir] convert hfsplus [readdir] convert hfs [readdir] convert befs [readdir] convert cifs [readdir] convert freevxfs [readdir] convert fuse [readdir] convert hpfs reiserfs: switch reiserfs_readdir_dentry to inode reiserfs: is_privroot_deh() needs only directory inode, actually ...
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/dir.c57
1 files changed, 16 insertions, 41 deletions
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 605af51..6b4947f 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -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
OpenPOWER on IntegriCloud