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

📄 pvfs_setfileinfo.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
		}		h->mode = info->mode_information.in.mode;		break;	case RAW_SFILEINFO_RENAME_INFORMATION:	case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:		return pvfs_setfileinfo_rename(pvfs, req, h->name,					       &h->odb_locking_key,					       info);	case RAW_SFILEINFO_SEC_DESC:		notify_trigger(pvfs->notify_context, 			       NOTIFY_ACTION_MODIFIED, 			       FILE_NOTIFY_CHANGE_SECURITY,			       h->name->full_name);		return pvfs_acl_set(pvfs, req, h->name, h->fd, f->access_mask, info);	default:		return NT_STATUS_INVALID_LEVEL;	}	/* possibly change the file size */	if (newstats.st.st_size != h->name->st.st_size) {		if (h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) {			return NT_STATUS_FILE_IS_A_DIRECTORY;		}		if (h->name->stream_name) {			status = pvfs_stream_truncate(pvfs, h->name, h->fd, newstats.st.st_size);			if (!NT_STATUS_IS_OK(status)) {				return status;			}						change_mask |= FILE_NOTIFY_CHANGE_STREAM_SIZE;		} else {			int ret;			if (f->access_mask & 			    (SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA)) {				ret = ftruncate(h->fd, newstats.st.st_size);			} else {				ret = truncate(h->name->full_name, newstats.st.st_size);			}			if (ret == -1) {				return pvfs_map_errno(pvfs, errno);			}			change_mask |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_ATTRIBUTES;		}	}	/* possibly change the file timestamps */	ZERO_STRUCT(unix_times);	if (newstats.dos.create_time != h->name->dos.create_time) {		change_mask |= FILE_NOTIFY_CHANGE_CREATION;	}	if (newstats.dos.access_time != h->name->dos.access_time) {		unix_times.actime = nt_time_to_unix(newstats.dos.access_time);		change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS;	}	if (newstats.dos.write_time != h->name->dos.write_time) {		unix_times.modtime = nt_time_to_unix(newstats.dos.write_time);		change_mask |= FILE_NOTIFY_CHANGE_LAST_WRITE;	}	if (unix_times.actime != 0 || unix_times.modtime != 0) {		if (utime(h->name->full_name, &unix_times) == -1) {			return pvfs_map_errno(pvfs, errno);		}	}	/* possibly change the attribute */	if (newstats.dos.attrib != h->name->dos.attrib) {		mode_t mode;		if ((newstats.dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&		    !(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {			return NT_STATUS_INVALID_PARAMETER;		}		mode = pvfs_fileperms(pvfs, newstats.dos.attrib);		if (!(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {			if (fchmod(h->fd, mode) == -1) {				return pvfs_map_errno(pvfs, errno);			}		}		change_mask |= FILE_NOTIFY_CHANGE_ATTRIBUTES;	}	*h->name = newstats;	notify_trigger(pvfs->notify_context, 		       NOTIFY_ACTION_MODIFIED, 		       change_mask,		       h->name->full_name);	return pvfs_dosattrib_save(pvfs, h->name, h->fd);}/*  retry an open after a sharing violation*/static void pvfs_retry_setpathinfo(struct pvfs_odb_retry *r,				   struct ntvfs_module_context *ntvfs,				   struct ntvfs_request *req,				   void *_info,				   void *private_data,				   enum pvfs_wait_notice reason){	union smb_setfileinfo *info = talloc_get_type(_info,				      union smb_setfileinfo);	NTSTATUS status = NT_STATUS_INTERNAL_ERROR;	talloc_free(r);	switch (reason) {	case PVFS_WAIT_CANCEL:/*TODO*/		status = NT_STATUS_CANCELLED;		break;	case PVFS_WAIT_TIMEOUT:		/* if it timed out, then give the failure		   immediately *//*TODO*/		status = NT_STATUS_SHARING_VIOLATION;		break;	case PVFS_WAIT_EVENT:		/* try the open again, which could trigger another retry setup		   if it wants to, so we have to unmark the async flag so we		   will know if it does a second async reply */		req->async_states->state &= ~NTVFS_ASYNC_STATE_ASYNC;		status = pvfs_setpathinfo(ntvfs, req, info);		if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) {			/* the 2nd try also replied async, so we don't send			   the reply yet */			return;		}		/* re-mark it async, just in case someone up the chain does		   paranoid checking */		req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;		break;	}	/* send the reply up the chain */	req->async_states->status = status;	req->async_states->send_fn(req);}/*  setup for a unlink retry after a sharing violation  or a non granted oplock*/static NTSTATUS pvfs_setpathinfo_setup_retry(struct ntvfs_module_context *ntvfs,					     struct ntvfs_request *req,					     union smb_setfileinfo *info,					     struct odb_lock *lck,					     NTSTATUS status){	struct pvfs_state *pvfs = ntvfs->private_data;	struct timeval end_time;	if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {		end_time = timeval_add(&req->statistics.request_time,				       0, pvfs->sharing_violation_delay);	} else if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {		end_time = timeval_add(&req->statistics.request_time,				       pvfs->oplock_break_timeout, 0);	} else {		return NT_STATUS_INTERNAL_ERROR;	}	return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, info, NULL,				    pvfs_retry_setpathinfo);}/*  set info on a pathname*/NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,			  struct ntvfs_request *req, union smb_setfileinfo *info){	struct pvfs_state *pvfs = ntvfs->private_data;	struct pvfs_filename *name;	struct pvfs_filename newstats;	NTSTATUS status;	struct utimbuf unix_times;	uint32_t access_needed;	uint32_t change_mask = 0;	struct odb_lock *lck = NULL;	DATA_BLOB odb_locking_key;	/* resolve the cifs name to a posix name */	status = pvfs_resolve_name(pvfs, req, info->generic.in.file.path, 				   PVFS_RESOLVE_STREAMS, &name);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	if (!name->exists) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	access_needed = pvfs_setfileinfo_access(info);	status = pvfs_access_check_simple(pvfs, req, name, access_needed);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	/* we take a copy of the current file stats, then update	   newstats in each of the elements below. At the end we	   compare, and make any changes needed */	newstats = *name;	switch (info->generic.level) {	case RAW_SFILEINFO_SETATTR:		if (!null_time(info->setattr.in.write_time)) {			unix_to_nt_time(&newstats.dos.write_time, info->setattr.in.write_time);		}		if (info->setattr.in.attrib == 0) {			newstats.dos.attrib = FILE_ATTRIBUTE_NORMAL;		} else if (info->setattr.in.attrib != FILE_ATTRIBUTE_NORMAL) {			newstats.dos.attrib = info->setattr.in.attrib;		}  		break;	case RAW_SFILEINFO_SETATTRE:	case RAW_SFILEINFO_STANDARD:		if (!null_time(info->setattre.in.create_time)) {			unix_to_nt_time(&newstats.dos.create_time, info->setattre.in.create_time);		}		if (!null_time(info->setattre.in.access_time)) {			unix_to_nt_time(&newstats.dos.access_time, info->setattre.in.access_time);		}		if (!null_time(info->setattre.in.write_time)) {			unix_to_nt_time(&newstats.dos.write_time, info->setattre.in.write_time);		}  		break;	case RAW_SFILEINFO_EA_SET:		return pvfs_setfileinfo_ea_set(pvfs, name, -1, 					       info->ea_set.in.num_eas,					       info->ea_set.in.eas);	case RAW_SFILEINFO_BASIC_INFO:	case RAW_SFILEINFO_BASIC_INFORMATION:		if (!null_nttime(info->basic_info.in.create_time)) {			newstats.dos.create_time = info->basic_info.in.create_time;		}		if (!null_nttime(info->basic_info.in.access_time)) {			newstats.dos.access_time = info->basic_info.in.access_time;		}		if (!null_nttime(info->basic_info.in.write_time)) {			newstats.dos.write_time = info->basic_info.in.write_time;		}		if (!null_nttime(info->basic_info.in.change_time)) {			newstats.dos.change_time = info->basic_info.in.change_time;		}		if (info->basic_info.in.attrib != 0) {			newstats.dos.attrib = info->basic_info.in.attrib;		}  		break;	case RAW_SFILEINFO_ALLOCATION_INFO:	case RAW_SFILEINFO_ALLOCATION_INFORMATION:		status = pvfs_can_update_file_size(pvfs, req, name, &lck);		/*		 * on a sharing violation we need to retry when the file is closed by		 * the other user, or after 1 second		 * on a non granted oplock we need to retry when the file is closed by		 * the other user, or after 30 seconds		*/		if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||		     NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&		    (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {			return pvfs_setpathinfo_setup_retry(pvfs->ntvfs, req, info, lck, status);		}		NT_STATUS_NOT_OK_RETURN(status);		if (info->allocation_info.in.alloc_size > newstats.dos.alloc_size) {			/* strange. Increasing the allocation size via setpathinfo 			   should be silently ignored */			break;		}		newstats.dos.alloc_size = info->allocation_info.in.alloc_size;		if (newstats.dos.alloc_size < newstats.st.st_size) {			newstats.st.st_size = newstats.dos.alloc_size;		}		newstats.dos.alloc_size = pvfs_round_alloc_size(pvfs, 								newstats.dos.alloc_size);		break;	case RAW_SFILEINFO_END_OF_FILE_INFO:	case RAW_SFILEINFO_END_OF_FILE_INFORMATION:		status = pvfs_can_update_file_size(pvfs, req, name, &lck);		/*		 * on a sharing violation we need to retry when the file is closed by		 * the other user, or after 1 second		 * on a non granted oplock we need to retry when the file is closed by		 * the other user, or after 30 seconds		*/		if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||		     NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&		    (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {			return pvfs_setpathinfo_setup_retry(pvfs->ntvfs, req, info, lck, status);		}		NT_STATUS_NOT_OK_RETURN(status);		newstats.st.st_size = info->end_of_file_info.in.size;		break;	case RAW_SFILEINFO_MODE_INFORMATION:		if (info->mode_information.in.mode != 0 &&		    info->mode_information.in.mode != 2 &&		    info->mode_information.in.mode != 4 &&		    info->mode_information.in.mode != 6) {			return NT_STATUS_INVALID_PARAMETER;		}		return NT_STATUS_OK;	case RAW_SFILEINFO_RENAME_INFORMATION:	case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:		status = pvfs_locking_key(name, name, &odb_locking_key);		NT_STATUS_NOT_OK_RETURN(status);		status = pvfs_setfileinfo_rename(pvfs, req, name,						 &odb_locking_key, info);		NT_STATUS_NOT_OK_RETURN(status);		return NT_STATUS_OK;	case RAW_SFILEINFO_DISPOSITION_INFO:	case RAW_SFILEINFO_DISPOSITION_INFORMATION:	case RAW_SFILEINFO_POSITION_INFORMATION:		return NT_STATUS_OK;	default:		return NT_STATUS_INVALID_LEVEL;	}	/* possibly change the file size */	if (newstats.st.st_size != name->st.st_size) {		if (name->stream_name) {			status = pvfs_stream_truncate(pvfs, name, -1, newstats.st.st_size);			if (!NT_STATUS_IS_OK(status)) {				return status;			}		} else if (truncate(name->full_name, newstats.st.st_size) == -1) {			return pvfs_map_errno(pvfs, errno);		}		change_mask |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_ATTRIBUTES;	}	/* possibly change the file timestamps */	ZERO_STRUCT(unix_times);	if (newstats.dos.create_time != name->dos.create_time) {		change_mask |= FILE_NOTIFY_CHANGE_CREATION;	}	if (newstats.dos.access_time != name->dos.access_time) {		unix_times.actime = nt_time_to_unix(newstats.dos.access_time);		change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS;	}	if (newstats.dos.write_time != name->dos.write_time) {		unix_times.modtime = nt_time_to_unix(newstats.dos.write_time);		change_mask |= FILE_NOTIFY_CHANGE_LAST_WRITE;	}	if (unix_times.actime != 0 || unix_times.modtime != 0) {		if (utime(name->full_name, &unix_times) == -1) {			return pvfs_map_errno(pvfs, errno);		}	}	/* possibly change the attribute */	newstats.dos.attrib |= (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY);	if (newstats.dos.attrib != name->dos.attrib) {		mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib);		if (chmod(name->full_name, mode) == -1) {			return pvfs_map_errno(pvfs, errno);		}		change_mask |= FILE_NOTIFY_CHANGE_ATTRIBUTES;	}	*name = newstats;	if (change_mask != 0) {		notify_trigger(pvfs->notify_context, 			       NOTIFY_ACTION_MODIFIED, 			       change_mask,			       name->full_name);	}	return pvfs_dosattrib_save(pvfs, name, -1);}

⌨️ 快捷键说明

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