generic: add preliminary 3.19 support
[openwrt/staging/wigyori.git] / target / linux / generic / patches-3.19 / 503-yaffs-3.12-convert-readdir-to-iterate.patch
1 --- a/fs/yaffs2/yaffs_vfs.c
2 +++ b/fs/yaffs2/yaffs_vfs.c
3 @@ -1701,6 +1701,110 @@ static void yaffs_remove_obj_callback(st
4
5 /*-----------------------------------------------------------------*/
6
7 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
8 +static int yaffs_readdir(struct file *file, struct dir_context *ctx)
9 +{
10 + struct yaffs_obj *obj;
11 + struct yaffs_dev *dev;
12 + struct yaffs_search_context *sc;
13 + struct inode *inode = file->f_dentry->d_inode;
14 + unsigned long offset, curoffs;
15 + struct yaffs_obj *l;
16 + int ret_val = 0;
17 +
18 + char name[YAFFS_MAX_NAME_LENGTH + 1];
19 +
20 + obj = yaffs_dentry_to_obj(file->f_dentry);
21 + dev = obj->my_dev;
22 +
23 + yaffs_gross_lock(dev);
24 +
25 + yaffs_dev_to_lc(dev)->readdir_process = current;
26 +
27 + offset = ctx->pos;
28 +
29 + sc = yaffs_new_search(obj);
30 + if (!sc) {
31 + ret_val = -ENOMEM;
32 + goto out;
33 + }
34 +
35 + yaffs_trace(YAFFS_TRACE_OS,
36 + "yaffs_readdir: starting at %d", (int)offset);
37 +
38 + if (offset == 0) {
39 + yaffs_trace(YAFFS_TRACE_OS,
40 + "yaffs_readdir: entry . ino %d",
41 + (int)inode->i_ino);
42 + yaffs_gross_unlock(dev);
43 + if (!dir_emit_dot(file, ctx)) {
44 + yaffs_gross_lock(dev);
45 + goto out;
46 + }
47 + yaffs_gross_lock(dev);
48 + offset++;
49 + ctx->pos++;
50 + }
51 + if (offset == 1) {
52 + yaffs_trace(YAFFS_TRACE_OS,
53 + "yaffs_readdir: entry .. ino %d",
54 + (int)file->f_dentry->d_parent->d_inode->i_ino);
55 + yaffs_gross_unlock(dev);
56 + if (!dir_emit_dotdot(file, ctx)) {
57 + yaffs_gross_lock(dev);
58 + goto out;
59 + }
60 + yaffs_gross_lock(dev);
61 + offset++;
62 + ctx->pos++;
63 + }
64 +
65 + curoffs = 1;
66 +
67 + /* If the directory has changed since the open or last call to
68 + readdir, rewind to after the 2 canned entries. */
69 + if (file->f_version != inode->i_version) {
70 + offset = 2;
71 + ctx->pos = offset;
72 + file->f_version = inode->i_version;
73 + }
74 +
75 + while (sc->next_return) {
76 + curoffs++;
77 + l = sc->next_return;
78 + if (curoffs >= offset) {
79 + int this_inode = yaffs_get_obj_inode(l);
80 + int this_type = yaffs_get_obj_type(l);
81 +
82 + yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
83 + yaffs_trace(YAFFS_TRACE_OS,
84 + "yaffs_readdir: %s inode %d",
85 + name, yaffs_get_obj_inode(l));
86 +
87 + yaffs_gross_unlock(dev);
88 +
89 + if (!dir_emit(ctx, name, strlen(name),
90 + this_inode, this_type) < 0) {
91 + yaffs_gross_lock(dev);
92 + goto out;
93 + }
94 +
95 + yaffs_gross_lock(dev);
96 +
97 + offset++;
98 + ctx->pos++;
99 + }
100 + yaffs_search_advance(sc);
101 + }
102 +
103 +out:
104 + yaffs_search_end(sc);
105 + yaffs_dev_to_lc(dev)->readdir_process = NULL;
106 + yaffs_gross_unlock(dev);
107 +
108 + return ret_val;
109 +}
110 +#else
111 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
112 {
113 struct yaffs_obj *obj;
114 @@ -1807,10 +1911,15 @@ out:
115
116 return ret_val;
117 }
118 +#endif
119
120 static const struct file_operations yaffs_dir_operations = {
121 .read = generic_read_dir,
122 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
123 + .iterate = yaffs_readdir,
124 +#else
125 .readdir = yaffs_readdir,
126 +#endif
127 .fsync = yaffs_sync_object,
128 .llseek = generic_file_llseek,
129 };