summaryrefslogtreecommitdiffstats
path: root/target/linux/generic/patches-3.18/503-yaffs-3.12-convert-readdir-to-iterate.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/patches-3.18/503-yaffs-3.12-convert-readdir-to-iterate.patch')
-rw-r--r--target/linux/generic/patches-3.18/503-yaffs-3.12-convert-readdir-to-iterate.patch129
1 files changed, 129 insertions, 0 deletions
diff --git a/target/linux/generic/patches-3.18/503-yaffs-3.12-convert-readdir-to-iterate.patch b/target/linux/generic/patches-3.18/503-yaffs-3.12-convert-readdir-to-iterate.patch
new file mode 100644
index 0000000000..586c141e0a
--- /dev/null
+++ b/target/linux/generic/patches-3.18/503-yaffs-3.12-convert-readdir-to-iterate.patch
@@ -0,0 +1,129 @@
+--- a/fs/yaffs2/yaffs_vfs.c
++++ b/fs/yaffs2/yaffs_vfs.c
+@@ -1701,6 +1701,110 @@ static void yaffs_remove_obj_callback(st
+
+ /*-----------------------------------------------------------------*/
+
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
++static int yaffs_readdir(struct file *file, struct dir_context *ctx)
++{
++ struct yaffs_obj *obj;
++ struct yaffs_dev *dev;
++ struct yaffs_search_context *sc;
++ struct inode *inode = file->f_dentry->d_inode;
++ unsigned long offset, curoffs;
++ struct yaffs_obj *l;
++ int ret_val = 0;
++
++ char name[YAFFS_MAX_NAME_LENGTH + 1];
++
++ obj = yaffs_dentry_to_obj(file->f_dentry);
++ dev = obj->my_dev;
++
++ yaffs_gross_lock(dev);
++
++ yaffs_dev_to_lc(dev)->readdir_process = current;
++
++ offset = ctx->pos;
++
++ sc = yaffs_new_search(obj);
++ if (!sc) {
++ ret_val = -ENOMEM;
++ goto out;
++ }
++
++ yaffs_trace(YAFFS_TRACE_OS,
++ "yaffs_readdir: starting at %d", (int)offset);
++
++ if (offset == 0) {
++ yaffs_trace(YAFFS_TRACE_OS,
++ "yaffs_readdir: entry . ino %d",
++ (int)inode->i_ino);
++ yaffs_gross_unlock(dev);
++ if (!dir_emit_dot(file, ctx)) {
++ yaffs_gross_lock(dev);
++ goto out;
++ }
++ yaffs_gross_lock(dev);
++ offset++;
++ ctx->pos++;
++ }
++ if (offset == 1) {
++ yaffs_trace(YAFFS_TRACE_OS,
++ "yaffs_readdir: entry .. ino %d",
++ (int)file->f_dentry->d_parent->d_inode->i_ino);
++ yaffs_gross_unlock(dev);
++ if (!dir_emit_dotdot(file, ctx)) {
++ yaffs_gross_lock(dev);
++ goto out;
++ }
++ yaffs_gross_lock(dev);
++ offset++;
++ ctx->pos++;
++ }
++
++ curoffs = 1;
++
++ /* If the directory has changed since the open or last call to
++ readdir, rewind to after the 2 canned entries. */
++ if (file->f_version != inode->i_version) {
++ offset = 2;
++ ctx->pos = offset;
++ file->f_version = inode->i_version;
++ }
++
++ while (sc->next_return) {
++ curoffs++;
++ l = sc->next_return;
++ if (curoffs >= offset) {
++ int this_inode = yaffs_get_obj_inode(l);
++ int this_type = yaffs_get_obj_type(l);
++
++ yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
++ yaffs_trace(YAFFS_TRACE_OS,
++ "yaffs_readdir: %s inode %d",
++ name, yaffs_get_obj_inode(l));
++
++ yaffs_gross_unlock(dev);
++
++ if (!dir_emit(ctx, name, strlen(name),
++ this_inode, this_type) < 0) {
++ yaffs_gross_lock(dev);
++ goto out;
++ }
++
++ yaffs_gross_lock(dev);
++
++ offset++;
++ ctx->pos++;
++ }
++ yaffs_search_advance(sc);
++ }
++
++out:
++ yaffs_search_end(sc);
++ yaffs_dev_to_lc(dev)->readdir_process = NULL;
++ yaffs_gross_unlock(dev);
++
++ return ret_val;
++}
++#else
+ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
+ {
+ struct yaffs_obj *obj;
+@@ -1807,10 +1911,15 @@ out:
+
+ return ret_val;
+ }
++#endif
+
+ static const struct file_operations yaffs_dir_operations = {
+ .read = generic_read_dir,
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
++ .iterate = yaffs_readdir,
++#else
+ .readdir = yaffs_readdir,
++#endif
+ .fsync = yaffs_sync_object,
+ .llseek = generic_file_llseek,
+ };