/** * build the export entry */ fsal_status_t XFSFSAL_BuildExportContext(xfsfsal_export_context_t * p_export_context, /* OUT */ fsal_path_t * p_export_path, /* IN */ char *fs_specific_options /* IN */ ) { /* Get the mount point for this lustre FS, * so it can be used for building .lustre/fid paths. */ FILE *fp; struct mntent *p_mnt; struct stat pathstat; char rpath[MAXPATHLEN]; char mntdir[MAXPATHLEN]; char fs_spec[MAXPATHLEN]; char *first_xfs_dir = NULL; char type[256]; size_t pathlen, outlen; int rc; char *handle; size_t handle_len = 0; /* sanity check */ if(p_export_context == NULL) { LogCrit(COMPONENT_FSAL, "NULL mandatory argument passed to %s()", __FUNCTION__); Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_BuildExportContext); } outlen = 0; if(p_export_path != NULL) strncpy(rpath, p_export_path->path, MAXPATHLEN); /* open mnt file */ fp = setmntent(MOUNTED, "r"); if(fp == NULL) { rc = errno; LogCrit(COMPONENT_FSAL, "Error %d in setmntent(%s): %s", rc, MOUNTED, strerror(rc)); Return(posix2fsal_error(rc), rc, INDEX_FSAL_BuildExportContext); } while((p_mnt = getmntent(fp)) != NULL) { /* get the longer path xfs related export that matches export path */ if(p_mnt->mnt_dir != NULL) { pathlen = strlen(p_mnt->mnt_dir); if(strncmp(p_mnt->mnt_type, "xfs", 256)) continue; if(first_xfs_dir == NULL) first_xfs_dir = p_mnt->mnt_dir; if((pathlen > outlen) && !strcmp(p_mnt->mnt_dir, "/")) { LogDebug(COMPONENT_FSAL, "Root mountpoint is allowed for matching %s, type=%s, fs=%s", rpath, p_mnt->mnt_type, p_mnt->mnt_fsname); outlen = pathlen; strncpy(mntdir, p_mnt->mnt_dir, MAXPATHLEN); strncpy(type, p_mnt->mnt_type, 256); strncpy(fs_spec, p_mnt->mnt_fsname, MAXPATHLEN); } /* in other cases, the filesystem must be <mountpoint>/<smthg> or <mountpoint>\0 */ else if((pathlen > outlen) && !strncmp(rpath, p_mnt->mnt_dir, pathlen) && ((rpath[pathlen] == '/') || (rpath[pathlen] == '\0'))) { LogFullDebug(COMPONENT_FSAL, "%s is under mountpoint %s, type=%s, fs=%s", rpath, p_mnt->mnt_dir, p_mnt->mnt_type, p_mnt->mnt_fsname); outlen = pathlen; strncpy(mntdir, p_mnt->mnt_dir, MAXPATHLEN); strncpy(type, p_mnt->mnt_type, 256); strncpy(fs_spec, p_mnt->mnt_fsname, MAXPATHLEN); } } } if(outlen <= 0) { if(p_export_path == NULL) strncpy(mntdir, first_xfs_dir, MAXPATHLEN); else { LogCrit(COMPONENT_FSAL, "No mount entry matches '%s' in %s", rpath, MOUNTED); endmntent(fp); Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_BuildExportContext); } } /* Do the path_to_fshandle call to init the xfs's libhandle */ strncpy(p_export_context->mount_point, mntdir, MAXPATHLEN); if((rc = path_to_fshandle(mntdir, (void **)(&handle), &handle_len)) < 0) Return(ERR_FSAL_FAULT, errno, INDEX_FSAL_BuildExportContext); memcpy(p_export_context->mnt_fshandle_val, handle, handle_len); p_export_context->mnt_fshandle_len = handle_len; if((rc = path_to_handle(mntdir, (void **)(&handle), &handle_len)) < 0) Return(ERR_FSAL_FAULT, errno, INDEX_FSAL_BuildExportContext); memcpy(p_export_context->mnt_handle_val, handle, handle_len); p_export_context->mnt_handle_len = handle_len; p_export_context->dev_id = 1; /** @todo BUGAZOMEU : put something smarter here, using setmntent */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_BuildExportContext); }
static int parent_list(int fullpath) { void *handlep; size_t handlen; int error, i; int retval = 1; __u32 count; parent_t *entryp; parent_t *parentbuf = NULL; char *path = file->name; int pb_size = PARENTBUF_SZ; /* XXXX for linux libhandle version - to set libhandle fsfd cache */ { void *fshandle; size_t fshlen; if (path_to_fshandle(mntpt, &fshandle, &fshlen) != 0) { fprintf(stderr, _("%s: failed path_to_fshandle \"%s\": %s\n"), progname, path, strerror(errno)); goto error; } } if (path_to_handle(path, &handlep, &handlen) != 0) { fprintf(stderr, _("%s: path_to_handle failed for \"%s\"\n"), progname, path); goto error; } do { parentbuf = (parent_t *)realloc(parentbuf, pb_size); if (!parentbuf) { fprintf(stderr, _("%s: unable to allocate parent buffer: %s\n"), progname, strerror(errno)); return 1; } if (fullpath) { error = parentpaths_by_handle(handlep, handlen, parentbuf, pb_size, &count); } else { error = parents_by_handle(handlep, handlen, parentbuf, pb_size, &count); } if (error == ERANGE) { pb_size *= 2; } else if (error) { fprintf(stderr, _("%s: %s call failed for \"%s\": %s\n"), progname, fullpath ? "parentpaths" : "parents", path, strerror(errno)); goto error; } } while (error == ERANGE); if (count == 0) { /* no links for inode - something wrong here */ fprintf(stderr, _("%s: inode-path is missing\n"), progname); goto error; } entryp = parentbuf; for (i = 0; i < count; i++) { print_parent_entry(entryp, fullpath); entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen); } retval = 0; error: free(parentbuf); return retval; }