aboutsummaryrefslogtreecommitdiff
blob: c2ca77147f70f71bad9f8302b11aecc9020c7a90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
From da6a877ec27753ce11499d1bde68d392f90179c4 Mon Sep 17 00:00:00 2001
From: James Simmons <uja.ornl@gmail.com>
Date: Mon, 20 Jan 2014 21:23:00 -0500
Subject: [PATCH 11/12] LU-3974 llite: use new struct dir_context

The readdir and nfs code over time has added more
parameters to be passed to be processed. For the 3.11
kernel a new struct dir_context was introduced to
minimize the impact of future expansion. This patch
addresses this change.

Conflicts:
	lustre/llite/dir.c

Signed-off-by: James Simmons <uja.ornl@gmail.com>
Change-Id: Ib42bf8cb06635a2a64e63b294d79e66ac82a1a5b
Signed-off-by: Alexey Shvetsov <alexxy@gentoo.org>
---
 lustre/autoconf/lustre-core.m4 | 20 +++++++++++++
 lustre/llite/dir.c             | 65 ++++++++++++++++++++++++++++++++++--------
 lustre/llite/llite_internal.h  | 14 +++++++--
 lustre/llite/llite_nfs.c       | 17 +++++++----
 4 files changed, 96 insertions(+), 20 deletions(-)

diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4
index e6207c9..f44a277 100644
--- a/lustre/autoconf/lustre-core.m4
+++ b/lustre/autoconf/lustre-core.m4
@@ -1349,6 +1349,25 @@ LB_LINUX_TRY_COMPILE([
 ])
 
 #
+# 3.11 readdir now takes the new struct dir_context
+#
+AC_DEFUN([LC_HAVE_DIR_CONTEXT],
+[AC_MSG_CHECKING([if dir_context exist])
+LB_LINUX_TRY_COMPILE([
+	#include <linux/fs.h>
+],[
+	struct dir_context ctx;
+
+	ctx.pos = 0;
+],[
+	AC_DEFINE(HAVE_DIR_CONTEXT, 1, [dir_context exist])
+	AC_MSG_RESULT([yes])
+],[
+	AC_MSG_RESULT([no])
+])
+])
+
+#
 # 3.11 dentry_operations.d_compare() taken 5 arguments.
 #
 AC_DEFUN([LC_D_COMPARE_5ARGS],
@@ -1523,6 +1542,7 @@ AC_DEFUN([LC_PROG_LINUX],
 	 LC_BLKDEV_RELEASE_RETURN_INT
 
 	 # 3.11
+	 LC_HAVE_DIR_CONTEXT
 	 LC_D_COMPARE_5ARGS
 	 LC_HAVE_DCOUNT
 
diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c
index dc5d623..5009934 100644
--- a/lustre/llite/dir.c
+++ b/lustre/llite/dir.c
@@ -195,9 +195,27 @@ struct lu_dirent *ll_dir_entry_next(struct inode *dir,
 	return entry;
 }
 
+void ll_dir_entry_end(struct inode *dir, struct md_op_data *op_data,
+		      struct lu_dirent *ent)
+{
+	struct lu_dirent *entry;
+	struct md_callback cb_op;
+
+	cb_op.md_blocking_ast = ll_md_blocking_ast;
+	op_data->op_cli_flags = CLI_READENT_END;
+	md_read_entry(ll_i2mdexp(dir), op_data, &cb_op, &entry);
+	return;
+}
+
+#ifdef HAVE_DIR_CONTEXT
+int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
+		struct dir_context *ctx)
+{
+#else
 int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
 		void *cookie, filldir_t filldir)
 {
+#endif
 	struct ll_sb_info	*sbi = ll_i2sbi(inode);
 	struct ll_dir_chain	chain;
 	struct lu_dirent	*ent;
@@ -241,12 +259,17 @@ int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
 		fid_le_to_cpu(&fid, &ent->lde_fid);
 		ino = cl_fid_build_ino(&fid, api32);
 		type = ll_dirent_type_get(ent);
+
+#ifdef HAVE_DIR_CONTEXT
 		/* For 'll_nfs_get_name_filldir()', it will try
 		 * to access the 'ent' through its 'lde_name',
 		 * so the parameter 'name' for 'filldir()' must
 		 * be part of the 'ent'. */
+		done = !dir_emit(ctx, ent->lde_name, namelen, ino, type);
+#else
 		done = filldir(cookie, ent->lde_name, namelen, lhash,
 			       ino, type);
+#endif
 		if (done) {
 			if (op_data->op_hash_offset != MDS_DIR_END_OFF)
 				op_data->op_hash_offset = last_hash;
@@ -268,7 +291,11 @@ int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
 	RETURN(rc);
 }
 
+#ifdef HAVE_DIR_CONTEXT
+static int ll_iterate(struct file *filp, struct dir_context *ctx)
+#else
 static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
+#endif
 {
 	struct inode		*inode	= filp->f_dentry->d_inode;
 	struct ll_file_data	*lfd	= LUSTRE_FPRIVATE(filp);
@@ -305,22 +332,32 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
 
 	op_data->op_hash_offset = pos;
 	op_data->op_max_pages = sbi->ll_md_brw_size >> PAGE_CACHE_SHIFT;
+#ifdef HAVE_DIR_CONTEXT
+	ctx->pos = pos;
+	rc = ll_dir_read(inode, op_data, ctx);
+	pos = ctx->pos;
+#else
 	rc = ll_dir_read(inode, op_data, cookie, filldir);
+#endif
 	if (lfd != NULL)
 		lfd->lfd_pos = op_data->op_hash_offset;
 
 	if (pos == MDS_DIR_END_OFF) {
 		if (api32)
-			filp->f_pos = LL_DIR_END_OFF_32BIT;
+			pos = LL_DIR_END_OFF_32BIT;
 		else
-			filp->f_pos = LL_DIR_END_OFF;
+			pos = LL_DIR_END_OFF;
 	} else {
 		if (api32 && hash64)
-			filp->f_pos = op_data->op_hash_offset >> 32;
+			pos = op_data->op_hash_offset >> 32;
 		else
-			filp->f_pos = op_data->op_hash_offset;
+			pos = op_data->op_hash_offset;
 	}
-
+#ifdef HAVE_DIR_CONTEXT
+	ctx->pos = pos;
+#else
+	filp->f_pos = pos;
+#endif
 	ll_finish_md_op_data(op_data);
 	filp->f_version = inode->i_version;
 #ifdef HAVE_TOUCH_ATIME_1ARG
@@ -1702,11 +1739,15 @@ int ll_dir_release(struct inode *inode, struct file *file)
 }
 
 struct file_operations ll_dir_operations = {
-        .llseek   = ll_dir_seek,
-        .open     = ll_dir_open,
-        .release  = ll_dir_release,
-        .read     = generic_read_dir,
-        .readdir  = ll_readdir,
-        .unlocked_ioctl   = ll_dir_ioctl,
-        .fsync    = ll_fsync,
+	.llseek		= ll_dir_seek,
+	.open		= ll_dir_open,
+	.release	= ll_dir_release,
+	.read		= generic_read_dir,
+#ifdef HAVE_DIR_CONTEXT
+	.iterate	= ll_iterate,
+#else
+	.readdir	= ll_readdir,
+#endif
+	.unlocked_ioctl	= ll_dir_ioctl,
+	.fsync		= ll_fsync,
 };
diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h
index 92b278e..c477b4c 100644
--- a/lustre/llite/llite_internal.h
+++ b/lustre/llite/llite_internal.h
@@ -91,9 +91,12 @@ extern struct file_operations ll_pgcache_seq_fops;
 #define REMOTE_PERM_HASHSIZE 16
 
 struct ll_getname_data {
-        char            *lgd_name;      /* points to a buffer with NAME_MAX+1 size */
-        struct lu_fid    lgd_fid;       /* target fid we are looking for */
-        int              lgd_found;     /* inode matched? */
+#ifdef HAVE_DIR_CONTEXT
+	struct dir_context	ctx;
+#endif
+	char		*lgd_name;	/* points to a buffer with NAME_MAX+1 size */
+	struct lu_fid	lgd_fid;	/* target fid we are looking for */
+	int		lgd_found;	/* inode matched? */
 };
 
 /* llite setxid/access permission for user on remote client */
@@ -719,8 +722,13 @@ static void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count) {}
 /* llite/dir.c */
 extern struct file_operations ll_dir_operations;
 extern struct inode_operations ll_dir_inode_operations;
+#ifdef HAVE_DIR_CONTEXT
+int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
+		struct dir_context *ctx);
+#else
 int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
 		void *cookie, filldir_t filldir);
