Skip to content

Mount over NFS can't create files #11

@mcadam

Description

@mcadam

Hello,

I have been trying to use the Fuse mount over NFS lately and am facing an issue.
When trying to create a file, NFS will send the operation mknod and not create as what we get when creating a file directly from the Fuse mount.

I tried to implement the mknod operation in the code by reusing how we create a new file but following the spec for mknod basically.

I have this:

    void mknod(fuse_req_t req, fuse_ino_t parent_ino, const char *name, mode_t mode, dev_t rdev) {
        Account *account = getAccount(req);
        GDriveObject parent = getObjectFromInodeAndReq(req, parent_ino);
        if (parent) {
            if (!parent->getIsFolder()) {
                int reply_err = fuse_reply_err(req, ENOTDIR);
                while(reply_err != 0){
                    reply_err = fuse_reply_err(req, ENOTDIR);
                }
                return;
            }
        } else {
            int reply_err = fuse_reply_err(req, ENOENT);
            while(reply_err != 0){
                reply_err = fuse_reply_err(req, ENOENT);
            }
            return;
        }

        if( strchr(name, '/') != nullptr){
            LOG(ERROR) << "File with a forward slash is illegal: " << name;
            int reply_err = fuse_reply_err(req, EINVAL);
            while(reply_err != 0){
                reply_err = fuse_reply_err(req, EINVAL);
            }
            return;
        }

        for (auto child: parent->children) {
            if (child->getName().compare(name) == 0) {
                LOG(INFO) << "When creating file with name " << name << " parentId " << parent->getId() << " already existed";
                int reply_err = fuse_reply_err(req, EEXIST);
                while(reply_err != 0){
                    reply_err = fuse_reply_err(req, EEXIST);
                }
                return;
            }
        }

        LOG(INFO) << "Creating file with name " << name << " and parent Id " << parent->getId();

        GDriveObject child = account->createNewChild(parent, name, mode, true);
        struct fuse_entry_param e;
        memset(&e, 0, sizeof(struct fuse_entry_param));

        e.ino = child->attribute.st_ino;
        e.generation = timeSinceEpochMillisec();
        e.attr = child->attribute;
        e.attr_timeout = 300;
        e.entry_timeout = 300;
        child->lookupCount.fetch_add(1, std::memory_order_relaxed);

        int reply_err = fuse_reply_entry(req, &e);
        while(reply_err != 0){
            reply_err = fuse_reply_entry(req, &e);
        }
    }

Compile alright, but when creating the file and then listing the current directory with the new file I get an error:

/mnt/nfs/gdrive/media # touch worldd
/mnt/nfs/gdrive/media # ls -l
ls: ./worldd: No such file or directory
total 0
drwxrwxrwx 2526 root     root          4096 Mar 13  2017 movies
drwxrwxrwx    1 root     root          4096 Sep 10 00:55 music
drwxrwxrwx  299 root     root          4096 Mar 13  2017 tvshows

Any help would be appreciated :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions