}
#else /* !AFS_NT40_ENV */
Inode
-namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4)
+icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
+ FD_t *afd, Inode *ainode)
{
namei_t name;
int fd = INVALID_FD;
}
bad:
- if (fd != INVALID_FD)
- OS_CLOSE(fd);
-
-
if (code || (fd == INVALID_FD)) {
if (p2 != -1) {
fdP = IH_OPEN(lh);
}
}
}
- return (code || (fd == INVALID_FD)) ? (Inode) - 1 : tmp.ih_ino;
+
+ *afd = fd;
+ *ainode = tmp.ih_ino;
+
+ return code;
+}
+
+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;
+ int code;
+
+ code = icreate(lh, part, p1, p2, p3, p4, &fd, &ino);
+ if (fd != INVALID_FD) {
+ close(fd);
+ }
+ return (code || (fd == INVALID_FD)) ? (Inode) - 1 : 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;
+
+ code = icreate(lh, part, p1, p2, p3, p4, &fd, &ino);
+ if (fd == INVALID_FD) {
+ return NULL;
+ }
+ if (code) {
+ close(fd);
+ return NULL;
+ }
+
+ IH_INIT(ihP, dev, p1, ino);
+ fdP = ih_attachfd(ihP, fd);
+ if (!fdP) {
+ close(fd);
+ } else {
+ FDH_CLOSE(fdP);
+ }
+
+ return ihP;
}
#endif
/* ListViceInodes - write inode data to a results file. */
static int DecodeInode(char *dpath, char *name, struct ViceInodeInfo *info,
- VolumeId volid);
+ IHandle_t *myIH);
static int DecodeVolumeName(char *name, VolumeId *vid);
static int namei_ListAFSSubDirs(IHandle_t * dirIH,
int (*write_fun) (FD_t,
int ret = 0;
struct ViceInodeInfo info;
- if (DecodeInode(path1, dname, &info, myIH->ih_vid) < 0) {
+ if (DecodeInode(path1, dname, &info, myIH) < 0) {
ret = 0;
goto error;
}
"(dir_vgid=%" AFS_VOLID_FMT ", inode_vgid=%" AFS_VOLID_FMT ")\n",
path1, dname, afs_printable_VolumeId_lu(myIH->ih_vid),
afs_printable_VolumeId_lu(info.u.param[0]));
+ /* We need to set the linkCount to _something_, so linkCount
+ * doesn't just contain stack garbage. Set it to 0, so in case
+ * the salvager or whatever our caller is does try to process
+ * this like a normal file, we won't try to INC or DEC it. */
+ info.linkCount = 0;
} else {
char path2[512];
/* Open this handle */
int dirl; /* Windows-only (one level hash dir) */
#endif
- if (DecodeInode(path3, dname, &info, myIH->ih_vid) < 0) {
+ if (DecodeInode(path3, dname, &info, myIH) < 0) {
goto error;
}
#ifdef AFS_NT40_ENV
static int
DecodeInode(char *dpath, char *name, struct ViceInodeInfo *info,
- VolumeId volid)
+ IHandle_t *myIH)
{
char fpath[512];
int tag, vno;
char stmp[16];
FdHandle_t linkHandle;
char dirl;
+ VolumeId volid = myIH->ih_vid;
snprintf(fpath, sizeof(fpath), "%s" OS_DIRSEP "%s", dpath, name);
#else
static int
DecodeInode(char *dpath, char *name, struct ViceInodeInfo *info,
- VolumeId volid)
+ IHandle_t *myIH)
{
char fpath[512];
struct afs_stat_st status;
+ struct afs_stat_st checkstatus;
int parm, tag;
lb64_string_t check;
+ VolumeId volid = myIH->ih_vid;
+ IHandle_t tmpih;
+ namei_t nameiname;
snprintf(fpath, sizeof(fpath), "%s" OS_DIRSEP "%s", dpath, name);
if (strcmp(name, check))
return -1;
+ /* Check if the _full_ path is correct, to ensure we can actually open this
+ * file later. Otherwise, the salvager can choke. */
+ memset(&tmpih, 0, sizeof(tmpih));
+ tmpih.ih_dev = myIH->ih_dev;
+ tmpih.ih_vid = myIH->ih_vid;
+ tmpih.ih_ino = info->inodeNumber;
+ namei_HandleToName(&nameiname, &tmpih);
+ if ((afs_stat(nameiname.n_path, &checkstatus) < 0) ||
+ checkstatus.st_ino != status.st_ino ||
+ checkstatus.st_size != status.st_size) {
+ static int logged;
+ /* log something for this case, since this means the filename looks
+ * like a valid inode, but it's just in the wrong place. That's pretty
+ * strange. */
+ if (!logged) {
+ logged = 1;
+ Log("Note:\n");
+ Log(" Seemingly-misplaced files have been found, which I am\n");
+ Log(" ignoring for now. If you cannot salvage the relevant volume,\n");
+ Log(" you may try manually moving them to their correct location.\n");
+ Log(" If the relevant volume seems fine, and these files do not\n");
+ Log(" appear to contain important data, you can probably manually\n");
+ Log(" delete them, or leave them alone. Contact your local OpenAFS\n");
+ Log(" expert if you are unsure.\n");
+ }
+ Log("Ignoring misplaced file in volume group %u: %s (should be %s)\n",
+ (unsigned)myIH->ih_vid, fpath, nameiname.n_path);
+ return -1;
+ }
+
if ((info->inodeNumber & NAMEI_INODESPECIAL) == NAMEI_INODESPECIAL) {
parm = ((info->inodeNumber >> NAMEI_UNIQSHIFT) & NAMEI_UNIQMASK);
tag = (int)((info->inodeNumber >> NAMEI_TAGSHIFT) & NAMEI_TAGMASK);
if (*dp->d_name == '.')
continue;
#endif
- if (DecodeInode(dir_name, dp->d_name, &info, ih->ih_vid) < 0) {
+ if (DecodeInode(dir_name, dp->d_name, &info, ih) < 0) {
Log("1 namei_ConvertROtoRWvolume: DecodeInode failed for %s" OS_DIRSEP "%s\n",
dir_name, dp->d_name);
closedir(dirp);