f628f3d
diff -u -r nfs-ganesha-2.8.0/src/CMakeLists.txt nfs-ganesha-2.8.0.1/src/CMakeLists.txt
f628f3d
--- nfs-ganesha-2.8.0/src/CMakeLists.txt	2019-05-31 17:37:31.000000000 -0400
f628f3d
+++ nfs-ganesha-2.8.0.1/src/CMakeLists.txt	2019-06-07 18:00:00.000000000 -0400
f628f3d
@@ -39,7 +39,7 @@
f628f3d
 # Patch level is always ".0" for mainline (master).  It is blank for development.
f628f3d
 # When starting a stable maintenance branch, this becomes ".N"
f628f3d
 # where N is monotonically increasing starting at 1. Remember to include the "." !!
f628f3d
-set(GANESHA_PATCH_LEVEL .0)
f628f3d
+set(GANESHA_PATCH_LEVEL .0.1)
f628f3d
 
f628f3d
 # Extra version is for naming development/RC.  It is blank in master/stable branches
f628f3d
 # so it can be available to end-users to name local variants/versions
f628f3d
diff -u -r nfs-ganesha-2.8.0/src/config_parsing/config_parsing.c nfs-ganesha-2.8.0.1/src/config_parsing/config_parsing.c
f628f3d
--- nfs-ganesha-2.8.0/src/config_parsing/config_parsing.c	2019-05-31 17:37:31.000000000 -0400
f628f3d
+++ nfs-ganesha-2.8.0.1/src/config_parsing/config_parsing.c	2019-06-07 18:00:00.000000000 -0400
f628f3d
@@ -984,7 +984,7 @@
f628f3d
 	void *param_addr;
f628f3d
 	struct config_node *node, *term_node, *next_node = NULL;
f628f3d
 	struct glist_head *ns;
f628f3d
-	int errors = 0;
f628f3d
+	int errors = 0, prev_errors = err_type->errors;
f628f3d
 
f628f3d
 	for (item = params; item->name != NULL; item++) {
f628f3d
 		uint64_t num64;
f628f3d
@@ -1259,6 +1259,16 @@
f628f3d
 			node = next_node;
f628f3d
 		}
f628f3d
 	}
f628f3d
+
f628f3d
+	/* Check for any errors in parsing params.
f628f3d
+	 * It will set to default value if parsing fails.
f628f3d
+	 * For params like Export_Id if parsing fails, we
f628f3d
+	 * will end up setting it to 1, which could cause issue
f628f3d
+	 * if we set it to 1 for multiple exports.
f628f3d
+	 */
f628f3d
+	if (err_type->errors > prev_errors)
f628f3d
+		errors = err_type->errors;
f628f3d
+
f628f3d
 	if (relax)
f628f3d
 		return errors;
f628f3d
 
f628f3d
diff -u -r nfs-ganesha-2.8.0/src/FSAL/FSAL_CEPH/handle.c nfs-ganesha-2.8.0.1/src/FSAL/FSAL_CEPH/handle.c
f628f3d
--- nfs-ganesha-2.8.0/src/FSAL/FSAL_CEPH/handle.c	2019-05-31 17:37:31.000000000 -0400
f628f3d
+++ nfs-ganesha-2.8.0.1/src/FSAL/FSAL_CEPH/handle.c	2019-06-07 18:00:00.000000000 -0400
f628f3d
@@ -222,6 +222,13 @@
f628f3d
 			/* skip . and .. */
f628f3d
 			if ((strcmp(de.d_name, ".") == 0)
f628f3d
 			    || (strcmp(de.d_name, "..") == 0)) {
f628f3d
+				/* Deref inode here as we reference inode in
f628f3d
+				 * libcephfs readdir_r_cb. The other inodes
f628f3d
+				 * gets deref in deconstruct_handle.
f628f3d
+				 */
f628f3d
+				if (i != NULL)
f628f3d
+					ceph_ll_put(export->cmount, i);
f628f3d
+
f628f3d
 				continue;
f628f3d
 			}
