From d86fc3ec8c99aaa5ffaa14a97525154507c39df7 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 16 Jan 2008 12:17:03 +0300 Subject: Add support for offline files support, remote storage, and Async I/O force operations to VFS Offline files support and remote storage are for allowing communication with backup and archiving tools that mark files moved to a tape library as offline. We translate this info into corresponding CIFS offline file attribute and mark an exported volume as remote storage. Async I/O force is to allow selective redirection of I/O operations to asynchronous processing in case it is viable at VFS module discretion. It is needed for proper handling of offline files as performing regular I/O on offline file will block smbd. Signed-off-by: Alexander Bokovoy (This used to be commit 875208724e39564fe81385dfe36e6c963e79e101) --- source3/smbd/reply.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index e2316ef120..381ddfe151 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3329,8 +3329,12 @@ void reply_read_and_X(struct smb_request *req) return; } - if (!big_readX - && schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) { + /* It is possible for VFS modules to selectively decide whether Async I/O should be used + for the file or not. + */ + if ((SMB_VFS_AIO_FORCE(fsp)) && + !big_readX && + schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) { END_PROFILE(SMBreadX); return; } @@ -4001,13 +4005,16 @@ void reply_write_and_X(struct smb_request *req) nwritten = 0; } else { - if (req->unread_bytes == 0 && - schedule_aio_write_and_X(conn, req, fsp, data, - startpos, numtowrite)) { + /* It is possible for VFS modules to selectively decide whether Async I/O + should be used for the file or not. + */ + if ((SMB_VFS_AIO_FORCE(fsp)) && (req->unread_bytes == 0) && + schedule_aio_write_and_X(conn, req, fsp, data, startpos, + numtowrite)) { END_PROFILE(SMBwriteX); return; } - + nwritten = write_file(req,fsp,data,startpos,numtowrite); } -- cgit From 1069cfe4ade88a032164c1242c9480a544584655 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 23:25:36 +0100 Subject: Add streams support This is the core of the streams support. The main change is that in files_struct there is now a base_fsp pointer that holds the main file open while a stream is open. This is necessary to get the rather strange delete semantics right: You can't delete the main file while a stream is open without FILE_SHARE_DELETE, and while a stream is open a successful unlink of the main file leads to DELETE_PENDING for all further access on the main file or any stream. (This used to be commit 6022873cc155bdbbd3fb620689715f07a24d6ed1) --- source3/smbd/reply.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 381ddfe151..61ec611b6b 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -167,6 +167,10 @@ static NTSTATUS check_path_syntax_internal(char *path, } *d = '\0'; + + if (NT_STATUS_IS_OK(ret) && !posix_path) { + ret = split_ntfs_stream_name(NULL, path, NULL, NULL); + } return ret; } @@ -2289,14 +2293,22 @@ static NTSTATUS do_unlink(connection_struct *conn, /* On open checks the open itself will check the share mode, so don't do it here as we'll get it wrong. */ - status = open_file_ntcreate(conn, req, fname, &sbuf, - DELETE_ACCESS, - FILE_SHARE_NONE, - FILE_OPEN, - 0, - FILE_ATTRIBUTE_NORMAL, - req != NULL ? 0 : INTERNAL_OPEN_ONLY, - NULL, &fsp); + status = create_file_unixpath + (conn, /* conn */ + req, /* req */ + fname, /* fname */ + DELETE_ACCESS, /* access_mask */ + FILE_SHARE_NONE, /* share_access */ + FILE_OPEN, /* create_disposition*/ + FILE_NON_DIRECTORY_FILE, /* create_options */ + FILE_ATTRIBUTE_NORMAL, /* file_attributes */ + 0, /* oplock_request */ + 0, /* allocation_size */ + NULL, /* sd */ + NULL, /* ea_list */ + &fsp, /* result */ + NULL, /* pinfo */ + &sbuf); /* psbuf */ if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("open_file_ntcreate failed: %s\n", -- cgit From f87d08f6222f3e86b771c9c8ef669c1872118f6b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 14:43:30 +0100 Subject: Don't test split_ntfs_stream_name This is a hot code path, and if it has a :, the name will be split later on anyway. (This used to be commit 9f7f6b812d89decea1456ccdc37978e645d11a63) --- source3/smbd/reply.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 61ec611b6b..5a5eb1e190 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -168,9 +168,6 @@ static NTSTATUS check_path_syntax_internal(char *path, *d = '\0'; - if (NT_STATUS_IS_OK(ret) && !posix_path) { - ret = split_ntfs_stream_name(NULL, path, NULL, NULL); - } return ret; } -- cgit From 33f3eeaa00974860dfc45962d5fd34cf05396c76 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 17:35:25 +0100 Subject: Fix some "set but never used" warnings (This used to be commit 4a6dadc5178f4861e9c032321939db3b639734b5) --- source3/smbd/reply.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 5a5eb1e190..4ea81a3819 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3375,7 +3375,6 @@ void error_to_writebrawerr(struct smb_request *req) void reply_writebraw(struct smb_request *req) { connection_struct *conn = req->conn; - int outsize = 0; char *buf = NULL; ssize_t nwritten=0; ssize_t total_written=0; @@ -3485,8 +3484,7 @@ void reply_writebraw(struct smb_request *req) * it to send more bytes */ memcpy(buf, req->inbuf, smb_size); - outsize = srv_set_message(buf, - Protocol>PROTOCOL_COREPLUS?1:0,0,True); + srv_set_message(buf,Protocol>PROTOCOL_COREPLUS?1:0,0,True); SCVAL(buf,smb_com,SMBwritebraw); SSVALS(buf,smb_vwv0,0xFFFF); show_msg(buf); -- cgit From 34a92c6285513acff08c7c9ad67474243559fd2f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 30 Jan 2008 11:11:27 +0100 Subject: Re-enable async I/O for non-TSM systems The logic was wrong: A "SMB_VFS_AIO_FORCE()==False" disabled async I/O, whereas a "SMB_VFS_AIO_FORCE()==True" should enforce it regardless of other settings. Alexander, please check! (This used to be commit 46882ad9927c95caadeb7fb03c1d7491bbe1fb22) --- source3/smbd/reply.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 4ea81a3819..18376031ec 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3338,11 +3338,7 @@ void reply_read_and_X(struct smb_request *req) return; } - /* It is possible for VFS modules to selectively decide whether Async I/O should be used - for the file or not. - */ - if ((SMB_VFS_AIO_FORCE(fsp)) && - !big_readX && + if (!big_readX && schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) { END_PROFILE(SMBreadX); return; @@ -4012,10 +4008,7 @@ void reply_write_and_X(struct smb_request *req) nwritten = 0; } else { - /* It is possible for VFS modules to selectively decide whether Async I/O - should be used for the file or not. - */ - if ((SMB_VFS_AIO_FORCE(fsp)) && (req->unread_bytes == 0) && + if ((req->unread_bytes == 0) && schedule_aio_write_and_X(conn, req, fsp, data, startpos, numtowrite)) { END_PROFILE(SMBwriteX); -- cgit From 9f6e983d0b67b64daf27dab130348d3491bad4ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 21:31:40 +0100 Subject: Convert read_smb_length to return NTSTATUS (This used to be commit 5750c3a51b4ddac635a98195d1621b24f91bad3f) --- source3/smbd/reply.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 18376031ec..46c14d158e 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3492,18 +3492,12 @@ void reply_writebraw(struct smb_request *req) } /* Now read the raw data into the buffer and write it */ - if (read_smb_length(smbd_server_fd(),buf, - SMB_SECONDARY_WAIT, get_srv_read_error()) == -1) { + status = read_smb_length(smbd_server_fd(), buf, SMB_SECONDARY_WAIT, + &numtowrite); + if (!NT_STATUS_IS_OK(status)) { exit_server_cleanly("secondary writebraw failed"); } - /* - * Even though this is not an smb message, - * smb_len returns the generic length of a packet. - */ - - numtowrite = smb_len(buf); - /* Set up outbuf to return the correct size */ reply_outbuf(req, 1, 0); -- cgit From 21e7344d2f45416ea996f88be72de1a923c0ee9c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 23:57:20 +0100 Subject: Make get_srv_read_error static to process.c (This used to be commit 9e2947039ef70cab8bbd6027182d9c721eac3194) --- source3/smbd/reply.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 46c14d158e..f371dde705 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3516,8 +3516,8 @@ void reply_writebraw(struct smb_request *req) (int)tcount,(int)nwritten,(int)numtowrite)); } - if (read_data(smbd_server_fd(), buf+4, numtowrite,get_srv_read_error()) - != numtowrite ) { + if (read_data(smbd_server_fd(), buf+4, numtowrite, NULL) + != numtowrite ) { DEBUG(0,("reply_writebraw: Oversize secondary write " "raw read failed (%s). Terminating\n", strerror(errno) )); -- cgit From b42a5d68a3ffd88fd60c64b6a75fe2d687d9c92d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 26 Jan 2008 10:39:21 +0100 Subject: Convert read_data() to NTSTATUS (This used to be commit af40b71023f8c4a2133d996ea698c72b97624043) --- source3/smbd/reply.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index f371dde705..bced8ed984 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3516,11 +3516,12 @@ void reply_writebraw(struct smb_request *req) (int)tcount,(int)nwritten,(int)numtowrite)); } - if (read_data(smbd_server_fd(), buf+4, numtowrite, NULL) - != numtowrite ) { + status = read_data(smbd_server_fd(), buf+4, numtowrite); + + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("reply_writebraw: Oversize secondary write " - "raw read failed (%s). Terminating\n", - strerror(errno) )); + "raw read failed (%s). Terminating\n", + nt_errstr(status))); exit_server_cleanly("secondary writebraw failed"); } -- cgit From a4436154b8ce446e84e6c07bd9c69edfafe1b68c Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 6 Feb 2008 09:10:50 +0300 Subject: Change the file time before we change the file mode. This doesn't matter for most applications, but for offline files it matters as it allows you to set files offline from windows clients even with HSM systems that refuse to offline newly created files. Merge from Tridge's v3-0-ctdb tree. (This used to be commit 7da6c675440b0253ab37ee6097f769a2e45c7b7b) --- source3/smbd/reply.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index bced8ed984..baebff83de 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1110,6 +1110,12 @@ void reply_setatr(struct smb_request *req) mode = SVAL(req->inbuf,smb_vwv0); mtime = srv_make_unix_date3(req->inbuf+smb_vwv1); + if (!set_filetime(conn,fname,convert_time_t_to_timespec(mtime))) { + reply_unixerror(req, ERRDOS, ERRnoaccess); + END_PROFILE(SMBsetatr); + return; + } + if (mode != FILE_ATTRIBUTE_NORMAL) { if (VALID_STAT_OF_DIR(sbuf)) mode |= aDIR; @@ -1123,12 +1129,6 @@ void reply_setatr(struct smb_request *req) } } - if (!set_filetime(conn,fname,convert_time_t_to_timespec(mtime))) { - reply_unixerror(req, ERRDOS, ERRnoaccess); - END_PROFILE(SMBsetatr); - return; - } - reply_outbuf(req, 0, 0); DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) ); -- cgit From 2a6a2288c5fae908f431bd79332554e0a23dbeed Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Fri, 8 Feb 2008 09:28:57 +0100 Subject: Fix some typos. Karolin (This used to be commit 2bec0a1fb7857e6fb8ec15e5f597b2d4125f105b) --- source3/smbd/reply.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index baebff83de..669dad2e3a 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2469,7 +2469,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, } count++; - DEBUG(3,("unlink_internals: succesful unlink [%s]\n", + DEBUG(3,("unlink_internals: successful unlink [%s]\n", fname)); TALLOC_FREE(fname); -- cgit From 14aa57a9e3368fed5b8b7d1ac0f6e94b9b1ac20e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 22 Feb 2008 16:17:10 +0100 Subject: Don't use fname after create_file has been called create_file calls unix_convert internally, so modifies fname. So we can't use "fname" after create_file has returned. Use fsp->fsp_name instead. Found during a lengthy debugging session with Karolin testing the xattr_tdb module... (This used to be commit 183fe570469963923864b732817a87f8660341ed) --- source3/smbd/reply.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 669dad2e3a..818ff319e4 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1639,11 +1639,11 @@ void reply_open(struct smb_request *req) } size = sbuf.st_size; - fattr = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fsp->fsp_name,&sbuf); mtime = sbuf.st_mtime; if (fattr & aDIR) { - DEBUG(3,("attempt to open a directory %s\n",fname)); + DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name)); close_file(fsp,ERROR_CLOSE); reply_doserror(req, ERRDOS,ERRnoaccess); END_PROFILE(SMBopen); @@ -1802,7 +1802,7 @@ void reply_open_and_X(struct smb_request *req) sbuf.st_size = get_allocation_size(conn,fsp,&sbuf); } - fattr = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fsp->fsp_name,&sbuf); mtime = sbuf.st_mtime; if (fattr & aDIR) { close_file(fsp,ERROR_CLOSE); @@ -1985,7 +1985,7 @@ void reply_mknew(struct smb_request *req) } ts[0] = get_atimespec(&sbuf); /* atime. */ - file_ntimes(conn, fname, ts); + file_ntimes(conn, fsp->fsp_name, ts); reply_outbuf(req, 1, 0); SSVAL(req->outbuf,smb_vwv0,fsp->fnum); @@ -2000,9 +2000,9 @@ void reply_mknew(struct smb_request *req) CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED); } - DEBUG( 2, ( "reply_mknew: file %s\n", fname ) ); + DEBUG( 2, ( "reply_mknew: file %s\n", fsp->fsp_name ) ); DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", - fname, fsp->fh->fd, (unsigned int)fattr ) ); + fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) ); END_PROFILE(SMBcreate); return; @@ -2125,9 +2125,9 @@ void reply_ctemp(struct smb_request *req) SSVAL(req->outbuf,smb_vwv0,fsp->fnum); /* the returned filename is relative to the directory */ - s = strrchr_m(fname, '/'); + s = strrchr_m(fsp->fsp_name, '/'); if (!s) { - s = fname; + s = fsp->fsp_name; } else { s++; } @@ -2154,9 +2154,9 @@ void reply_ctemp(struct smb_request *req) CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED); } - DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) ); - DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd, - (unsigned int)sbuf.st_mode ) ); + DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) ); + DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name, + fsp->fh->fd, (unsigned int)sbuf.st_mode ) ); END_PROFILE(SMBctemp); return; -- cgit