You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							110 lines
						
					
					
						
							3.9 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							110 lines
						
					
					
						
							3.9 KiB
						
					
					
				| package mount | |
| 
 | |
| import ( | |
| 	"github.com/hanwen/go-fuse/v2/fuse" | |
| 	"github.com/seaweedfs/seaweedfs/weed/glog" | |
| ) | |
| 
 | |
| /** | |
| 	 * Open a file | |
| 	 * | |
| 	 * Open flags are available in fi->flags. The following rules | |
| 	 * apply. | |
| 	 * | |
| 	 *  - Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be | |
| 	 *    filtered out / handled by the kernel. | |
| 	 * | |
| 	 *  - Access modes (O_RDONLY, O_WRONLY, O_RDWR) should be used | |
| 	 *    by the filesystem to check if the operation is | |
| 	 *    permitted.  If the ``-o default_permissions`` mount | |
| 	 *    option is given, this check is already done by the | |
| 	 *    kernel before calling open() and may thus be omitted by | |
| 	 *    the filesystem. | |
| 	 * | |
| 	 *  - When writeback caching is enabled, the kernel may send | |
| 	 *    read requests even for files opened with O_WRONLY. The | |
| 	 *    filesystem should be prepared to handle this. | |
| 	 * | |
| 	 *  - When writeback caching is disabled, the filesystem is | |
| 	 *    expected to properly handle the O_APPEND flag and ensure | |
| 	 *    that each write is appending to the end of the file. | |
| 	 * | |
|          *  - When writeback caching is enabled, the kernel will | |
| 	 *    handle O_APPEND. However, unless all changes to the file | |
| 	 *    come through the kernel this will not work reliably. The | |
| 	 *    filesystem should thus either ignore the O_APPEND flag | |
| 	 *    (and let the kernel handle it), or return an error | |
| 	 *    (indicating that reliably O_APPEND is not available). | |
| 	 * | |
| 	 * Filesystem may store an arbitrary file handle (pointer, | |
| 	 * index, etc) in fi->fh, and use this in other all other file | |
| 	 * operations (read, write, flush, release, fsync). | |
| 	 * | |
| 	 * Filesystem may also implement stateless file I/O and not store | |
| 	 * anything in fi->fh. | |
| 	 * | |
| 	 * There are also some flags (direct_io, keep_cache) which the | |
| 	 * filesystem may set in fi, to change the way the file is opened. | |
| 	 * See fuse_file_info structure in <fuse_common.h> for more details. | |
| 	 * | |
| 	 * If this request is answered with an error code of ENOSYS | |
| 	 * and FUSE_CAP_NO_OPEN_SUPPORT is set in | |
| 	 * `fuse_conn_info.capable`, this is treated as success and | |
| 	 * future calls to open and release will also succeed without being | |
| 	 * sent to the filesystem process. | |
| 	 * | |
| 	 * Valid replies: | |
| 	 *   fuse_reply_open | |
| 	 *   fuse_reply_err | |
| 	 * | |
| 	 * @param req request handle | |
| 	 * @param ino the inode number | |
| 	 * @param fi file information | |
| */ | |
| func (wfs *WFS) Open(cancel <-chan struct{}, in *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Status) { | |
| 	var fileHandle *FileHandle | |
| 	fileHandle, status = wfs.AcquireHandle(in.NodeId, in.Flags, in.Uid, in.Gid) | |
| 	if status == fuse.OK { | |
| 		out.Fh = uint64(fileHandle.fh) | |
| 		out.OpenFlags = in.Flags | |
| 		if wfs.option.IsMacOs { | |
| 			// remove the direct_io flag, as it is not well-supported on macOS | |
| 			// https://code.google.com/archive/p/macfuse/wikis/OPTIONS.wiki recommended to avoid the direct_io flag | |
| 			if in.Flags&fuse.FOPEN_DIRECT_IO != 0 { | |
| 				glog.V(4).Infof("macfuse direct_io mode %v => false\n", in.Flags&fuse.FOPEN_DIRECT_IO != 0) | |
| 				out.OpenFlags &^= fuse.FOPEN_DIRECT_IO | |
| 			} | |
| 		} | |
| 		// TODO https://github.com/libfuse/libfuse/blob/master/include/fuse_common.h#L64 | |
| 	} | |
| 	return status | |
| } | |
| 
 | |
| /** | |
|  * Release an open file | |
|  * | |
|  * Release is called when there are no more references to an open | |
|  * file: all file descriptors are closed and all memory mappings | |
|  * are unmapped. | |
|  * | |
|  * For every open call there will be exactly one release call (unless | |
|  * the filesystem is force-unmounted). | |
|  * | |
|  * The filesystem may reply with an error, but error values are | |
|  * not returned to close() or munmap() which triggered the | |
|  * release. | |
|  * | |
|  * fi->fh will contain the value set by the open method, or will | |
|  * be undefined if the open method didn't set any value. | |
|  * fi->flags will contain the same flags as for open. | |
|  * | |
|  * Valid replies: | |
|  *   fuse_reply_err | |
|  * | |
|  * @param req request handle | |
|  * @param ino the inode number | |
|  * @param fi file information | |
|  */ | |
| func (wfs *WFS) Release(cancel <-chan struct{}, in *fuse.ReleaseIn) { | |
| 	wfs.ReleaseHandle(FileHandleId(in.Fh)) | |
| }
 |