r7963: Add aio support to 3.0.
[samba.git] / source / smbd / close.c
1 /* 
2    Unix SMB/CIFS implementation.
3    file closing
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison 1992-2004.
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 /****************************************************************************
25  Run a file if it is a magic script.
26 ****************************************************************************/
27
28 static void check_magic(files_struct *fsp,connection_struct *conn)
29 {
30         if (!*lp_magicscript(SNUM(conn)))
31                 return;
32
33         DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
34
35         {
36                 char *p;
37                 if (!(p = strrchr_m(fsp->fsp_name,'/')))
38                         p = fsp->fsp_name;
39                 else
40                         p++;
41
42                 if (!strequal(lp_magicscript(SNUM(conn)),p))
43                         return;
44         }
45
46         {
47                 int ret;
48                 pstring magic_output;
49                 pstring fname;
50                 SMB_STRUCT_STAT st;
51                 int tmp_fd, outfd;
52
53                 pstrcpy(fname,fsp->fsp_name);
54                 if (*lp_magicoutput(SNUM(conn)))
55                         pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
56                 else
57                         slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
58
59                 chmod(fname,0755);
60                 ret = smbrun(fname,&tmp_fd);
61                 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
62                 unlink(fname);
63                 if (ret != 0 || tmp_fd == -1) {
64                         if (tmp_fd != -1)
65                                 close(tmp_fd);
66                         return;
67                 }
68                 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
69                 if (outfd == -1) {
70                         close(tmp_fd);
71                         return;
72                 }
73
74                 if (sys_fstat(tmp_fd,&st) == -1) {
75                         close(tmp_fd);
76                         close(outfd);
77                         return;
78                 }
79
80                 transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
81                 close(tmp_fd);
82                 close(outfd);
83         }
84 }
85
86 /****************************************************************************
87   Common code to close a file or a directory.
88 ****************************************************************************/
89
90 static int close_filestruct(files_struct *fsp)
91 {   
92         connection_struct *conn = fsp->conn;
93         int ret = 0;
94     
95         if (fsp->fd != -1) {
96                 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
97                         ret = -1;
98
99                 delete_write_cache(fsp);
100         }
101
102         conn->num_files_open--;
103         SAFE_FREE(fsp->wbmpx_ptr);
104
105         return ret;
106 }    
107
108 /****************************************************************************
109  If any deferred opens are waiting on this close, notify them.
110 ****************************************************************************/
111
112 static void notify_deferred_opens(files_struct *fsp)
113 {
114         deferred_open_entry *de_array = NULL;
115         int num_de_entries, i;
116         pid_t mypid = sys_getpid();
117
118         if (!lp_defer_sharing_violations()) {
119                 return;
120         }
121
122         num_de_entries = get_deferred_opens(fsp->conn, fsp->dev, fsp->inode, &de_array);
123         for (i = 0; i < num_de_entries; i++) {
124                 deferred_open_entry *entry = &de_array[i];
125                 if (entry->pid == mypid) {
126                         /*
127                          * We need to notify ourself to retry the open.
128                          * Do this by finding the queued SMB record, moving it
129                          * to the head of the queue and changing the wait time to zero.
130                          */
131                         schedule_sharing_violation_open_smb_message(entry->mid);
132                 } else {
133                         send_deferred_open_retry_message(entry);
134                 }
135         }
136 }
137
138 /****************************************************************************
139  Close a file.
140
141  If normal_close is 1 then this came from a normal SMBclose (or equivalent)
142  operation otherwise it came as the result of some other operation such as
143  the closing of the connection. In the latter case printing and
144  magic scripts are not run.
145 ****************************************************************************/
146
147 static int close_normal_file(files_struct *fsp, BOOL normal_close)
148 {
149         share_mode_entry *share_entry = NULL;
150         size_t share_entry_count = 0;
151         BOOL delete_on_close = False;
152         connection_struct *conn = fsp->conn;
153         int saved_errno = 0;
154         int err = 0;
155         int err1 = 0;
156
157         remove_pending_lock_requests_by_fid(fsp);
158
159         if (fsp->aio_write_behind) {
160                 /*
161                  * If we're finishing write behind on a close we can get a write
162                  * error here, we must remember this.
163                  */
164                 int ret = wait_for_aio_completion(fsp);
165                 if (ret) {
166                         saved_errno = ret;
167                         err1 = -1;
168                 }
169         } else {
170                 cancel_aio_by_fsp(fsp);
171         }
172  
173         /*
174          * If we're flushing on a close we can get a write
175          * error here, we must remember this.
176          */
177
178         if (close_filestruct(fsp) == -1) {
179                 saved_errno = errno;
180                 err1 = -1;
181         }
182
183         if (fsp->print_file) {
184                 print_fsp_end(fsp, normal_close);
185                 file_free(fsp);
186                 return 0;
187         }
188
189         /*
190          * Lock the share entries, and determine if we should delete
191          * on close. If so delete whilst the lock is still in effect.
192          * This prevents race conditions with the file being created. JRA.
193          */
194
195         lock_share_entry_fsp(fsp);
196
197         if (fsp->delete_on_close) {
198
199                 /*
200                  * Modify the share mode entry for all files open
201                  * on this device and inode to tell other smbds we have
202                  * changed the delete on close flag. The last closer will delete the file
203                  * if flag is set.
204                  */
205
206                 NTSTATUS status =set_delete_on_close_over_all(fsp, fsp->delete_on_close);
207                 if (NT_STATUS_V(status) !=  NT_STATUS_V(NT_STATUS_OK))
208                         DEBUG(0,("close_normal_file: failed to change delete on close flag for file %s\n",
209                                 fsp->fsp_name ));
210         }
211
212         share_entry_count = del_share_mode(fsp, &share_entry);
213
214         DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n",
215                 (unsigned long)share_entry_count, fsp->fsp_name ));
216
217         /*
218          * We delete on close if it's the last open, and the
219          * delete on close flag was set in the entry we just deleted.
220          */
221
222         if ((share_entry_count == 0) && share_entry && 
223                         GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) )
224                 delete_on_close = True;
225
226         SAFE_FREE(share_entry);
227
228         /* Notify any deferred opens waiting on this close. */
229         notify_deferred_opens(fsp);
230
231         /*
232          * NT can set delete_on_close of the last open
233          * reference to a file.
234          */
235
236         if (normal_close && delete_on_close) {
237                 DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
238                         fsp->fsp_name));
239                 if(SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
240                         /*
241                          * This call can potentially fail as another smbd may have
242                          * had the file open with delete on close set and deleted
243                          * it when its last reference to this file went away. Hence
244                          * we log this but not at debug level zero.
245                          */
246
247                 DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
248 with error %s\n", fsp->fsp_name, strerror(errno) ));
249                 }
250                 process_pending_change_notify_queue((time_t)0);
251         }
252
253         unlock_share_entry_fsp(fsp);
254
255         if(fsp->oplock_type)
256                 release_file_oplock(fsp);
257
258         locking_close_file(fsp);
259
260         err = fd_close(conn, fsp);
261
262         /* Only save errno if fd_close failed and we don't already
263            have an errno saved from a flush call. */
264         if ((err1 != -1) && (err == -1)) {
265                 saved_errno = errno;
266         }
267
268         /* check for magic scripts */
269         if (normal_close) {
270                 check_magic(fsp,conn);
271         }
272
273         /*
274          * Ensure pending modtime is set after close.
275          */
276
277         if(fsp->pending_modtime && fsp->pending_modtime_owner) {
278                 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
279         } else if (fsp->last_write_time) {
280                 set_filetime(conn, fsp->fsp_name, fsp->last_write_time);
281         }
282
283         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
284                 conn->user,fsp->fsp_name,
285                 conn->num_files_open,
286                 (err == -1 || err1 == -1) ? strerror(saved_errno) : ""));
287
288         if (fsp->fsp_name)
289                 string_free(&fsp->fsp_name);
290
291         file_free(fsp);
292
293         if (err == -1 || err1 == -1) {
294                 errno = saved_errno;
295                 return saved_errno;
296         } else {
297                 return 0;
298         }
299 }
300
301 /****************************************************************************
302  Close a directory opened by an NT SMB call. 
303 ****************************************************************************/
304   
305 static int close_directory(files_struct *fsp, BOOL normal_close)
306 {
307         remove_pending_change_notify_requests_by_fid(fsp);
308
309         /*
310          * NT can set delete_on_close of the last open
311          * reference to a directory also.
312          */
313
314         if (normal_close && fsp->directory_delete_on_close) {
315                 BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
316                 DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
317                         fsp->fsp_name, ok ? "succeeded" : "failed" ));
318
319                 /*
320                  * Ensure we remove any change notify requests that would
321                  * now fail as the directory has been deleted.
322                  */
323
324                 if(ok)
325                         remove_pending_change_notify_requests_by_filename(fsp);
326                 process_pending_change_notify_queue((time_t)0);
327         }
328
329         /*
330          * Do the code common to files and directories.
331          */
332         close_filestruct(fsp);
333         
334         if (fsp->fsp_name)
335                 string_free(&fsp->fsp_name);
336         
337         file_free(fsp);
338         return 0;
339 }
340
341 /****************************************************************************
342  Close a 'stat file' opened internally.
343 ****************************************************************************/
344   
345 static int close_stat(files_struct *fsp)
346 {
347         /*
348          * Do the code common to files and directories.
349          */
350         close_filestruct(fsp);
351         
352         if (fsp->fsp_name)
353                 string_free(&fsp->fsp_name);
354         
355         file_free(fsp);
356         return 0;
357 }
358
359 /****************************************************************************
360  Close a files_struct.
361 ****************************************************************************/
362   
363 int close_file(files_struct *fsp, BOOL normal_close)
364 {
365         if(fsp->is_directory)
366                 return close_directory(fsp, normal_close);
367         else if (fsp->is_stat)
368                 return close_stat(fsp);
369         else
370                 return close_normal_file(fsp, normal_close);
371 }