+#endif
 int ll_get_mdt_idx(struct inode *inode);
 
 struct lu_dirent *ll_dir_entry_start(struct inode *dir,
diff --git a/lustre/llite/llite_nfs.c b/lustre/llite/llite_nfs.c
index 68616e9..faad453 100644
--- a/lustre/llite/llite_nfs.c
+++ b/lustre/llite/llite_nfs.c
@@ -236,7 +236,14 @@ static int ll_get_name(struct dentry *dentry, char *name,
                        struct dentry *child)
 {
 	struct inode *dir = dentry->d_inode;
-	struct ll_getname_data lgd;
+	struct ll_getname_data lgd = {
+		.lgd_name	= name,
+		.lgd_fid	= ll_i2info(child->d_inode)->lli_fid,
+#ifdef HAVE_DIR_CONTEXT
+		.ctx.actor	= ll_nfs_get_name_filldir,
+#endif
+		.lgd_found = 0,
+	};
 	struct md_op_data *op_data;
 	int rc;
 	ENTRY;
@@ -247,10 +254,6 @@ static int ll_get_name(struct dentry *dentry, char *name,
         if (!dir->i_fop)
                 GOTO(out, rc = -EINVAL);
 
-        lgd.lgd_name = name;
-        lgd.lgd_fid = ll_i2info(child->d_inode)->lli_fid;
-        lgd.lgd_found = 0;
-
 	op_data = ll_prep_md_op_data(NULL, dir, dir, NULL, 0, 0,
 				     LUSTRE_OPC_ANY, dir);
 	if (IS_ERR(op_data))
@@ -260,7 +263,11 @@ static int ll_get_name(struct dentry *dentry, char *name,
 	op_data->op_max_pages =
 		ll_i2sbi(dir)->ll_md_brw_size >> PAGE_CACHE_SHIFT;
 	mutex_lock(&dir->i_mutex);
+#ifdef HAVE_DIR_CONTEXT
+	rc = ll_dir_read(dir, op_data, &lgd.ctx);
+#else
 	rc = ll_dir_read(dir, op_data, &lgd, ll_nfs_get_name_filldir);
+#endif
 	mutex_unlock(&dir->i_mutex);
 	ll_finish_md_op_data(op_data);
 	if (!rc && !lgd.lgd_found)
-- 
1.8.5.3