Bug #2410

procfs needlessly breaks large file support

Added by Bryan Cantrill about 2 years ago. Updated 4 months ago.

Status:Resolved Start date:2012-03-15
Priority:Normal Due date:
Assignee:Bryan Cantrill % Done:

100%

Category:kernel Spent time: -
Target version:-
Difficulty:Bite-size Tags:

Description

When attempting to include <sys/procfs.h> in compiling a 32-bit program with large file support, the compile will explicitly fail on a #error:

#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
#error  "Cannot use procfs in the large file compilation environment" 
#endif

Just googling this error reveals how many have hit this issue -- it's not uncommon for programs who do not intend to use /proc include (through include dependencies) <sys/procfs.h>. Over the years, many reasons have been offered up for this; they have ranged from the demonstrably false (e.g., asserting that the kernel cannot differentiate large file awareness in a 32-bit process) to the merely intransigent (e.g., defending this as documented behavior). From all appearances , this just appears to be incredibly lazy: while it is true that procfs is not entirely off_t-neutral, there is only one structure that embeds an off_t (priovec_t), and it is a straightforward matter for the kernel to reject -- dynamically -- any attempt to use this structure from a large file open in a 32-bit process. (In the highly unlikely case that this case should be supported instead of erroring out, that too is possible.)

Diffs:

diff --git a/usr/src/uts/common/fs/proc/prcontrol.c b/usr/src/uts/common/fs/proc
index 55a48bb..5370913 100644
--- a/usr/src/uts/common/fs/proc/prcontrol.c
+++ b/usr/src/uts/common/fs/proc/prcontrol.c
@@ -24,6 +24,10 @@
  * Use is subject to license terms.
  */

+/*
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <sys/param.h>
@@ -935,7 +939,7 @@ pr_control32(int32_t cmd, arg32_t *argp, prnode_t *pnp, cred

        case PCREAD:    /* read from the address space */
        case PCWRITE:   /* write to the address space */
-               if (PROCESS_NOT_32BIT(p))
+               if (PROCESS_NOT_32BIT(p) || (pnp->pr_flags & PR_OFFMAX))
                        error = EOVERFLOW;
                else {
                        enum uio_rw rw = (cmd == PCREAD)? UIO_READ : UIO_WRITE;
diff --git a/usr/src/uts/common/fs/proc/prdata.h b/usr/src/uts/common/fs/proc/pr
index 1294421..ce92577 100644
--- a/usr/src/uts/common/fs/proc/prdata.h
+++ b/usr/src/uts/common/fs/proc/prdata.h
@@ -23,6 +23,10 @@
  * Use is subject to license terms.
  */

+/*
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
 /*     Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
 /*       All Rights Reserved   */

@@ -183,6 +187,7 @@ typedef struct prnode {
 #define        PR_INVAL        0x01            /* vnode is invalidated */
 #define        PR_ISSELF       0x02            /* vnode is a self-open */
 #define        PR_AOUT         0x04            /* vnode is for an a.out path */
+#define        PR_OFFMAX       0x08            /* vnode is a large file open */

 /*
  * Conversion macros.
diff --git a/usr/src/uts/common/fs/proc/prvnops.c b/usr/src/uts/common/fs/proc/p
index a3e95a6..7831c1f 100644
--- a/usr/src/uts/common/fs/proc/prvnops.c
+++ b/usr/src/uts/common/fs/proc/prvnops.c
@@ -23,6 +23,10 @@
  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  */

+/*
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ */
+
 /*     Copyright (c) 1984,      1986, 1987, 1988, 1989 AT&T    */
 /*       All Rights Reserved   */

@@ -337,6 +341,15 @@ propen(vnode_t **vpp, int flag, cred_t *cr, caller_context_
        }

        /*
+        * If this is a large file open, indicate that in our flags -- some
+        * procfs structures are not off_t-neutral (e.g., priovec_t), and
+        * the open will need to be differentiated where 32-bit processes
+        * pass these structures across the user/kernel boundary.
+        */
+       if (flag & FOFFMAX)
+               pnp->pr_flags |= PR_OFFMAX;
+
+       /*
         * Do file-specific things.
         */
        switch (type) {
diff --git a/usr/src/uts/common/sys/procfs.h b/usr/src/uts/common/sys/procfs.h
index b320836..12a6925 100644
--- a/usr/src/uts/common/sys/procfs.h
+++ b/usr/src/uts/common/sys/procfs.h
@@ -62,10 +62,6 @@ extern "C" {
 #include <sys/procfs_isa.h>
 #include <sys/priv.h>

-#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
-#error "Cannot use procfs in the large file compilation environment" 
-#endif
-
 /*
  * System call interfaces for /proc.
  */

Related issues

related to illumos gate - Bug #1140: sys/swap.h should work in large file environment New 2011-06-23

History

Updated by Robert Mustacchi 4 months ago

  • Tags deleted (needs-triage)
  • % Done changed from 90 to 100
  • Status changed from New to Resolved

Resolved in d1b18d1a1255ac607d5e072515d727cdfe52f878.

Also available in: Atom PDF