From: NeilBrown <neilb@suse.com>
Subject: provide local version of iterate_dir()

iterate_dir() calls security_file_permission(), but osd-ldiskfs
doesn't have a convenient way to initialize ->f_security.
So provide a local version which doesn't bother with security.

Signed-off-by: NeilBrown <neilb@suse.com>

---
 lustre/osd-ldiskfs/osd_handler.c |   41 +++++++++++++++++++++++++++++++++++++--
 lustre/osd-ldiskfs/osd_scrub.c   |    5 +++-
 2 files changed, 43 insertions(+), 3 deletions(-)

--- a/lustre/osd-ldiskfs/osd_handler.c
+++ b/lustre/osd-ldiskfs/osd_handler.c
@@ -862,6 +862,43 @@ static int osd_stripe_dir_filldir(void *
 	return 1;
 }
 
+#ifdef HAVE_DIR_CONTEXT
+int iterate_dir_lustre(struct file *file, struct dir_context *ctx)
+{
+	struct inode *inode = file_inode(file);
+	bool shared = false;
+	int res = -ENOTDIR;
+	if (file->f_op->iterate_shared)
+		shared = true;
+	else if (!file->f_op->iterate)
+		goto out;
+
+	if (shared) {
+		inode_lock_shared(inode);
+	} else {
+		res = down_write_killable(&inode->i_rwsem);
+		if (res)
+			goto out;
+	}
+
+	res = -ENOENT;
+	if (!IS_DEADDIR(inode)) {
+		ctx->pos = file->f_pos;
+		if (shared)
+			res = file->f_op->iterate_shared(file, ctx);
+		else
+			res = file->f_op->iterate(file, ctx);
+		file->f_pos = ctx->pos;
+	}
+	if (shared)
+		inode_unlock_shared(inode);
+	else
+		inode_unlock(inode);
+out:
+	return res;
+}
+#endif
+
 /* When lookup item under striped directory, we need to locate the master
  * MDT-object of the striped directory firstly, then the client will send
  * lookup (getattr_by_name) RPC to the MDT with some slave MDT-object's FID
@@ -962,7 +999,7 @@ again:
 	do {
 		oclb.oclb_items = 0;
 #ifdef HAVE_DIR_CONTEXT
-		rc = iterate_dir(filp, &oclb.ctx);
+		rc = iterate_dir_lustre(filp, &oclb.ctx);
 #else
 		inode_lock(file_inode(filp));
 		rc = fops->readdir(filp, &oclb, osd_stripe_dir_filldir);
@@ -6094,7 +6131,7 @@ static int osd_ldiskfs_it_fill(const str
 
 	filp->f_mode |= FMODE_NONOTIFY;
 #ifdef HAVE_DIR_CONTEXT
-	rc = iterate_dir(filp, &buf.ctx);
+	rc = iterate_dir_lustre(filp, &buf.ctx);
 #else
 	inode_lock(file_inode(filp));
 	rc = inode->i_fop->readdir(filp, &buf, osd_ldiskfs_filldir);
--- a/lustre/osd-ldiskfs/osd_scrub.c
+++ b/lustre/osd-ldiskfs/osd_scrub.c
@@ -2331,6 +2331,9 @@ out_put:
 	RETURN(rc);
 }
 
+#ifdef HAVE_DIR_CONTEXT
+int iterate_dir_lustre(struct file *file, struct dir_context *ctx);
+#endif
 static int
 osd_ios_general_scan(struct osd_thread_info *info, struct osd_device *dev,
 		     struct dentry *dentry, filldir_t filldir)
@@ -2362,7 +2365,7 @@ osd_ios_general_scan(struct osd_thread_i
 	do {
 		buf.oifb_items = 0;
 #ifdef HAVE_DIR_CONTEXT
-		rc = iterate_dir(filp, &buf.ctx);
+		rc = iterate_dir_lustre(filp, &buf.ctx);
 #else
 		inode_lock(file_inode(filp));
 		rc = fops->readdir(filp, &buf, filldir);