f628f3d
 
f628f3d
@@ -233,6 +240,8 @@
f628f3d
 			rc = ceph_fsal_get_sec_label(obj, &attrs);
f628f3d
 			if (rc < 0) {
f628f3d
 				fsal_status = ceph2fsal_error(rc);
f628f3d
+				if (i != NULL)
f628f3d
+					ceph_ll_put(export->cmount, i);
f628f3d
 				goto closedir;
f628f3d
 			}
f628f3d
 
f628f3d
diff -u -r nfs-ganesha-2.8.0/src/FSAL/FSAL_VFS/vfs/main-c.in.cmake nfs-ganesha-2.8.0.1/src/FSAL/FSAL_VFS/vfs/main-c.in.cmake
f628f3d
--- nfs-ganesha-2.8.0/src/FSAL/FSAL_VFS/vfs/main-c.in.cmake	2019-05-31 17:37:31.000000000 -0400
f628f3d
+++ nfs-ganesha-2.8.0.1/src/FSAL/FSAL_VFS/vfs/main-c.in.cmake	2019-06-07 18:00:00.000000000 -0400
f628f3d
@@ -129,6 +129,7 @@
f628f3d
 {
f628f3d
 	struct vfs_fsal_module *vfs_module =
f628f3d
 	    container_of(vfs_fsal_module, struct vfs_fsal_module, module);
f628f3d
+	int prev_errors = err_type->errors;
f628f3d
 
f628f3d
 #ifdef F_OFD_GETLK
f628f3d
 	int fd, rc;
f628f3d
@@ -180,8 +181,15 @@
f628f3d
 				      vfs_module,
f628f3d
 				      true,
f628f3d
 				      err_type);
f628f3d
-	if (!config_error_is_harmless(err_type))
f628f3d
+
f628f3d
+	/* Check for actual errors in vfs_param parsing.
f628f3d
+	 * err_type could have errors from previous block
f628f3d
+	 * parsing also.
f628f3d
+	 */
f628f3d
+	if ((err_type->errors > prev_errors) &&
f628f3d
+	    !config_error_is_harmless(err_type))
f628f3d
 		return fsalstat(ERR_FSAL_INVAL, 0);
f628f3d
+
f628f3d
 	display_fsinfo(&vfs_module->module);
f628f3d
 	LogFullDebug(COMPONENT_FSAL,
f628f3d
 		     "Supported attributes constant = 0x%" PRIx64,
f628f3d
diff -u -r nfs-ganesha-2.8.0/src/FSAL/Stackable_FSALs/FSAL_MDCACHE/mdcache_helpers.c nfs-ganesha-2.8.0.1/src/FSAL/Stackable_FSALs/FSAL_MDCACHE/mdcache_helpers.c
f628f3d
--- nfs-ganesha-2.8.0/src/FSAL/Stackable_FSALs/FSAL_MDCACHE/mdcache_helpers.c	2019-05-31 17:37:31.000000000 -0400
f628f3d
+++ nfs-ganesha-2.8.0.1/src/FSAL/Stackable_FSALs/FSAL_MDCACHE/mdcache_helpers.c	2019-06-07 18:00:00.000000000 -0400
f628f3d
@@ -217,7 +217,29 @@
f628f3d
 }
f628f3d
 
f628f3d
 /**
f628f3d
+ * @brief Drop ref on remaining dirents in chunk
f628f3d
  *
f628f3d
+ * @note content_lock of parent dir must be held for WRITE
f628f3d
+ *
f628f3d
+ * @param[in]  dirent	First ref'd dirent
f628f3d
+ */
f628f3d
+static void mdc_unref_chunk(struct dir_chunk *chunk,
f628f3d
+			    mdcache_dir_entry_t *dirent)
f628f3d
+{
f628f3d
+	for (;
f628f3d
+	     dirent != NULL;
f628f3d
+	     dirent = glist_next_entry(&chunk->dirents,
f628f3d
+				       mdcache_dir_entry_t,
f628f3d
+				       chunk_list,
f628f3d
+				       &dirent->chunk_list)) {
f628f3d
+		if (dirent->entry) {
f628f3d
+			mdcache_put(dirent->entry);
f628f3d
+			dirent->entry = NULL;
f628f3d
+		}
f628f3d
+	}
f628f3d
+}
f628f3d
+
f628f3d
+/**
f628f3d
  * @brief Cleans up an entry so it can be reused
f628f3d
  *
f628f3d
  * @param[in]  entry     The cache entry to clean
f628f3d
@@ -403,17 +425,18 @@
f628f3d
 
f628f3d
 /* entry's content_lock must not be held, this function will
f628f3d
 get the content_lock in exclusive mode */
