1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 222c2961f8Sjose borrego * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23da6c28aaSamw * Use is subject to license terms. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw /* 27da6c28aaSamw * The flush SMB is sent to ensure all data and allocation information 28da6c28aaSamw * for the corresponding file has been written to stable storage. This 29da6c28aaSamw * is a synchronous request. The response should not be sent until the 30da6c28aaSamw * writes are complete. 31da6c28aaSamw * 32da6c28aaSamw * The SmbFlush request is described in CIFS/1.0 1996 Section 3.9.14. 33da6c28aaSamw * 34da6c28aaSamw * CIFS/1.0 June 13, 1996 35da6c28aaSamw * Heizer, et al 36da6c28aaSamw * draft-heizer-cifs-v1-spec-00.txt 37da6c28aaSamw */ 38da6c28aaSamw 39*bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h> 40da6c28aaSamw #include <smbsrv/smb_fsops.h> 41da6c28aaSamw 42da6c28aaSamw 43da6c28aaSamw static void smb_flush_file(struct smb_request *sr, struct smb_ofile *ofile); 44da6c28aaSamw 45da6c28aaSamw /* 46da6c28aaSamw * smb_com_flush 47da6c28aaSamw * 48da6c28aaSamw * Flush any cached data for a specified file, or for all files that 49da6c28aaSamw * this client has open, to stable storage. If the fid is valid (i.e. 50da6c28aaSamw * not 0xFFFF), we flush only that file. Otherwise we flush all files 51da6c28aaSamw * associated with this client. 52da6c28aaSamw * 53da6c28aaSamw * We need to protect the list because there's a good chance we'll 54da6c28aaSamw * block during the flush operation. 55da6c28aaSamw */ 567b59d02dSjb150015 smb_sdrc_t 57faa1795aSjb150015 smb_pre_flush(smb_request_t *sr) 58faa1795aSjb150015 { 59faa1795aSjb150015 int rc; 60faa1795aSjb150015 61faa1795aSjb150015 rc = smbsr_decode_vwv(sr, "w", &sr->smb_fid); 62faa1795aSjb150015 63faa1795aSjb150015 DTRACE_SMB_1(op__Flush__start, smb_request_t *, sr); 64faa1795aSjb150015 65faa1795aSjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 66faa1795aSjb150015 } 67faa1795aSjb150015 68faa1795aSjb150015 void 69faa1795aSjb150015 smb_post_flush(smb_request_t *sr) 70faa1795aSjb150015 { 71faa1795aSjb150015 DTRACE_SMB_1(op__Flush__done, smb_request_t *, sr); 72faa1795aSjb150015 } 73faa1795aSjb150015 74faa1795aSjb150015 smb_sdrc_t 75da6c28aaSamw smb_com_flush(smb_request_t *sr) 76da6c28aaSamw { 77da6c28aaSamw smb_ofile_t *file; 78da6c28aaSamw smb_llist_t *flist; 797b59d02dSjb150015 int rc; 80da6c28aaSamw 81da6c28aaSamw if (smb_flush_required == 0) { 827b59d02dSjb150015 rc = smbsr_encode_empty_result(sr); 83faa1795aSjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 84da6c28aaSamw } 85da6c28aaSamw 86da6c28aaSamw if (sr->smb_fid != 0xffff) { 872c2961f8Sjose borrego smbsr_lookup_file(sr); 88da6c28aaSamw if (sr->fid_ofile == NULL) { 89dc20a302Sas200622 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, 90da6c28aaSamw ERRDOS, ERRbadfid); 91faa1795aSjb150015 return (SDRC_ERROR); 92da6c28aaSamw } 93da6c28aaSamw 94da6c28aaSamw smb_flush_file(sr, sr->fid_ofile); 95da6c28aaSamw } else { 96da6c28aaSamw flist = &sr->tid_tree->t_ofile_list; 97da6c28aaSamw smb_llist_enter(flist, RW_READER); 98da6c28aaSamw file = smb_llist_head(flist); 99da6c28aaSamw while (file) { 100da6c28aaSamw mutex_enter(&file->f_mutex); 101da6c28aaSamw smb_flush_file(sr, file); 102da6c28aaSamw mutex_exit(&file->f_mutex); 103da6c28aaSamw file = smb_llist_next(flist, file); 104da6c28aaSamw } 105da6c28aaSamw smb_llist_exit(flist); 106da6c28aaSamw } 1077b59d02dSjb150015 1087b59d02dSjb150015 rc = smbsr_encode_empty_result(sr); 109faa1795aSjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 110da6c28aaSamw } 111da6c28aaSamw 112da6c28aaSamw 113da6c28aaSamw /* 114da6c28aaSamw * smb_flush_file 115da6c28aaSamw * 116da6c28aaSamw * If writes on this file are not synchronous, flush it using the NFSv3 117da6c28aaSamw * commit interface. 118da6c28aaSamw */ 1197b59d02dSjb150015 static void 1207b59d02dSjb150015 smb_flush_file(struct smb_request *sr, struct smb_ofile *ofile) 121da6c28aaSamw { 122b89a8333Snatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_ofile_getcred(ofile); 123b89a8333Snatalie li - Sun Microsystems - Irvine United States 124da6c28aaSamw if ((ofile->f_node->flags & NODE_FLAGS_WRITE_THROUGH) == 0) 125da6c28aaSamw (void) smb_fsop_commit(sr, sr->user_cr, ofile->f_node); 126da6c28aaSamw } 127