[CIFS] Fix scheduling while atomic when pending writes at file close time
Fix the case in which readdir reset file type when SFU mount option
specified.

Also fix sfu related functions to not request EAs (xattrs) when not
configured in Kconfig

Signed-off-by: Steve French <sfrench@us.ibm.com>
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 9b7e0ff..9bdaaec 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -142,6 +142,11 @@
 		tmp_inode->i_gid = cifs_sb->mnt_gid;
 		/* set default mode. will override for dirs below */
 		tmp_inode->i_mode = cifs_sb->mnt_file_mode;
+	} else {
+		/* mask off the type bits since it gets set
+		below and we do not want to get two type
+		bits set */
+		tmp_inode->i_mode &= ~S_IFMT;
 	}
 
 	if (attr & ATTR_DIRECTORY) {
@@ -152,12 +157,18 @@
 		}
 		tmp_inode->i_mode |= S_IFDIR;
 	} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 
-		   (attr & ATTR_SYSTEM) && (end_of_file == 0)) {
-		*pobject_type = DT_FIFO;
-		tmp_inode->i_mode |= S_IFIFO;
-/* BB Finish for SFU style symlinks and devies */
-/*	} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
-		(attr & ATTR_SYSTEM) && ) { */
+		   (attr & ATTR_SYSTEM)) {
+		if (end_of_file == 0)  {
+			*pobject_type = DT_FIFO;
+			tmp_inode->i_mode |= S_IFIFO;
+		} else {
+			/* rather than get the type here, we mark the
+			inode as needing revalidate and get the real type
+			(blk vs chr vs. symlink) later ie in lookup */
+			*pobject_type = DT_REG;
+			tmp_inode->i_mode |= S_IFREG; 
+			cifsInfo->time = 0;	
+		}
 /* we no longer mark these because we could not follow them */
 /*        } else if (attr & ATTR_REPARSE) {
                 *pobject_type = DT_LNK;
@@ -264,6 +275,9 @@
 	    cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
 
 	tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
+	/* since we set the inode type below we need to mask off type
+           to avoid strange results if bits above were corrupt */
+        tmp_inode->i_mode &= ~S_IFMT;
 	if (type == UNIX_FILE) {
 		*pobject_type = DT_REG;
 		tmp_inode->i_mode |= S_IFREG;
@@ -289,6 +303,11 @@
 	} else if (type == UNIX_SOCKET) {
 		*pobject_type = DT_SOCK;
 		tmp_inode->i_mode |= S_IFSOCK;
+	} else {
+		/* safest to just call it a file */
+		*pobject_type = DT_REG;
+		tmp_inode->i_mode |= S_IFREG;
+		cFYI(1,("unknown inode type %d",type)); 
 	}
 
 	tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);