/////////////////////////////////////////////////////////////////////////////// /// // STFSd_open /// /// \brief Opens an existing STFS file /// /// \param const char *pp_Path, /// \param int pv_OFlag, /// \param pv_OpenerNodeId, /// \param pv_OpenerPID, /// \param STFS_ExternalFileMetadata *&pp_Efm, /// \param STFS_FragmentFileMetadata *&pp_Ffm, /// \param STFS_OpenIdentifier *&pp_OpenId) /// /////////////////////////////////////////////////////////////////////////////// int STFSd_open(const char *pp_Path, int pv_OFlag, int pv_OpenerNodeId, int pv_OpenerPID, STFS_ExternalFileMetadata *&pp_Efm, STFS_FragmentFileMetadata *&pp_Ffm, STFS_OpenIdentifier *&pp_OpenId) { const char *WHERE = "STFSd_open"; STFS_ScopeTrace lv_st(WHERE); STFS_Session *lp_Session = STFS_Session::GetSession(); int lv_Ret = 0; if (!pp_Path) { errno = EINVAL; char lp_ErrMess[] = "Error Path is NULL"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -1; } char lp_Path[STFS_PATH_MAX]; strcpy(lp_Path, pp_Path); STFS_ExternalFileMetadata *lp_Efm = STFS_ExternalFileMetadata::GetFromContainer(lp_Path); if(!lp_Efm) { TRACE_PRINTF2(1,"%s\n", "Error getting lp_Efm"); errno = EINVAL; char lp_ErrMess[] = "Error getting lp_Efm"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -2; } TRACE_PRINTF4(2, "FileName: %s, Opener Node Id: %d, Opener SQ PID: %d\n", lp_Efm->ExternalFileNameGet(), pv_OpenerNodeId, pv_OpenerPID); STFS_util::ValidateEFM(lp_Efm); if(!lp_Efm->FileAvailableGet()) { TRACE_PRINTF2(1, "File: %s is no longer available\n", pp_Path); errno = ENOENT; char lp_ErrMess[] = "Error file is no longer available"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -1; } int lv_FragmentOffset = 0; //If O_APPEND, last fragment will be set open, if((pv_OFlag & O_APPEND) == O_APPEND) { lv_FragmentOffset = lp_Efm->GetNumFragments(); if(lv_FragmentOffset == 0) { TRACE_PRINTF2(1,"%s\n", "Error Number of Fragments returned is 0"); errno = ENOENT; char lp_ErrMess[] = "Error number of fragments returned is 0"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -3; } lv_FragmentOffset -= 1; } STFS_FragmentFileMetadata *lp_Ffm = lp_Efm->GetFragment(lv_FragmentOffset); if(!lp_Ffm) { errno = ENOENT; char lp_ErrMess[] = "Error obtaining fragment"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -4; } STFS_ExternalFileHandle *lp_Efh = lp_Efm->Open(true); if (!lp_Efh) { // TBD cleanup errno = ENOENT; char lp_ErrMess[] = "Error allocating EFH"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -5; } lv_Ret = StoreOpenerInfo(lp_Efm, pv_OpenerNodeId, pv_OpenerPID, pp_OpenId); if (lv_Ret < 0) { //TBD cleanup errno = ENOENT; char lp_ErrMess[] = "Error storing opener information"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -6; } pp_Efm = lp_Efm; pp_Ffm = lp_Ffm; //Build Success Reply return 0; }
/////////////////////////////////////////////////////////////////////////////// /// // STFSd_mkstemp /// /// \brief Processes an mkstemp request /// - Generates an external file name /// /// \param int *pp_Ctemplate, /// \param int pv_OpenerNodeId, /// \param int pv_OpenerPID, /// \param STFS_ExternalFileMetadata *&pp_Efm, /// \param STFS_OpenIdentifier *&pp_OpenId) /// /// /////////////////////////////////////////////////////////////////////////////// int STFSd_mkstemp(char *pp_Ctemplate, int pv_OpenerNodeId, int pv_OpenerPID, STFS_ExternalFileMetadata *&pp_Efm, STFS_OpenIdentifier *&pp_OpenId) { ///////////////////////////////// /// parameter checking and housekeeping ///////////////////////////////// const char *WHERE = "STFSd_mkstemp"; STFS_ScopeTrace lv_st(WHERE); STFS_Session *lp_Session = STFS_Session::GetSession(); int lv_Ret = 0; if (!pp_Ctemplate) { errno = EFAULT; lp_Session->SetError(true, errno, 0, NULL, 0); return -1; } /// Generate the file name lv_Ret = STFS_util::GenerateExternalFilename(pp_Ctemplate); if (lv_Ret < 0) { errno = EINVAL; char lp_ErrMess[] = "Error generating external file name"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -2; } ///////////////////////////////// /// Reserve the name ///////////////////////////////// // We're the owning daemon process, so we need to reserve the name lv_Ret = STFS_File::ReserveName (pp_Ctemplate); if (lv_Ret<0) { errno = EIO; char lp_ErrMess[] = "Error while reserving name"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); //name exists? Couldn't talk to the disk? WhatEVer... Hope that //ReserveName packed the error correctly... return -6; } ///////////////////////////////// /// Create the EFM for the file ///////////////////////////////// STFS_ExternalFileMetadata *lp_Efm = new STFS_ExternalFileMetadata(pp_Ctemplate, STFS_util::GetMyNodeId()); if (lp_Efm == NULL) { //Could not find/allocate EFM, probably doesn't exist errno = ENOENT; char lp_ErrMess[] = "Error allocating EFM"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); //UhOh, couldn't allocate an EFM! Gotta free the directory we created STFS_File::ReleaseName (pp_Ctemplate); // return -7; } TRACE_PRINTF4(2, "FileName: %s, Opener Node Id: %d, Opener SQ PID: %d\n", lp_Efm->ExternalFileNameGet(), pv_OpenerNodeId, pv_OpenerPID); ///////////////////////////////// ///insert EFM in a global map ///////////////////////////////// lv_Ret = STFS_ExternalFileMetadata::InsertIntoContainer(lp_Efm); if (lv_Ret < 0) { //TBD cleanup //Could not insert into EFM Container... errno = ENOMEM; char lp_ErrMess[] = "Error Insertnig EFM into EFM Container"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -4; } ///////////////////////////////// /// Store the opener info in the EFM ///////////////////////////////// lv_Ret = StoreOpenerInfo(lp_Efm, pv_OpenerNodeId, pv_OpenerPID, pp_OpenId); if (lv_Ret < 0) { //TBD cleanup //Could not store opener information errno = ENOMEM; char lp_ErrMess[] = "Error storing opener information"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -5; } ///////////////////////////////// /// Create the fragment ///////////////////////////////// if (STFSd_createFragment(lp_Efm, pv_OpenerNodeId, pv_OpenerPID, 0) < 0) { //Could not create fragment errno = EIO; char lp_ErrMess[] = "Error creating fragment"; lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess)); return -3; } STFS_util::ValidateEFM(lp_Efm); pp_Efm = lp_Efm; return 0; }