SerCeMan / jnr-fuse

FUSE implementation in Java using Java Native Runtime (JNR)
MIT License
365 stars 87 forks source link

getattr on non-existing file return I/O error #44

Closed nelsonjr closed 6 years ago

nelsonjr commented 6 years ago

If you try to getattr() and it fails, e.g. file does not exist, according to C stat() it should return ENOENT. If the return of getattr() is not 0 the system receives I/O error.

Actual

$ ls -l /mnt/myfuse/i-dont-exist
ls: cannot access '/mnt/myfuse/i-dont-exist': Input/output error

Expected

$ ls -l /mnt/myfuse/i-dont-exist
ls: cannot access '/mnt/myfuse/i-dont-exist': No such file or directory

Sample Code

@Override
public int getattr(String path, FileStat stat) {
  try {
    ...
  } catch (FileNotFoundException e) {
    return -ErrorCodes.ENOENT();
  }
}

Logs

unique: 5, opcode: LOOKUP (1), nodeid: 1, insize: 53, pid: 23107
LOOKUP /i-dont-exist
getattr /i-dont-exist

   NODEID: 4
   unique: 5, success, outsize: 144
SerCeMan commented 6 years ago

Hi, @nelsonjr!

Are you sure that you're actually returning -ENOENT? You've attached logs which are saying that the operation was completed successfully, whereas If you returned -ENOENT() the logs would look like

LOOKUP /i-dont-exist
getattr /i-dont-exist
   unique: 4, error: -2 (No such file or directory), outsize: 16
nelsonjr commented 6 years ago

Thanks @SerCeMan! Hmmm, would you look at this... I was using your ru.serce.jnrfuse.ErrorCodes class by running return -ErrorCodes.ENOENT(). But ErrorCodes was throwing an exception, and because it was a return statement I thought it was just returning it. So no issue here after all! Thanks!

SerCeMan commented 6 years ago

Maybe I misunderstood you, but ErrorCodes should never throw an exception.

Github-uckYour2FA commented 6 months ago

Hi. I had input/output errors too. No mkdir success, even MemoryFS example didn't work. This is because of constants level error because I didn't import all the dependencies (I do it manually).

    @Override
    public int getattr(String path, FileStat stat) {
        System.out.printf("---- getattr %s\n", path);

will print you ---- getattr... But, if you add -ErrorCodes.ENOENT()

    @Override
    public int getattr(String path, FileStat stat) {
        System.out.printf("---- getattr %s %d\n", path, -ErrorCodes.ENOENT());

console/stderr tells you that getattr just done. Why? This is because the print call just can't done because of error. But you can't see these errors.

It would be nice if jnr-fuse somehow re-threw the error. Or just don't return a success state in case of error. (Maybe a special error code indicating Java errors would be useful?)

I solved the problem by adding jnr-constants from Maven. Now seems the library works.

Thanks for the library UwU