[Libsysio-commit] HEAD: libsysio/src namei.c
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2009-08-04 14:19:11
|
Update of /cvsroot/libsysio/libsysio/src In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv18445/src Modified Files: namei.c Log Message: The namei family now takes the ND_WANTPARENT flag as well. This new flag causes a lock to be taken on the parent of the returned pnode when the return indicates success. Updated copyright date and contact. Index: namei.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/namei.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -w -b -B -p -r1.34 -r1.35 --- namei.c 4 Feb 2009 19:17:42 -0000 1.34 +++ namei.c 4 Aug 2009 14:19:00 -0000 1.35 @@ -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-2007 Sandia Corporation. + * Cplant(TM) Copyright 1998-2009 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 @@ -36,7 +36,7 @@ * Lee Ward * Sandia National Laboratories, New Mexico * P.O. Box 5800 - * Albuquerque, NM 87185-1110 + * Albuquerque, NM 87185-1319 * * le...@sa... */ @@ -211,6 +211,7 @@ _sysio_path_walk(struct pnode *parent, s const char *path; struct qstr this, next; struct inode *ino; + int done; /* * NULL path? @@ -282,6 +283,7 @@ _sysio_path_walk(struct pnode *parent, s path = next.name; parent = NULL; err = 0; + done = 0; /* * Derecurse the path tree-walk. @@ -294,6 +296,11 @@ _sysio_path_walk(struct pnode *parent, s ssize_t cc; struct nameidata nameidata; + if (parent) { + P_PUT(parent); + parent = NULL; + } + if (nd->nd_slicnt >= MAX_SYMLINK) { err = -ELOOP; break; @@ -334,6 +341,10 @@ _sysio_path_walk(struct pnode *parent, s break; P_PUT(nd->nd_pno); nd->nd_pno = nameidata.nd_pno; + if (nd->nd_flags & ND_WANTPARENT) { + parent = nd->nd_pno->p_parent; + assert(P_ISLOCKED(parent) && parent->p_ref); + } ino = nd->nd_pno->p_base->pb_ino; } #ifdef AUTOMOUNT_FILE_NAME @@ -403,6 +414,10 @@ _sysio_path_walk(struct pnode *parent, s * Must go back top and retry with this * new pnode as parent. */ + if (parent) { + P_PUT(parent); + parent = NULL; + } continue; } err = 0; /* it never happened */ @@ -428,6 +443,8 @@ _sysio_path_walk(struct pnode *parent, s } nd->nd_path = this.name + this.len; _sysio_next_component(nd->nd_path, &next); + if (parent) + P_PUT(parent); parent = nd->nd_pno; nd->nd_pno = NULL; @@ -484,7 +501,7 @@ _sysio_path_walk(struct pnode *parent, s !next.len && (nd->nd_flags & ND_NEGOK)) err = 0; - break; + done = 1; } path = NULL; /* Stop that! */ /* @@ -499,14 +516,15 @@ _sysio_path_walk(struct pnode *parent, s * to include the path again. */ path = nd->nd_path; - } - /* - * Finished with the current parent. + * Also, the parent isn't really the parent. */ P_PUT(parent); parent = NULL; } + if (done) + break; + } /* * Trailing separators cause us to break from the loop with @@ -524,12 +542,19 @@ _sysio_path_walk(struct pnode *parent, s err = -ENOTDIR; } + if (parent) { + if (err || !(nd->nd_flags & ND_WANTPARENT)) { /* - * Put the parent if present. Either we have a dup of the original - * parent or an intermediate reference. + * Put the parent if present. Either we have a dup of + * the original parent or an intermediate reference. */ - if (parent) P_PUT(parent); + parent = NULL; + } + } else if (!err && (nd->nd_flags & ND_WANTPARENT)) { + parent = nd->nd_pno->p_parent; + P_GET(parent); + } /* * On error, we will want to drop the current |