f628f3d
-void
f628f3d
+fsal_status_t
f628f3d
 mdc_get_parent(struct mdcache_fsal_export *export, mdcache_entry_t *entry,
f628f3d
 	       struct gsh_buffdesc *parent_out)
f628f3d
 {
f628f3d
 	struct fsal_obj_handle *sub_handle = NULL;
f628f3d
-	fsal_status_t status;
f628f3d
+	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
f628f3d
 
f628f3d
 	PTHREAD_RWLOCK_wrlock(&entry->content_lock);
f628f3d
 
f628f3d
 	if (entry->obj_handle.type != DIRECTORY) {
f628f3d
 		/* Parent pointer only for directories */
f628f3d
+		status.major = ERR_FSAL_INVAL;
f628f3d
 		goto out;
f628f3d
 	}
f628f3d
 
f628f3d
@@ -430,16 +453,26 @@
f628f3d
 			    entry->sub_handle, "..", &sub_handle, NULL)
f628f3d
 	       );
f628f3d
 
f628f3d
-	if (FSAL_IS_ERROR(status)) {
f628f3d
-		/* Top of filesystem */
f628f3d
-		goto copy_parent_out;
f628f3d
-	}
f628f3d
-
f628f3d
-	mdcache_free_fh(&entry->fsobj.fsdir.parent);
f628f3d
-	mdc_get_parent_handle(export, entry, sub_handle);
f628f3d
+	if (FSAL_IS_SUCCESS(status)) {
f628f3d
+		/* if we already had a parent handle, then we are
f628f3d
+		 * going to refresh it.
f628f3d
+		 */
f628f3d
+		mdcache_free_fh(&entry->fsobj.fsdir.parent);
f628f3d
+		mdc_get_parent_handle(export, entry, sub_handle);
f628f3d
+	} else if (entry->fsobj.fsdir.parent.len != 0) {
f628f3d
+		/* Lookup of (..) failed, but if we had a cached
f628f3d
+		 * parent handle then we will keep the same and
f628f3d
+		 * not fail this request for getting parent.
f628f3d
+		 */
f628f3d
+		LogDebug(COMPONENT_CACHE_INODE,
f628f3d
+			 "Lookup for (..) failed for entry: %p, but we have a "
f628f3d
+			 "cached parent handle so we will keep it", entry);
f628f3d
+		status.major = ERR_FSAL_NO_ERROR;
f628f3d
+	} else
f628f3d
+		goto out;
f628f3d
 
f628f3d
 copy_parent_out:
f628f3d
-	if (parent_out != NULL  && entry->fsobj.fsdir.parent.len != 0) {
f628f3d
+	if (parent_out != NULL) {
f628f3d
 		/* Copy the parent handle to parent_out */
f628f3d
 		mdcache_copy_fh(parent_out, &entry->fsobj.fsdir.parent);
f628f3d
 	}
f628f3d
@@ -453,6 +486,7 @@
f628f3d
 			    sub_handle->obj_ops->release(sub_handle)
f628f3d
 			   );
f628f3d
 	}
f628f3d
+	return status;
f628f3d
 }
f628f3d
 
