namei: Remove icreate tfd hack
authorAndrew Deason <adeason@sinenomine.net>
Fri, 30 Aug 2013 17:23:43 +0000 (12:23 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Wed, 3 Dec 2014 06:13:17 +0000 (01:13 -0500)
Currently, the namei icreate routine creates a fake FdHandle_t for a
SetLinkCount call if we're creating a linktable. In the past this was
probably done because we did not want to open a "real" fdP ,since that
would mean opening another file descriptor, when we already had a file
descriptor (from the creating afs_open call).

This is a problem in the salvager, since it means that we can reach
ihandle code before the ihandle package has been initialized.
Specifically, we can reach icreate -> namei_SetLinkCount -> ih_fdsync.
If we reach ih_fdsync without the ihandle package being initialized,
we assert and dump core.

The ihandle package assumes that we've already initialized it if we
reach any ihandle code, since creating any IHandle_t causes the
package to initialize. But since namei_icreate fakes its own IHandle_t
and FdHandle_t structures, that doesn't happen.

So, to avoid this, stop faking our FdHandle_t and create a real one.
Since we have ih_attachfd, we can create a real FdHandle_t with our
existing file descriptor.

Change-Id: I7a8c1e0ed1ee8e5c8ce2e165b9493811d5d2435d
Reviewed-on: http://gerrit.openafs.org/10213
Reviewed-by: D Brashear <shadow@your-file-system.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/vol/namei_ops.c

index 67354b6..fc0a14a 100644 (file)
@@ -954,20 +954,19 @@ bad:
 #else /* !AFS_NT40_ENV */
 Inode
 icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
-        FD_t *afd, Inode *ainode)
+        IHandle_t **a_ih)
 {
     namei_t name;
     int fd = INVALID_FD;
     int code = 0;
     int created_dir = 0;
     IHandle_t tmp;
+    IHandle_t *realh = NULL;
     FdHandle_t *fdP;
-    FdHandle_t tfd;
     int tag;
     int ogm_parm;
 
     memset((void *)&tmp, 0, sizeof(IHandle_t));
-    memset(&tfd, 0, sizeof(FdHandle_t));
 
     tmp.ih_dev = volutil_GetPartitionID(part);
     if (tmp.ih_dev == -1) {
@@ -1035,14 +1034,19 @@ icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3,
        goto bad;
     }
 
+    IH_INIT(realh, tmp.ih_dev, tmp.ih_vid, tmp.ih_ino);
+    fdP = ih_attachfd(realh, fd);
+
+    /* ih_attachfd can only return NULL if we give it an invalid fd; our fd
+     * must be valid by this point. */
+    opr_Assert(fdP);
+
     if (p2 == (afs_uint32)-1 && p3 == VI_LINKTABLE) {
-       /* hack at tmp to setup for set link count call. */
-       memset((void *)&tfd, 0, sizeof(FdHandle_t));    /* minimalistic still, but a little cleaner */
-       tfd.fd_ih = &tmp;
-       tfd.fd_fd = fd;
-       code = namei_SetLinkCount(&tfd, (Inode) 0, 1, 0);
+       code = namei_SetLinkCount(fdP, (Inode) 0, 1, 0);
     }
 
+    FDH_CLOSE(fdP);
+
   bad:
     if (code || (fd == INVALID_FD)) {
        if (p2 != -1) {
@@ -1052,10 +1056,10 @@ icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3,
                FDH_CLOSE(fdP);
            }
        }
+       IH_RELEASE(realh);
     }
 
-    *afd = fd;
-    *ainode = tmp.ih_ino;
+    *a_ih = realh;
 
     return code;
 }
@@ -1064,44 +1068,32 @@ Inode
 namei_icreate(IHandle_t * lh, char *part,
               afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4)
 {
-    Inode ino = 0;
-    int fd = INVALID_FD;
+    Inode ino;
+    IHandle_t *ihP = NULL;
     int code;
 
-    code = icreate(lh, part, p1, p2, p3, p4, &fd, &ino);
-    if (fd != INVALID_FD) {
-       close(fd);
+    code = icreate(lh, part, p1, p2, p3, p4, &ihP);
+    if (code || !ihP) {
+       opr_Assert(!ihP);
+       ino = -1;
+    } else {
+       ino = ihP->ih_ino;
+       IH_RELEASE(ihP);
     }
-    return (code || (fd == INVALID_FD)) ? (Inode) - 1 : ino;
+    return ino;
 }
 
 IHandle_t *
 namei_icreate_init(IHandle_t * lh, int dev, char *part,
                    afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4)
 {
-    Inode ino = 0;
-    int fd = INVALID_FD;
     int code;
-    IHandle_t *ihP;
-    FdHandle_t *fdP;
+    IHandle_t *ihP = NULL;
 
-    code = icreate(lh, part, p1, p2, p3, p4, &fd, &ino);
-    if (fd == INVALID_FD) {
-       return NULL;
-    }
+    code = icreate(lh, part, p1, p2, p3, p4, &ihP);
     if (code) {
-       close(fd);
-       return NULL;
+       opr_Assert(!ihP);
     }
-
-    IH_INIT(ihP, dev, p1, ino);
-    fdP = ih_attachfd(ihP, fd);
-    if (!fdP) {
-       close(fd);
-    } else {
-       FDH_CLOSE(fdP);
-    }
-
     return ihP;
 }
 #endif