if (atomic_dec_and_test(&ff->count)) {
                struct fuse_req *req = ff->reserved_req;
 
-               if (sync) {
+               if (ff->fc->no_open) {
+                       /*
+                        * Drop the release request when client does not
+                        * implement 'open'
+                        */
+                       req->background = 0;
+                       path_put(&req->misc.release.path);
+                       fuse_put_request(ff->fc, req);
+               } else if (sync) {
                        req->background = 0;
                        fuse_request_send(ff->fc, req);
                        path_put(&req->misc.release.path);
 int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
                 bool isdir)
 {
-       struct fuse_open_out outarg;
        struct fuse_file *ff;
-       int err;
        int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
 
        ff = fuse_file_alloc(fc);
        if (!ff)
                return -ENOMEM;
 
-       err = fuse_send_open(fc, nodeid, file, opcode, &outarg);
-       if (err) {
-               fuse_file_free(ff);
-               return err;
+       ff->fh = 0;
+       ff->open_flags = FOPEN_KEEP_CACHE; /* Default for no-open */
+       if (!fc->no_open || isdir) {
+               struct fuse_open_out outarg;
+               int err;
+
+               err = fuse_send_open(fc, nodeid, file, opcode, &outarg);
+               if (!err) {
+                       ff->fh = outarg.fh;
+                       ff->open_flags = outarg.open_flags;
+
+               } else if (err != -ENOSYS || isdir) {
+                       fuse_file_free(ff);
+                       return err;
+               } else {
+                       fc->no_open = 1;
+               }
        }
 
        if (isdir)
-               outarg.open_flags &= ~FOPEN_DIRECT_IO;
+               ff->open_flags &= ~FOPEN_DIRECT_IO;
 
-       ff->fh = outarg.fh;
        ff->nodeid = nodeid;
-       ff->open_flags = outarg.open_flags;
        file->private_data = fuse_file_get(ff);
 
        return 0;