[PATCH] support FSCTL_RECALL_FILE nttrans

David Disseldorp ddiss at sgi.com
Fri Jun 13 08:19:10 GMT 2008


FSCTL_RECALL_FILE can be used to recall files moved offline by hierarchical
storage management software.

The nttrans ioctl packet is handled in the following steps:
- check for FILE_SUPPORTS_REMOTE_STORAGE, if without, return error
- return error if attempting to recall a directory.
- if SMB_VFS_IS_OFFLINE() is false return success immediately
- otherwise, call SMB_VFS_RECALL_OFFLINE() to recall the file
---
 source/include/ntioctl.h |    2 +-
 source/smbd/nttrans.c    |   57 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 1 deletions(-)

diff --git a/source/include/ntioctl.h b/source/include/ntioctl.h
index c565b8f..fb91c01 100644
--- a/source/include/ntioctl.h
+++ b/source/include/ntioctl.h
@@ -54,6 +54,7 @@
 #define FSCTL_WRITE_RAW_ENCRYPTED    0x000900DF
 #define FSCTL_READ_RAW_ENCRYPTED     0x000900E3
 #define FSCTL_SIS_COPYFILE           0x00090100
+#define FSCTL_RECALL_FILE            0x00090117
 #define FSCTL_QUERY_ALLOCATED_RANGES 0x000940CF
 #define FSCTL_SIS_LINK_FILES         0x0009C104
 
@@ -64,7 +65,6 @@
 #define FSCTL_DISMOUNT_VOLUME
 #define FSCTL_GET_NTFS_FILE_RECORD
 #define FSCTL_ALLOW_EXTENDED_DASD_IO
-#define FSCTL_RECALL_FILE
 
 #endif
 
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index 270f382..f013250 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -2020,6 +2020,63 @@ static void call_nt_transact_ioctl(connection_struct *conn,
 		return;
 	}
 
+	case FSCTL_RECALL_FILE:
+	{
+		/*
+		 * recall an offline file
+		 */
+		SMB_STRUCT_STAT st;
+		uint16 setup_data = 0;
+
+		if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
+			return;
+		}
+
+		if (!(conn->fs_capabilities & FILE_SUPPORTS_REMOTE_STORAGE)) {
+			/* no hsm support */
+			reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
+			DEBUG(0,("FSCTL_RECALL_FILE called without REMOTE_STORAGE"
+				" capabilities\n"));
+			return;
+		}
+
+ 		if (SMB_VFS_STAT(conn, fsp->fsp_name, &st)) {
+			reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+			DEBUG(3,("FSCTL_RECALL_FILE stat failed\n"));
+			return;
+		}
+
+		if (S_ISDIR(st.st_mode)) {
+			/* directories cannot be offline */
+			reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+			DEBUG(3,("FSCTL_RECALL_FILE cannot recall directory\n"));
+			return;
+		}
+
+		if (SMB_VFS_IS_OFFLINE(conn, fsp->fsp_name, &st) == false) {
+  			/* file already online, return success */
+			send_nt_replies(conn, req, NT_STATUS_OK,
+				&setup_data, 1, /* NT_TRANSACT_IOCTL replies */
+				NULL, 0, /* no params */
+				NULL, 0); /* no data */
+			DEBUG(3,("FSCTL_RECALL_FILE file already online\n"));
+			return;
+		}
+
+		if (SMB_VFS_RECALL_OFFLINE(fsp) == 0) {
+			send_nt_replies(conn, req, NT_STATUS_OK,
+				&setup_data, 1, /* NT_TRANSACT_IOCTL replies */
+				NULL, 0, /* no params */
+				NULL, 0); /* no data */
+			DEBUG(3,("FSCTL_RECALL_FILE successfully recalled\n"));
+		}
+		else {
+			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+			DEBUG(3,("FSCTL_RECALL_FILE recall failed\n"));
+		}
+		return;
+	}
+
 	default:
 		if (!logged_message) {
 			logged_message = True; /* Only print this once... */
-- 
1.5.4.rc0



More information about the samba-technical mailing list