f628f3d
 /**
f628f3d
@@ -1179,12 +1213,13 @@
f628f3d
 		LogFullDebugAlt(COMPONENT_NFS_READDIR, COMPONENT_CACHE_INODE,
f628f3d
 				"Lookup parent (..) of %p", mdc_parent);
f628f3d
 
f628f3d
-		mdc_get_parent(export, mdc_parent, &tmpfh);
f628f3d
+		status = mdc_get_parent(export, mdc_parent, &tmpfh);
f628f3d
 
f628f3d
-		status =  mdcache_locate_host(&tmpfh, export, new_entry,
f628f3d
-					      attrs_out);
f628f3d
-
f628f3d
-		mdcache_free_fh(&tmpfh);
f628f3d
+		if (FSAL_IS_SUCCESS(status)) {
f628f3d
+			status =  mdcache_locate_host(&tmpfh, export, new_entry,
f628f3d
+						      attrs_out);
f628f3d
+			mdcache_free_fh(&tmpfh);
f628f3d
+		}
f628f3d
 
f628f3d
 		if (status.major == ERR_FSAL_STALE)
f628f3d
 			status.major = ERR_FSAL_NOENT;
f628f3d
@@ -3198,6 +3233,14 @@
f628f3d
 							 MDCACHE_DIR_POPULATED);
f628f3d
 			}
f628f3d
 
f628f3d
+			if (has_write) {
f628f3d
+				/* We need to drop the ref on the rest of the
f628f3d
+				 * entries in this chunk, so that they don't
f628f3d
+				 * hang around until the directory is
f628f3d
+				 * invalidated. */
f628f3d
+				mdc_unref_chunk(chunk, dirent);
f628f3d
+			}
f628f3d
+
f628f3d
 			LogDebugAlt(COMPONENT_NFS_READDIR,
f628f3d
 				    COMPONENT_CACHE_INODE,
f628f3d
 				    "readdir completed, eod = %s",
f628f3d
diff -u -r nfs-ganesha-2.8.0/src/FSAL/Stackable_FSALs/FSAL_MDCACHE/mdcache_int.h nfs-ganesha-2.8.0.1/src/FSAL/Stackable_FSALs/FSAL_MDCACHE/mdcache_int.h
f628f3d
--- nfs-ganesha-2.8.0/src/FSAL/Stackable_FSALs/FSAL_MDCACHE/mdcache_int.h	2019-05-31 17:37:31.000000000 -0400
f628f3d
+++ nfs-ganesha-2.8.0.1/src/FSAL/Stackable_FSALs/FSAL_MDCACHE/mdcache_int.h	2019-06-07 18:00:00.000000000 -0400
f628f3d
@@ -504,7 +504,7 @@
f628f3d
 				      attrmask_t attrmask,
f628f3d
 				      bool *eod_met);
f628f3d
 
f628f3d
-void mdc_get_parent(struct mdcache_fsal_export *exp,
f628f3d
+fsal_status_t mdc_get_parent(struct mdcache_fsal_export *exp,
f628f3d
 		    mdcache_entry_t *entry,
f628f3d
 		    struct gsh_buffdesc *parent_out);
f628f3d
 
f628f3d
diff -u -r nfs-ganesha-2.8.0/src/nfs-ganesha.spec-in.cmake nfs-ganesha-2.8.0.1/src/nfs-ganesha.spec-in.cmake
f628f3d
--- nfs-ganesha-2.8.0/src/nfs-ganesha.spec-in.cmake	2019-05-31 17:37:31.000000000 -0400
f628f3d
+++ nfs-ganesha-2.8.0.1/src/nfs-ganesha.spec-in.cmake	2019-06-07 18:00:00.000000000 -0400
f628f3d
@@ -202,6 +202,10 @@
f628f3d
 Requires(post): psmisc
f628f3d
 Requires(pre): shadow-utils
f628f3d
 
f628f3d
+%if ( 0%{?fedora} >= 30 || 0%{?rhel} >= 8 )
f628f3d
+Requires: nfs-ganesha-selinux = %{version}-%{release}
f628f3d
+%endif
f628f3d
+
f628f3d
 # Use CMake variables
f628f3d
 
f628f3d
 %description