diff --git a/src/s3fs.cpp b/src/s3fs.cpp index aafd78a..f40d7d4 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -744,13 +744,26 @@ static int create_file_object(const char* path, mode_t mode, uid_t uid, gid_t gi return s3fscurl.PutRequest(path, meta, -1, false); // fd=-1 means for creating zero byte object. } -static int s3fs_mknod(const char* path, mode_t mode, dev_t rdev) +static int s3fs_mknod(const char *path, mode_t mode, dev_t rdev) { - FGPRINT("s3fs_mknod[path=%s][mode=%d]\n", path, mode); + int result; + headers_t meta; + struct fuse_context* pcxt; - // Could not make block or character special files on S3, - // always return a error. - return -EPERM; + FGPRINT("s3fs_mknod[path=%s][mode=0%o][dev=%lu]\n", path, mode, rdev); + + if(NULL == (pcxt = fuse_get_context())){ + return -EIO; + } + + if(0 != (result = create_file_object(path, mode, pcxt->uid, pcxt->gid))){ + FGPRINT("s3fs_mknod: could not create object for special file(result=%d)\n", result); + SYSLOGERR("could not create object for special file(result=%d)", result); + return result; + } + StatCache::getStatCacheData()->DelStat(path); + + return result; } static int s3fs_create(const char* path, mode_t mode, struct fuse_file_info* fi) diff --git a/src/s3fs_util.cpp b/src/s3fs_util.cpp index 42ee761..e766576 100644 --- a/src/s3fs_util.cpp +++ b/src/s3fs_util.cpp @@ -647,34 +647,39 @@ mode_t get_mode(headers_t& meta, const char* path, bool checkdir, bool forcedir) isS3sync = true; } } - if(!isS3sync){ - if(checkdir){ - if(forcedir){ - mode |= S_IFDIR; - }else{ - if(meta.end() != (iter = meta.find("Content-Type"))){ - string strConType = (*iter).second; - if(strConType == "application/x-directory"){ - mode |= S_IFDIR; - }else if(path && 0 < strlen(path) && '/' == path[strlen(path) - 1]){ - if(strConType == "binary/octet-stream" || strConType == "application/octet-stream"){ + // Checking the bitmask, if the last 3 bits are all zero then process as a regular + // file type (S_IFDIR or S_IFREG), otherwise return mode unmodified so that S_IFIFO, + // S_IFSOCK, S_IFCHR, S_IFLNK and S_IFBLK devices can be processed properly by fuse. + if(!(mode & S_IFMT)){ + if(!isS3sync){ + if(checkdir){ + if(forcedir){ + mode |= S_IFDIR; + }else{ + if(meta.end() != (iter = meta.find("Content-Type"))){ + string strConType = (*iter).second; + if(strConType == "application/x-directory"){ mode |= S_IFDIR; + }else if(path && 0 < strlen(path) && '/' == path[strlen(path) - 1]){ + if(strConType == "binary/octet-stream" || strConType == "application/octet-stream"){ + mode |= S_IFDIR; + }else{ + mode |= S_IFREG; + } }else{ mode |= S_IFREG; } }else{ mode |= S_IFREG; } - }else{ - mode |= S_IFREG; } } - } - }else{ - if(!checkdir){ - // cut dir/reg flag. - mode &= ~S_IFDIR; - mode &= ~S_IFREG; + }else{ + if(!checkdir){ + // cut dir/reg flag. + mode &= ~S_IFDIR; + mode &= ~S_IFREG; + } } } return mode;