diff options
Diffstat (limited to 'target/linux/generic/patches-3.12/503-yaffs-3.12-convert-readdir-to-iterate.patch')
-rw-r--r-- | target/linux/generic/patches-3.12/503-yaffs-3.12-convert-readdir-to-iterate.patch | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/target/linux/generic/patches-3.12/503-yaffs-3.12-convert-readdir-to-iterate.patch b/target/linux/generic/patches-3.12/503-yaffs-3.12-convert-readdir-to-iterate.patch new file mode 100644 index 0000000000..586c141e0a --- /dev/null +++ b/target/linux/generic/patches-3.12/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, + }; |