Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

truncate does not exist for nfsrods #178

Closed
boydwilson opened this issue May 12, 2023 · 13 comments
Closed

truncate does not exist for nfsrods #178

boydwilson opened this issue May 12, 2023 · 13 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@boydwilson
Copy link

example to reproduce:

$echo hello, world > file
$echo goodbye > file
$cat file
goodbye
orld

@korydraughn
Copy link
Collaborator

This is going to depend on how nfs4j uses the VFS implementation to achieve truncation. The NFSRODS VFS implementation as of today does not provide any direct truncation operations, therefore the results you're seeing are expected because the write operation always opens the data object for reading and writing (i.e. it never truncates). The write operation only overwrites bytes.

See the following.

@Override
public WriteResult write(Inode _inode, byte[] _data, long _offset, int _count, StabilityLevel _stabilityLevel)
throws IOException
{
log_.debug("vfs::write");
try
{
Path path = getPath(toInodeNumber(_inode));
log_.debug("""
write - _inode path = {}
write - _data.length = {}
write - _offset = {}
write - _count = {}""",
path, _data.length, _offset, _count);
IRODSAccount acct = getCurrentIRODSUser().getAccount();
// NFS will attempt to write large files in parallel by calling
// the write operation from multiple threads. This will result in
// an error if old stat information is used across multiple writes.
// We remove any cached stat object for the path to avoid this.
statObjectCache_.remove(acct.getUserName() + "_" + path.toString());
// Because iRODS timestamps are stored in seconds, operations that trigger
// an mtime update may not be detected by NFSRODS if the operations happen
// within the same second.
//
// To get around this limitation, NFSRODS must manually clear this cache
// so that the user sees the updates.
listOpCache_.remove(acct.getUserName() + "#" + path.getParent().toString());
IRODSFileFactory ff = factory_.getIRODSFileFactory(acct);
final var coordinated = true;
IRODSRandomAccessFile file = ff.instanceIRODSRandomAccessFile(path.toString(), OpenFlags.READ_WRITE, coordinated);
try (AutoClosedIRODSRandomAccessFile ac = new AutoClosedIRODSRandomAccessFile(file))
{
file.seek(_offset, FileIOOperations.SeekWhenceType.SEEK_START);
file.write(_data, 0, _count);
return new WriteResult(StabilityLevel.FILE_SYNC, _count);
}
}
catch (IOException | JargonException e)
{
log_.error(e.getMessage());
throw new IOException(e);
}
finally
{
closeCurrentConnection();
}
}

Is the sequence of operations required for what you're trying to achieve?

@boydwilson
Copy link
Author

We are implementing nfsrods mounts that are accessed by applications that do things like this. We ran into this with VS Code Server when a file is made shorter from within the editor then the original contents remain after saving (at the end of the file)
.

@korydraughn
Copy link
Collaborator

Sure. We'll investigate as soon as we can.

@boydwilson
Copy link
Author

thank you!

@boydwilson
Copy link
Author

boydwilson commented May 22, 2023

So I had a thought and maybe this should be sent to the mailing list, but we are just trying to provide a mount for multiple users (not a single user or we could have used the fuse module), but if there is another approach we are open to ideas.

@korydraughn
Copy link
Collaborator

korydraughn commented May 22, 2023

It really depends on what your users need. If your users are running shell scripts, then NFSRODS is the right tool (at this time).

We may be able to add support for truncation by modifying the following.

@Override
public void setattr(Inode _inode, Stat _stat) throws IOException
{
log_.debug("""
vfs::setattr
setattr - _inode = {}
setattr - _stat = {}""",
getPath(toInodeNumber(_inode)), _stat);
if (_stat.isDefined(Stat.StatAttribute.MODE))
{
log_.warn("setattr - Adjusting the mode is not supported");
}
if (_stat.isDefined(Stat.StatAttribute.SIZE))
{
log_.warn("setattr - Adjusting the size is not supported");
}
}

I believe we originally supported truncation, but it was removed for some reason. I'm going to see if I can track that down. Perhaps it can be supported with recent versions of iRODS.

I'll let you know what I find.

@boydwilson
Copy link
Author

boydwilson commented May 22, 2023

@korydraughn
Copy link
Collaborator

I believe the challenge with that implementation of truncate was that it was slow.

The best solution is to add native support for truncation to the iRODS server. Obviously that doesn't help you today, but it would in the long run.

Until we have native support in the iRODS server, I believe your only option with NFSRODS is to remove the data object before writing. Alternatively, you introduce a second tool/GUI that users can use for those cases which NFSRODS cannot handle (yet).

@boydwilson
Copy link
Author

makes sense thx.

@boydwilson
Copy link
Author

So we took the truncate code from 0.8.0 and put it in the latest and it does seem to fix the truncate cases, it does seem slow, but only seems slow for things that would otherwise be broken (with not very scientific tests). Do you recall any cases where it impacted non-truncate needed code? (We still agree that it should be in the core of iRODS), just not sure if you want us to push our pulling it forward?

@korydraughn
Copy link
Collaborator

korydraughn commented May 25, 2023

One thing that may matter to you is that implementation will result in the data id changing. If you rely on consistent data ids, then you're going to run into problems.

Also, if you're running the latest version of NFSRODS, remember that it caches various pieces of information about data objects, etc. You'll need to think through if any of the caches need to be cleared for the data object being truncated. I suspect you'll need to remove the cached Stat object for that data object at the very least.

Please make sure to test things before deploying to production.

Other than that, feel free to modify your clone as you see fit. We'll look into adding support for truncate to the iRODS server in a later release. Most likely 4.3.2.

@boydwilson
Copy link
Author

We are only deploying at the POC stage, this project won't go prod until after 4.3.2 I imagine, but thank you for the heads up on those items.

@korydraughn
Copy link
Collaborator

Got it. Let us know how it goes.

@trel trel changed the title It seems that truncate does not work properly through nfsrods truncate does not exist for nfsrods Oct 13, 2023
@korydraughn korydraughn added this to the 2.3.0 milestone Feb 1, 2024
@korydraughn korydraughn self-assigned this May 17, 2024
@trel trel added the enhancement New feature or request label May 20, 2024
korydraughn added a commit to korydraughn/irods_client_nfsrods that referenced this issue May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

No branches or pull requests

3 participants