tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Use consistent errno for read(2) failure on directories



Hi,

According to the online OpenGroup specification for read(2) available
at [1], read(2) on directories is implementation dependant. If
unsupported, it shall fail with EISDIR.

Not all our file systems comply, and return random errno values in
this case (mostly EINVAL or ENOTSUP).

The attached patch fix some of them (the ones i have access to),
adjust the man page accordingly and add a small testcase to exercize
this.

Is it ok to apply ?
Thanks.

[1] http://pubs.opengroup.org/onlinepubs/009695399/functions/read.html

-- 
Nicolas Joly

Projects and Developments in Bioinformatics
Institut Pasteur, Paris.
Index: lib/libc/sys/read.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/read.2,v
retrieving revision 1.33
diff -u -p -r1.33 read.2
--- lib/libc/sys/read.2 5 Apr 2010 07:53:47 -0000       1.33
+++ lib/libc/sys/read.2 5 Dec 2011 09:30:04 -0000
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)read.2     8.4 (Berkeley) 2/26/94
 .\"
-.Dd April 3, 2010
+.Dd December 9, 2011
 .Dt READ 2
 .Os
 .Sh NAME
@@ -161,6 +161,16 @@ the total length of the I/O is more than
 return value.
 .It Bq Er EIO
 An I/O error occurred while reading from the file system.
+.It Bq Er EISDIR
+.Fa d
+refers to a directory and the implementation does not allow the directory
+to be read using
+.Fn read
+or
+.Fn pread .
+The
+.Fn readdir
+function should be used instead.
 .El
 .Pp
 In addition,
Index: sys/fs/ptyfs/ptyfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/ptyfs/ptyfs_vnops.c,v
retrieving revision 1.37
diff -u -p -r1.37 ptyfs_vnops.c
--- sys/fs/ptyfs/ptyfs_vnops.c  18 Nov 2011 21:18:50 -0000      1.37
+++ sys/fs/ptyfs/ptyfs_vnops.c  5 Dec 2011 09:30:04 -0000
@@ -788,6 +788,9 @@ ptyfs_read(void *v)
        struct ptyfsnode *ptyfs = VTOPTYFS(vp);
        int error;
 
+       if (vp->v_type == VDIR)
+               return EISDIR;
+
        ptyfs->ptyfs_flag |= PTYFS_ACCESS;
        /* hardclock() resolution is good enough for ptyfs */
        getnanotime(&ts);
Index: sys/fs/sysvbfs/sysvbfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/sysvbfs/sysvbfs_vnops.c,v
retrieving revision 1.38
diff -u -p -r1.38 sysvbfs_vnops.c
--- sys/fs/sysvbfs/sysvbfs_vnops.c      19 May 2011 03:11:58 -0000      1.38
+++ sys/fs/sysvbfs/sysvbfs_vnops.c      5 Dec 2011 09:30:05 -0000
@@ -378,8 +378,14 @@ sysvbfs_read(void *arg)
        const int advice = IO_ADV_DECODE(a->a_ioflag);
 
        DPRINTF("%s: type=%d\n", __func__, v->v_type);
-       if (v->v_type != VREG)
+       switch (v->v_type) {
+       case VREG:
+               break;
+       case VDIR:
+               return EISDIR;
+       default:
                return EINVAL;
+       }
 
        while (uio->uio_resid > 0) {
                if ((sz = MIN(filesz - uio->uio_offset, uio->uio_resid)) == 0)
Index: sys/miscfs/kernfs/kernfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/kernfs/kernfs_vnops.c,v
retrieving revision 1.143
diff -u -p -r1.143 kernfs_vnops.c
--- sys/miscfs/kernfs/kernfs_vnops.c    21 Jul 2010 09:06:38 -0000      1.143
+++ sys/miscfs/kernfs/kernfs_vnops.c    5 Dec 2011 09:30:05 -0000
@@ -941,7 +941,7 @@ kernfs_default_xread(void *v)
        int error;
 
        if (ap->a_vp->v_type == VDIR)
-               return (EOPNOTSUPP);
+               return EISDIR;
 
        off = (int)uio->uio_offset;
        /* Don't allow negative offsets */
Index: sys/rump/librump/rumpvfs/rumpfs.c
===================================================================
RCS file: /cvsroot/src/sys/rump/librump/rumpvfs/rumpfs.c,v
retrieving revision 1.103
diff -u -p -r1.103 rumpfs.c
--- sys/rump/librump/rumpvfs/rumpfs.c   27 Sep 2011 14:24:52 -0000      1.103
+++ sys/rump/librump/rumpvfs/rumpfs.c   5 Dec 2011 09:30:06 -0000
@@ -1284,6 +1284,9 @@ rump_vop_read(void *v)
        off_t chunk;
        int error = 0;
 
+       if (vp->v_type == VDIR)
+               return EISDIR;
+
        /* et op? */
        if (rn->rn_flags & RUMPNODE_ET_PHONE_HOST)
                return etread(rn, uio);
Index: tests/fs/vfs/t_vnops.c
===================================================================
RCS file: /cvsroot/src/tests/fs/vfs/t_vnops.c,v
retrieving revision 1.29
diff -u -p -r1.29 t_vnops.c
--- tests/fs/vfs/t_vnops.c      8 Oct 2011 13:08:54 -0000       1.29
+++ tests/fs/vfs/t_vnops.c      5 Dec 2011 09:30:06 -0000
@@ -827,6 +827,27 @@ access_simple(const atf_tc_t *tc, const 
        FSTEST_EXIT();
 }
 
+static void
+read_directory(const atf_tc_t *tc, const char *mp)
+{
+       char buf[1024];
+       int fd, res;
+       ssize_t size;
+
+       FSTEST_ENTER();
+       fd = rump_sys_open(".", O_DIRECTORY | O_RDONLY, 0777);
+       ATF_REQUIRE(fd != -1);
+
+       size = rump_sys_pread(fd, buf, sizeof(buf), 0);
+       ATF_CHECK(size != -1 || errno == EISDIR);
+       size = rump_sys_read(fd, buf, sizeof(buf));
+       ATF_CHECK(size != -1 || errno == EISDIR);
+
+       res = rump_sys_close(fd);
+       ATF_REQUIRE(res != -1);
+       FSTEST_EXIT();
+}
+
 ATF_TC_FSAPPLY(lookup_simple, "simple lookup (./.. on root)");
 ATF_TC_FSAPPLY(lookup_complex, "lookup of non-dot entries");
 ATF_TC_FSAPPLY(dir_simple, "mkdir/rmdir");
@@ -844,6 +865,7 @@ ATF_TC_FSAPPLY(attrs, "check setting att
 ATF_TC_FSAPPLY(fcntl_lock, "check fcntl F_SETLK");
 ATF_TC_FSAPPLY(fcntl_getlock_pids,"fcntl F_GETLK w/ many procs, PR 
kern/44494");
 ATF_TC_FSAPPLY(access_simple, "access(2)");
+ATF_TC_FSAPPLY(read_directory, "read(2) on directories");
 
 ATF_TP_ADD_TCS(tp)
 {
@@ -865,6 +887,7 @@ ATF_TP_ADD_TCS(tp)
        ATF_TP_FSAPPLY(fcntl_lock);
        ATF_TP_FSAPPLY(fcntl_getlock_pids);
        ATF_TP_FSAPPLY(access_simple);
+       ATF_TP_FSAPPLY(read_directory);
 
        return atf_no_error();
 }


Home | Main Index | Thread Index | Old Index