EricTheMagician / DriveFS

A google drive fuse filesystem implemented in C++
Mozilla Public License 2.0
63 stars 7 forks source link

Mount over NFS can't create files #11

Open mcadam opened 5 years ago

mcadam commented 5 years ago

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 :)