Skip to content

Commit

Permalink
Allow stating a file just created
Browse files Browse the repository at this point in the history
  • Loading branch information
iychoi committed Mar 16, 2022
1 parent a6cafeb commit 3d8b62f
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 82 deletions.
4 changes: 1 addition & 3 deletions fs/file_handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/cyverse/go-irodsclient/irods/types"
)

// FileHandle ...
// FileHandle is a handle for a file opened
type FileHandle struct {
id string
filesystem *FileSystem
Expand Down Expand Up @@ -285,8 +285,6 @@ func (handle *FileHandle) postprocessRename(newPath string, newEntry *Entry) err
if handle.offset != newOffset {
return fmt.Errorf("failed to seek to %d", handle.offset)
}

fmt.Printf("postprocessRename seeked - %s, offset %d\n", newPath, handle.offset)
}

fileHandle := &FileHandle{
Expand Down
82 changes: 43 additions & 39 deletions fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -673,8 +673,6 @@ func (fs *FileSystem) preprocessRenameFileHandle(srcPath string) ([]*FileHandle,
handles := fs.fileHandleMap.PopByPath(srcPath)
handlesLocked := []*FileHandle{}

fmt.Printf("preprocess rename - %s\n", srcPath)

errs := []error{}
for _, handle := range handles {
// lock handles
Expand Down Expand Up @@ -717,14 +715,12 @@ func (fs *FileSystem) preprocessRenameFileHandleForDir(srcPath string) ([]*FileH
}

func (fs *FileSystem) postprocessRenameFileHandle(handles []*FileHandle, conn *connection.IRODSConnection, destPath string) error {
newEntry, err := fs.getDataObjectWithConnectin(conn, destPath)
newEntry, err := fs.getDataObjectWithConnection(conn, destPath)
if err != nil {
return err
}

errs := []error{}
fmt.Printf("postprocess rename - %s\n", destPath)

for _, handle := range handles {
err := handle.postprocessRename(destPath, newEntry)
if err != nil {
Expand Down Expand Up @@ -755,7 +751,7 @@ func (fs *FileSystem) postprocessRenameFileHandleForDir(handles []*FileHandle, c
errs = append(errs, err)
} else {
destFullPath := util.JoinPath(destPath, relPath)
newEntry, err := fs.getDataObjectWithConnectin(conn, destFullPath)
newEntry, err := fs.getDataObjectWithConnection(conn, destFullPath)
if err != nil {
errs = append(errs, err)
} else {
Expand Down Expand Up @@ -1181,7 +1177,7 @@ func (fs *FileSystem) OpenFile(path string, resource string, mode string) (*File
var entry *Entry = nil
if types.IsFileOpenFlagOpeningExisting(types.FileOpenMode(mode)) {
// file may exists
entryExisting, err := fs.getDataObject(irodsPath)
entryExisting, err := fs.getDataObjectWithConnection(conn, irodsPath)
if err == nil {
entry = entryExisting
}
Expand Down Expand Up @@ -1227,33 +1223,41 @@ func (fs *FileSystem) CreateFile(path string, resource string, mode string) (*Fi
return nil, err
}

// create
handle, err := irods_fs.CreateDataObject(conn, irodsPath, resource, mode, true)
if err != nil {
fs.session.ReturnConnection(conn)
return nil, err
}

// do not return connection here
entry := &Entry{
ID: 0,
Type: FileEntry,
Name: util.GetIRODSPathFileName(irodsPath),
Path: irodsPath,
Owner: fs.account.ClientUser,
Size: 0,
CreateTime: time.Now(),
ModifyTime: time.Now(),
CheckSum: "",
Internal: nil,
// close - this is required to let other processes see the file existence
err = irods_fs.CloseDataObject(conn, handle)
if err != nil {
fs.session.ReturnConnection(conn)
return nil, err
}

entry, err := fs.getDataObjectWithConnectionNoCache(conn, irodsPath)
if err != nil {
fs.session.ReturnConnection(conn)
return nil, err
}

// re-open
handle, offset, err := irods_fs.OpenDataObject(conn, irodsPath, resource, mode)
if err != nil {
fs.session.ReturnConnection(conn)
return nil, err
}

// do not return connection here
fileHandle := &FileHandle{
id: xid.New().String(),
filesystem: fs,
connection: conn,
irodsfilehandle: handle,
entry: entry,
offset: 0,
offset: offset,
openmode: types.FileOpenMode(mode),
}

Expand Down Expand Up @@ -1501,32 +1505,19 @@ func (fs *FileSystem) searchEntriesByMeta(metaName string, metaValue string) ([]
return entries, nil
}

// getDataObjectWithConnectin returns an entry for data object
func (fs *FileSystem) getDataObjectWithConnectin(conn *connection.IRODSConnection, path string) (*Entry, error) {
if fs.cache.HasNegativeEntryCache(path) {
return nil, types.NewFileNotFoundErrorf("could not find a data object")
}

// check cache first
cachedEntry := fs.cache.GetEntryCache(path)
if cachedEntry != nil && cachedEntry.Type == FileEntry {
return cachedEntry, nil
}

// otherwise, retrieve it and add it to cache
// getDataObjectWithConnectionNoCache returns an entry for data object
func (fs *FileSystem) getDataObjectWithConnectionNoCache(conn *connection.IRODSConnection, path string) (*Entry, error) {
// retrieve it and add it to cache
collection, err := fs.getCollection(util.GetIRODSPathDirname(path))
if err != nil {
return nil, err
}

fmt.Printf("getDataObjectWithConnectin check data object - %s\n", path)
dataobject, err := irods_fs.GetDataObjectMasterReplica(conn, collection.Internal.(*types.IRODSCollection), util.GetIRODSPathFileName(path))
if err != nil {
return nil, err
}

fmt.Printf("getDataObjectWithConnectin check data object found - %s\n", path)

if dataobject.ID > 0 {
entry := &Entry{
ID: dataobject.ID,
Expand All @@ -1550,6 +1541,22 @@ func (fs *FileSystem) getDataObjectWithConnectin(conn *connection.IRODSConnectio
return nil, types.NewFileNotFoundErrorf("could not find a data object")
}

// getDataObjectWithConnection returns an entry for data object
func (fs *FileSystem) getDataObjectWithConnection(conn *connection.IRODSConnection, path string) (*Entry, error) {
if fs.cache.HasNegativeEntryCache(path) {
return nil, types.NewFileNotFoundErrorf("could not find a data object")
}

// check cache first
cachedEntry := fs.cache.GetEntryCache(path)
if cachedEntry != nil && cachedEntry.Type == FileEntry {
return cachedEntry, nil
}

// otherwise, retrieve it and add it to cache
return fs.getDataObjectWithConnectionNoCache(conn, path)
}

// getDataObjectNoCache returns an entry for data object
func (fs *FileSystem) getDataObjectNoCache(path string) (*Entry, error) {
// retrieve it and add it to cache
Expand All @@ -1564,14 +1571,11 @@ func (fs *FileSystem) getDataObjectNoCache(path string) (*Entry, error) {
}
defer fs.session.ReturnConnection(conn)

fmt.Printf("getDataObjectNoCache check data object - %s\n", path)
dataobject, err := irods_fs.GetDataObjectMasterReplica(conn, collection.Internal.(*types.IRODSCollection), util.GetIRODSPathFileName(path))
if err != nil {
return nil, err
}

fmt.Printf("getDataObjectNoCache check data object found - %s\n", path)

if dataobject.ID > 0 {
entry := &Entry{
ID: dataobject.ID,
Expand Down
3 changes: 2 additions & 1 deletion irods/common/api_number.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ const (
AUTH_PLUG_REQ_AN APINumber = 1201
AUTH_PLUG_RESP_AN APINumber = 1202

ATOMIC_APPLY_METADATA_OPERATIONS_APN APINumber = 20002
GET_FILE_DESCRIPTOR_INFO_APN APINumber = 20000
ATOMIC_APPLY_METADATA_OPERATIONS_APN APINumber = 20002
REPLICA_CLOSE_APN APINumber = 20004
TOUCH_APN APINumber = 20007
)
2 changes: 1 addition & 1 deletion test/server/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ services:
POSTGRESQL_USER: "irods"
POSTGRESQL_DATABASE: "ICAT"
irods:
image: cyverse/irods-test:v4.2.10
image: cyverse/irods-test:v4.2.11
container_name: irods_test
restart: always
ports:
Expand Down
Loading

0 comments on commit 3d8b62f

Please sign in to comment.