Issue #21679: Prevent extraneous fstat() calls during open().  Patch by Bohuslav Kabrda.
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
index cbb2daf..038b2c6 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -53,6 +53,7 @@
     signed int seekable : 2; /* -1 means unknown */
     unsigned int closefd : 1;
     char finalizing;
+    unsigned int blksize;
     PyObject *weakreflist;
     PyObject *dict;
 } fileio;
@@ -161,6 +162,7 @@
         self->writable = 0;
         self->appending = 0;
         self->seekable = -1;
+        self->blksize = 0;
         self->closefd = 1;
         self->weakreflist = NULL;
     }
@@ -168,26 +170,6 @@
     return (PyObject *) self;
 }
 
-/* On Unix, open will succeed for directories.
-   In Python, there should be no file objects referring to
-   directories, so we need a check.  */
-
-static int
-dircheck(fileio* self, PyObject *nameobj)
-{
-#if defined(HAVE_FSTAT) && defined(S_ISDIR) && defined(EISDIR)
-    struct stat buf;
-    if (self->fd < 0)
-        return 0;
-    if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
-        errno = EISDIR;
-        PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
-        return -1;
-    }
-#endif
-    return 0;
-}
-
 static int
 check_fd(int fd)
 {
@@ -233,6 +215,9 @@
 #elif !defined(MS_WINDOWS)
     int *atomic_flag_works = NULL;
 #endif
+#ifdef HAVE_FSTAT
+    struct stat fdfstat;
+#endif
 
     assert(PyFileIO_Check(oself));
     if (self->fd >= 0) {
@@ -421,8 +406,26 @@
             goto error;
 #endif
     }
-    if (dircheck(self, nameobj) < 0)
+
+    self->blksize = DEFAULT_BUFFER_SIZE;
+#ifdef HAVE_FSTAT
+    if (fstat(self->fd, &fdfstat) < 0)
         goto error;
+#if defined(S_ISDIR) && defined(EISDIR)
+    /* On Unix, open will succeed for directories.
+       In Python, there should be no file objects referring to
+       directories, so we need a check.  */
+    if (S_ISDIR(fdfstat.st_mode)) {
+        errno = EISDIR;
+        PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
+        goto error;
+    }
+#endif /* defined(S_ISDIR) */
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+    if (fdfstat.st_blksize > 1)
+        self->blksize = fdfstat.st_blksize;
+#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
+#endif /* HAVE_FSTAT */
 
 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
     /* don't translate newlines (\r\n <=> \n) */
@@ -1216,6 +1219,7 @@
 };
 
 static PyMemberDef fileio_members[] = {
+    {"_blksize", T_UINT, offsetof(fileio, blksize), 0},
     {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
     {NULL}
 };