⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pvfs_open.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
	f->handle->have_opendb_entry = true;	if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {		oplock_granted = OPLOCK_BATCH;	} else if (oplock_granted != OPLOCK_NONE) {		status = pvfs_setup_oplock(f, oplock_granted);		if (!NT_STATUS_IS_OK(status)) {			talloc_free(lck);			return status;		}	}	stream_existed = name->stream_exists;	/* if this was a stream create then create the stream as well */	if (!name->stream_exists) {		status = pvfs_stream_create(pvfs, f->handle->name, fd);		if (!NT_STATUS_IS_OK(status)) {			talloc_free(lck);			return status;		}		if (stream_truncate) {			status = pvfs_stream_truncate(pvfs, f->handle->name, fd, 0);			if (!NT_STATUS_IS_OK(status)) {				talloc_free(lck);				return status;			}		}	}	/* re-resolve the open fd */	status = pvfs_resolve_name_fd(f->pvfs, fd, f->handle->name);	if (!NT_STATUS_IS_OK(status)) {		talloc_free(lck);		return status;	}	if (f->handle->name->stream_id == 0 &&	    (io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE ||	     io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE_IF)) {		/* for overwrite we need to replace file permissions */		uint32_t attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE;		mode_t mode = pvfs_fileperms(pvfs, attrib);		if (fchmod(fd, mode) == -1) {			talloc_free(lck);			return pvfs_map_errno(pvfs, errno);		}		name->dos.alloc_size = io->ntcreatex.in.alloc_size;		name->dos.attrib = attrib;		status = pvfs_dosattrib_save(pvfs, name, fd);		if (!NT_STATUS_IS_OK(status)) {			talloc_free(lck);			return status;		}	}	    	talloc_free(lck);	status = ntvfs_handle_set_backend_data(h, ntvfs, f);	NT_STATUS_NOT_OK_RETURN(status);	/* mark the open as having completed fully, so delete on close	   can now be used */	f->handle->open_completed     = true;	io->generic.out.oplock_level  = oplock_granted;	io->generic.out.file.ntvfs    = h;	io->generic.out.create_action = stream_existed?		create_action:NTCREATEX_ACTION_CREATED;		io->generic.out.create_time   = name->dos.create_time;	io->generic.out.access_time   = name->dos.access_time;	io->generic.out.write_time    = name->dos.write_time;	io->generic.out.change_time   = name->dos.change_time;	io->generic.out.attrib        = name->dos.attrib;	io->generic.out.alloc_size    = name->dos.alloc_size;	io->generic.out.size          = name->st.st_size;	io->generic.out.file_type     = FILE_TYPE_DISK;	io->generic.out.ipc_state     = 0;	io->generic.out.is_directory  = 0;	return NT_STATUS_OK;}/*  close a file*/NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs,		    struct ntvfs_request *req, union smb_close *io){	struct pvfs_state *pvfs = ntvfs->private_data;	struct pvfs_file *f;	struct utimbuf unix_times;	if (io->generic.level == RAW_CLOSE_SPLCLOSE) {		return NT_STATUS_DOS(ERRSRV, ERRerror);	}	if (io->generic.level != RAW_CLOSE_GENERIC) {		return ntvfs_map_close(ntvfs, req, io);	}	f = pvfs_find_fd(pvfs, req, io->generic.in.file.ntvfs);	if (!f) {		return NT_STATUS_INVALID_HANDLE;	}	if (!null_time(io->generic.in.write_time)) {		unix_times.actime = 0;		unix_times.modtime = io->close.in.write_time;		utime(f->handle->name->full_name, &unix_times);	}	if (io->generic.in.flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) {		struct pvfs_filename *name;		NTSTATUS status;		struct pvfs_file_handle *h = f->handle;		status = pvfs_resolve_name_handle(pvfs, h);		if (!NT_STATUS_IS_OK(status)) {			return status;		}		name = h->name;		io->generic.out.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION;		io->generic.out.create_time = name->dos.create_time;		io->generic.out.access_time = name->dos.access_time;		io->generic.out.write_time  = name->dos.write_time;		io->generic.out.change_time = name->dos.change_time;		io->generic.out.alloc_size  = name->dos.alloc_size;		io->generic.out.size        = name->st.st_size;		io->generic.out.file_attr   = name->dos.attrib;			} else {		ZERO_STRUCT(io->generic.out);	}	talloc_free(f);	return NT_STATUS_OK;}/*  logoff - close all file descriptors open by a vuid*/NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs,		     struct ntvfs_request *req){	struct pvfs_state *pvfs = ntvfs->private_data;	struct pvfs_file *f, *next;	for (f=pvfs->files.list;f;f=next) {		next = f->next;		if (f->ntvfs->session_info == req->session_info) {			talloc_free(f);		}	}	return NT_STATUS_OK;}/*  exit - close files for the current pid*/NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs,		   struct ntvfs_request *req){	struct pvfs_state *pvfs = ntvfs->private_data;	struct pvfs_file *f, *next;	for (f=pvfs->files.list;f;f=next) {		next = f->next;		if (f->ntvfs->session_info == req->session_info &&		    f->ntvfs->smbpid == req->smbpid) {			talloc_free(f);		}	}	return NT_STATUS_OK;}/*  change the delete on close flag on an already open file*/NTSTATUS pvfs_set_delete_on_close(struct pvfs_state *pvfs,				  struct ntvfs_request *req, 				  struct pvfs_file *f, bool del_on_close){	struct odb_lock *lck;	NTSTATUS status;	if ((f->handle->name->dos.attrib & FILE_ATTRIBUTE_READONLY) && del_on_close) {		return NT_STATUS_CANNOT_DELETE;	}		if ((f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&	    !pvfs_directory_empty(pvfs, f->handle->name)) {		return NT_STATUS_DIRECTORY_NOT_EMPTY;	}	if (del_on_close) {		f->handle->create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;	} else {		f->handle->create_options &= ~NTCREATEX_OPTIONS_DELETE_ON_CLOSE;	}		lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key);	if (lck == NULL) {		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	status = odb_set_delete_on_close(lck, del_on_close);	talloc_free(lck);	return status;}/*  determine if a file can be deleted, or if it is prevented by an  already open file*/NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, 			 struct ntvfs_request *req,			 struct pvfs_filename *name,			 struct odb_lock **lckp){	NTSTATUS status;	DATA_BLOB key;	struct odb_lock *lck;	uint32_t share_access;	uint32_t access_mask;	bool delete_on_close;	status = pvfs_locking_key(name, name, &key);	if (!NT_STATUS_IS_OK(status)) {		return NT_STATUS_NO_MEMORY;	}	lck = odb_lock(req, pvfs->odb_context, &key);	if (lck == NULL) {		DEBUG(0,("Unable to lock opendb for can_delete\n"));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	share_access	= NTCREATEX_SHARE_ACCESS_READ |			  NTCREATEX_SHARE_ACCESS_WRITE |			  NTCREATEX_SHARE_ACCESS_DELETE;	access_mask	= SEC_STD_DELETE;	delete_on_close	= true;	status = odb_can_open(lck, name->stream_id,			      share_access, access_mask, delete_on_close,			      NTCREATEX_DISP_OPEN, false);	if (NT_STATUS_IS_OK(status)) {		status = pvfs_access_check_simple(pvfs, req, name, access_mask);	}	/*	 * if it's a sharing violation or we got no oplock	 * only keep the lock if the caller requested access	 * to the lock	 */	if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||	    NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {		if (lckp) {			*lckp = lck;		} else {			talloc_free(lck);		}	} else if (!NT_STATUS_IS_OK(status)) {		talloc_free(lck);		if (lckp) {			*lckp = NULL;		}	} else if (lckp) {		*lckp = lck;	}	return status;}/*  determine if a file can be renamed, or if it is prevented by an  already open file*/NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, 			 struct ntvfs_request *req,			 struct pvfs_filename *name,			 struct odb_lock **lckp){	NTSTATUS status;	DATA_BLOB key;	struct odb_lock *lck;	uint32_t share_access;	uint32_t access_mask;	bool delete_on_close;	status = pvfs_locking_key(name, name, &key);	if (!NT_STATUS_IS_OK(status)) {		return NT_STATUS_NO_MEMORY;	}	lck = odb_lock(req, pvfs->odb_context, &key);	if (lck == NULL) {		DEBUG(0,("Unable to lock opendb for can_stat\n"));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	share_access	= NTCREATEX_SHARE_ACCESS_READ |			  NTCREATEX_SHARE_ACCESS_WRITE;	access_mask	= SEC_STD_DELETE;	delete_on_close	= false;	status = odb_can_open(lck, name->stream_id,			      share_access, access_mask, delete_on_close,			      NTCREATEX_DISP_OPEN, false);	/*	 * if it's a sharing violation or we got no oplock	 * only keep the lock if the caller requested access	 * to the lock	 */	if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||	    NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {		if (lckp) {			*lckp = lck;		} else {			talloc_free(lck);		}	} else if (!NT_STATUS_IS_OK(status)) {		talloc_free(lck);		if (lckp) {			*lckp = NULL;		}	} else if (lckp) {		*lckp = lck;	}	return status;}/*  determine if the file size of a file can be changed,  or if it is prevented by an already open file*/NTSTATUS pvfs_can_update_file_size(struct pvfs_state *pvfs,				   struct ntvfs_request *req,				   struct pvfs_filename *name,				   struct odb_lock **lckp){	NTSTATUS status;	DATA_BLOB key;	struct odb_lock *lck;	uint32_t share_access;	uint32_t access_mask;	bool break_to_none;	bool delete_on_close;	status = pvfs_locking_key(name, name, &key);	if (!NT_STATUS_IS_OK(status)) {		return NT_STATUS_NO_MEMORY;	}	lck = odb_lock(req, pvfs->odb_context, &key);	if (lck == NULL) {		DEBUG(0,("Unable to lock opendb for can_stat\n"));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	share_access	= NTCREATEX_SHARE_ACCESS_READ |			  NTCREATEX_SHARE_ACCESS_WRITE |			  NTCREATEX_SHARE_ACCESS_DELETE;	/*	 * I would have thought that we would need to pass	 * SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA here too	 *	 * But you only need SEC_FILE_WRITE_ATTRIBUTE permissions	 * to set the filesize.	 *	 * --metze	 */	access_mask	= SEC_FILE_WRITE_ATTRIBUTE;	delete_on_close	= false;	break_to_none	= true;	status = odb_can_open(lck, name->stream_id,			      share_access, access_mask, delete_on_close,			      NTCREATEX_DISP_OPEN, break_to_none);	/*	 * if it's a sharing violation or we got no oplock	 * only keep the lock if the caller requested access	 * to the lock	 */	if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||	    NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {		if (lckp) {			*lckp = lck;		} else {			talloc_free(lck);		}	} else if (!NT_STATUS_IS_OK(status)) {		talloc_free(lck);		if (lckp) {			*lckp = NULL;		}	} else if (lckp) {		*lckp = lck;	}	return status;}/*  determine if file meta data can be accessed, or if it is prevented by an  already open file*/NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, 		       struct ntvfs_request *req,		       struct pvfs_filename *name){	NTSTATUS status;	DATA_BLOB key;	struct odb_lock *lck;	uint32_t share_access;	uint32_t access_mask;	bool delete_on_close;	status = pvfs_locking_key(name, name, &key);	if (!NT_STATUS_IS_OK(status)) {		return NT_STATUS_NO_MEMORY;	}	lck = odb_lock(req, pvfs->odb_context, &key);	if (lck == NULL) {		DEBUG(0,("Unable to lock opendb for can_stat\n"));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	share_access	= NTCREATEX_SHARE_ACCESS_READ |			  NTCREATEX_SHARE_ACCESS_WRITE;	access_mask	= SEC_FILE_READ_ATTRIBUTE;	delete_on_close	= false;	status = odb_can_open(lck, name->stream_id,			      share_access, access_mask, delete_on_close,			      NTCREATEX_DISP_OPEN, false);	if (!NT_STATUS_IS_OK(status)) {		talloc_free(lck);	}	return status;}/*  determine if delete on close is set on */bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *h){	NTSTATUS status;	bool del_on_close;	status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, 					 &del_on_close);	if (!NT_STATUS_IS_OK(status)) {		DEBUG(1,("WARNING: unable to determine delete on close status for open file\n"));		return false;	}	return del_on_close;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -