#include <afs/opr.h>
#include <rx/rx_queue.h>
+#ifdef AFS_PTHREAD_ENV
+# include <opr/lock.h>
+#endif
#include <lock.h>
#include <afs/afsutil.h>
#include <lwp.h>
* types, but if we get that far, this could should be dead by then.
*/
Inode
-namei_MakeSpecIno(int volid, int type)
+namei_MakeSpecIno(VolumeId volid, int type)
{
Inode ino;
ino = NAMEI_INODESPECIAL;
}
#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
} else {
IHandle_t *th;
IH_INIT(th, ih->ih_dev, ih->ih_vid, ino);
- Log("Warning: Lost ref on ihandle dev %d vid %d ino %lld\n",
- th->ih_dev, th->ih_vid, (afs_int64)th->ih_ino);
+ Log("Warning: Lost ref on ihandle dev %d vid %" AFS_VOLID_FMT " ino %lld\n",
+ th->ih_dev, afs_printable_VolumeId_lu(th->ih_vid), (afs_int64)th->ih_ino);
IH_RELEASE(th);
/* If we're less than 0, someone presumably unlinked;
#ifdef AFS_PTHREAD_ENV
/* XXX do static initializers work for WINNT/pthread? */
pthread_mutex_t _namei_glc_lock = PTHREAD_MUTEX_INITIALIZER;
-#define NAMEI_GLC_LOCK MUTEX_ENTER(&_namei_glc_lock)
-#define NAMEI_GLC_UNLOCK MUTEX_EXIT(&_namei_glc_lock)
+#define NAMEI_GLC_LOCK opr_mutex_enter(&_namei_glc_lock)
+#define NAMEI_GLC_UNLOCK opr_mutex_exit(&_namei_glc_lock)
#else /* !AFS_PTHREAD_ENV */
#define NAMEI_GLC_LOCK
#define NAMEI_GLC_UNLOCK
/* ListViceInodes - write inode data to a results file. */
static int DecodeInode(char *dpath, char *name, struct ViceInodeInfo *info,
- unsigned int volid);
-static int DecodeVolumeName(char *name, unsigned int *vid);
+ IHandle_t *myIH);
+static int DecodeVolumeName(char *name, VolumeId *vid);
static int namei_ListAFSSubDirs(IHandle_t * dirIH,
int (*write_fun) (FD_t,
struct ViceInodeInfo *,
char *, char *), FD_t fp,
int (*judgeFun) (struct ViceInodeInfo *,
- afs_uint32 vid, void *),
- afs_uint32 singleVolumeNumber, void *rock);
+ VolumeId vid, void *),
+ VolumeId singleVolumeNumber, void *rock);
/* WriteInodeInfo
*/
int
ListViceInodes(char *devname, char *mountedOn, FD_t inodeFile,
- int (*judgeInode) (struct ViceInodeInfo * info, afs_uint32 vid, void *rock),
- afs_uint32 singleVolumeNumber, int *forcep, int forceR, char *wpath,
+ int (*judgeInode) (struct ViceInodeInfo * info, VolumeId vid, void *rock),
+ VolumeId singleVolumeNumber, int *forcep, int forceR, char *wpath,
void *rock)
{
int ninodes;
int (*writeFun) (FD_t, struct ViceInodeInfo *, char *,
char *),
FD_t fp,
- int (*judgeFun) (struct ViceInodeInfo *, afs_uint32, void *),
- afs_uint32 singleVolumeNumber, void *rock)
+ int (*judgeFun) (struct ViceInodeInfo *, VolumeId, void *),
+ VolumeId singleVolumeNumber, void *rock)
{
IHandle_t ih;
namei_t name;
int (*writeFun) (FD_t, struct ViceInodeInfo *, char *,
char *),
FD_t fp,
- int (*judgeFun) (struct ViceInodeInfo *, afs_uint32, void *),
- int singleVolumeNumber,
+ int (*judgeFun) (struct ViceInodeInfo *, VolumeId, void *),
+ VolumeId singleVolumeNumber,
void *rock)
{
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;
}
* consistent with VGID encoded in namei path */
Log("namei_ListAFSSubDirs: warning: inconsistent linktable "
"filename \"%s" OS_DIRSEP "%s\"; salvager will delete it "
- "(dir_vgid=%u, inode_vgid=%u)\n",
- path1, dname, myIH->ih_vid,
- info.u.param[0]);
+ "(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 (*writeFun) (FD_t, struct ViceInodeInfo *, char *,
char *),
FD_t fp,
- int (*judgeFun) (struct ViceInodeInfo *, afs_uint32, void *),
- int singleVolumeNumber,
+ int (*judgeFun) (struct ViceInodeInfo *, VolumeId, void *),
+ VolumeId singleVolumeNumber,
void *rock)
{
int ret = 0;
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;
}
int (*writeFun) (FD_t, struct ViceInodeInfo *, char *, char *);
/** inode filter function */
- int (*judgeFun) (struct ViceInodeInfo *, afs_uint32, void *);
- int singleVolumeNumber; /**< volume id filter */
+ int (*judgeFun) (struct ViceInodeInfo *, VolumeId, void *);
+ VolumeId singleVolumeNumber; /**< volume id filter */
void * rock; /**< pointer passed to writeFun and judgeFun */
int code; /**< return code from examine function */
int special; /**< asserted when this is a volume
int (*writeFun) (FD_t, struct ViceInodeInfo *, char *,
char *),
FD_t fp,
- int (*judgeFun) (struct ViceInodeInfo *, afs_uint32, void *),
- afs_uint32 singleVolumeNumber, void *rock)
+ int (*judgeFun) (struct ViceInodeInfo *, VolumeId, void *),
+ VolumeId singleVolumeNumber, void *rock)
{
int code = 0, ret = 0;
IHandle_t myIH = *dirIH;
#endif
if (linkHandle.fd_fd == INVALID_FD) {
- Log("namei_ListAFSSubDirs: warning: VG %u does not have a link table; "
- "salvager will recreate it.\n", dirIH->ih_vid);
+ Log("namei_ListAFSSubDirs: warning: VG %" AFS_VOLID_FMT " does not have a link table; "
+ "salvager will recreate it.\n", afs_printable_VolumeId_lu(dirIH->ih_vid));
}
/* Now run through all the other subdirs */
#ifdef AFS_NT40_ENV
static int
-DecodeVolumeName(char *name, unsigned int *vid)
+DecodeVolumeName(char *name, VolumeId *vid)
{
/* Name begins with "Vol_" and ends with .data. See nt_HandleToVolDir() */
char stmp[32];
}
#else
static int
-DecodeVolumeName(char *name, unsigned int *vid)
+DecodeVolumeName(char *name, VolumeId *vid)
{
if (strlen(name) < 1)
return -1;
#ifdef AFS_NT40_ENV
static int
DecodeInode(char *dpath, char *name, struct ViceInodeInfo *info,
- unsigned int 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,
- unsigned int 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);
#ifdef FSSYNC_BUILD_CLIENT
static afs_int32
-convertVolumeInfo(FD_t fdr, FD_t fdw, afs_uint32 vid)
+convertVolumeInfo(FD_t fdr, FD_t fdw, VolumeId vid)
{
struct VolumeDiskData vd;
char *p;
if (OS_READ(fdr, &vd, sizeof(struct VolumeDiskData)) !=
sizeof(struct VolumeDiskData)) {
- Log("1 convertVolumeInfo: read failed for %lu with code %d\n",
- afs_printable_uint32_lu(vid),
+ Log("1 convertVolumeInfo: read failed for %" AFS_VOLID_FMT " with code %d\n",
+ afs_printable_VolumeId_lu(vid),
errno);
return -1;
}
*/
int
-namei_ConvertROtoRWvolume(char *pname, afs_uint32 volumeId)
+namei_ConvertROtoRWvolume(char *pname, VolumeId volumeId)
{
int code = 0;
#ifdef FSSYNC_BUILD_CLIENT
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);
largeSeen = 1;
} else {
closedir(dirp);
- Log("1 namei_ConvertROtoRWvolume: unknown type %d of special file found : %s" OS_DIRSEP "%s\n", info.u.param[2], dir_name, dp->d_name);
+ Log("1 namei_ConvertROtoRWvolume: unknown type %u of special file found : %s" OS_DIRSEP "%s\n", info.u.param[2], dir_name, dp->d_name);
code = -1;
goto done;
}