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.
		
		
		
		
		
			
		
			
				
					
					
						
							82 lines
						
					
					
						
							2.1 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							82 lines
						
					
					
						
							2.1 KiB
						
					
					
				| package mount | |
| 
 | |
| import ( | |
| 	"github.com/hanwen/go-fuse/v2/fuse" | |
| 	"github.com/seaweedfs/seaweedfs/weed/util" | |
| 	"net/http" | |
| 	"syscall" | |
| 	"time" | |
| ) | |
| 
 | |
| /** | |
|  * Write data | |
|  * | |
|  * Write should return exactly the number of bytes requested | |
|  * except on error.  An exception to this is when the file has | |
|  * been opened in 'direct_io' mode, in which case the return value | |
|  * of the write system call will reflect the return value of this | |
|  * operation. | |
|  * | |
|  * Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is | |
|  * expected to reset the setuid and setgid bits. | |
|  * | |
|  * fi->fh will contain the value set by the open method, or will | |
|  * be undefined if the open method didn't set any value. | |
|  * | |
|  * Valid replies: | |
|  *   fuse_reply_write | |
|  *   fuse_reply_err | |
|  * | |
|  * @param req request handle | |
|  * @param ino the inode number | |
|  * @param buf data to write | |
|  * @param size number of bytes to write | |
|  * @param off offset to write to | |
|  * @param fi file information | |
|  */ | |
| func (wfs *WFS) Write(cancel <-chan struct{}, in *fuse.WriteIn, data []byte) (written uint32, code fuse.Status) { | |
| 
 | |
| 	if wfs.IsOverQuota { | |
| 		return 0, fuse.Status(syscall.ENOSPC) | |
| 	} | |
| 
 | |
| 	fh := wfs.GetHandle(FileHandleId(in.Fh)) | |
| 	if fh == nil { | |
| 		return 0, fuse.ENOENT | |
| 	} | |
| 
 | |
| 	fh.dirtyPages.writerPattern.MonitorWriteAt(int64(in.Offset), int(in.Size)) | |
| 
 | |
| 	tsNs := time.Now().UnixNano() | |
| 
 | |
| 	fhActiveLock := fh.wfs.fhLockTable.AcquireLock("Write", fh.fh, util.ExclusiveLock) | |
| 	defer fh.wfs.fhLockTable.ReleaseLock(fh.fh, fhActiveLock) | |
| 
 | |
| 	entry := fh.GetEntry() | |
| 	if entry == nil { | |
| 		return 0, fuse.OK | |
| 	} | |
| 
 | |
| 	entry.Content = nil | |
| 	offset := int64(in.Offset) | |
| 	entry.Attributes.FileSize = uint64(max(offset+int64(len(data)), int64(entry.Attributes.FileSize))) | |
| 	// glog.V(4).Infof("%v write [%d,%d) %d", fh.f.fullpath(), req.Offset, req.Offset+int64(len(req.Data)), len(req.Data)) | |
|  | |
| 	fh.dirtyPages.AddPage(offset, data, fh.dirtyPages.writerPattern.IsSequentialMode(), tsNs) | |
| 
 | |
| 	written = uint32(len(data)) | |
| 
 | |
| 	if offset == 0 { | |
| 		// detect mime type | |
| 		fh.contentType = http.DetectContentType(data) | |
| 	} | |
| 
 | |
| 	fh.dirtyMetadata = true | |
| 
 | |
| 	if IsDebugFileReadWrite { | |
| 		// print("+") | |
| 		fh.mirrorFile.WriteAt(data, offset) | |
| 	} | |
| 
 | |
| 	return written, fuse.OK | |
| }
 |