Whamcloud - gitweb
LU-4725 obd: lu_object_find_at hung
[fs/lustre-release.git] / libsysio / src / chdir.c
index 36c4757..3f5c900 100644 (file)
@@ -9,7 +9,7 @@
  *    terms of the GNU Lesser General Public License
  *    (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html)
  *
- *    Cplant(TM) Copyright 1998-2003 Sandia Corporation. 
+ *    Cplant(TM) Copyright 1998-2006 Sandia Corporation. 
  *    Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
  *    license for use of this work by or on behalf of the US Government.
  *    Export of this program may require a license from the United States
 #include "file.h"
 #include "sysio-symbols.h"
 
+#ifdef DEFER_INIT_CWD
+const char *_sysio_init_cwd = NULL;
+#endif
+
 struct pnode *_sysio_cwd = NULL;
 
 /*
@@ -90,15 +94,17 @@ _sysio_p_chdir(struct pnode *pno)
        int     err;
 
        /*
-        * Revalidate the pnode, and ensure it's a directory
+        * Revalidate the pnode, and ensure it's an accessable directory
         */
        err = _sysio_p_validate(pno, NULL, NULL);
        if (err)
                return err;
-
        if (!(pno->p_base->pb_ino &&
-             S_ISDIR(pno->p_base->pb_ino->i_mode)))
+             S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode)))
                return -ENOTDIR;
+       if ((err = _sysio_permitted(pno, X_OK)) != 0)
+               return err;
+
        /*
         * Release old if set.
         */
@@ -154,6 +160,9 @@ _sysio_p_path(struct pnode *pno, char **buf, size_t size)
 
        cur = pno;
 
+       if (!size && buf && *buf)
+               return -EINVAL;
+
        /*
         * Walk up the tree to the root, summing the component name
         * lengths and counting the vertices.
@@ -231,6 +240,19 @@ SYSIO_INTERFACE_NAME(getcwd)(char *buf, size_t size)
        SYSIO_INTERFACE_DISPLAY_BLOCK;
 
        SYSIO_INTERFACE_ENTER;
+#ifdef DEFER_INIT_CWD
+       if (!_sysio_cwd) {
+               struct pnode *pno;
+
+               /*
+                * Can no longer defer initialization of the current working
+                * directory. Force namei to make it happen now.
+                */
+               if (_sysio_namei(NULL, ".", 0, NULL, &pno) != 0)
+                       abort();
+               P_RELE(pno);
+       }
+#endif
        err = _sysio_p_path(_sysio_cwd, &buf, buf ? size : 0);
        SYSIO_INTERFACE_RETURN(err ? NULL : buf, err);
 }