support for FSCTL_QUERY_ALLOCATED_RANGES.

Jeremy Allison jra at samba.org
Fri Apr 2 16:43:07 MDT 2010


On Fri, Apr 02, 2010 at 02:49:31PM -0700, Jeremy Allison wrote:
> On Thu, Apr 01, 2010 at 05:50:58PM -0400, Ira Cooper wrote:
> > This patch implements FSCTL_QUERY_ALLOCATED_RANGES, or at least enough
> > of it so that applications can use the call, and not die.
> > 
> > I've applied this patch to 3.5 and 3.6.
> > 
> > Thanks,
> > 
> > -Ira
> > 
> > --- a/source3/smbd/nttrans.c
> > +++ b/source3/smbd/nttrans.c
> > @@ -1964,6 +1964,16 @@ static void
> > call_nt_transact_ioctl(connection_struct *conn,
> >                 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
> >                 return;
> > 
> > +        case FSCTL_QUERY_ALLOCATED_RANGES:
> > +        {
> > +                /* All you do is return what you got.  We don't
> > implement sparse files really. */
> > +
> > +                DEBUG(10,("FSCTL_QUERY_ALLOCATED_RANGES called on
> > FID[0x%04X] - %d\n",fidnum, data_count));
> > +                send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
> > +                                pdata, data_count);
> > +                return;
> > +        }
> > +
> >         case FSCTL_CREATE_OR_GET_OBJECT_ID:
> >         {
> >                 unsigned char objid[16];
> 
> Ok, I think it's a little more complex than this patch
> (looking at MS-FSCC.pdf). If the file size is zero, we
> need to return no ranges. I think we need to truncate
> the length reply to the length of the file being queried
> also. I'll make up a test patch for you.

Ok, can you test this please and let me know if it fixes
the issue for you ?

Jeremy.
-------------- next part --------------
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index b79bb0b..46edc06 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -2215,6 +2215,58 @@ static void call_nt_transact_ioctl(connection_struct *conn,
 		send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
 		return;
 	}
+	case FSCTL_QUERY_ALLOCATED_RANGES:
+	{
+		NTSTATUS status;
+		uint64_t offset, length;
+
+		if (!fsp_belongs_conn(conn, req, fsp)) {
+			return;
+		}
+
+		if (data_count != 16) {
+			DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
+				data_count));
+			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+			return;
+		}
+
+		if (max_data_count < 16) {
+			DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_data_count(%u) < 16 is invalid!\n",
+				max_data_count));
+			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+			return;
+		}
+
+		offset = BVAL(pdata,0);
+		length = BVAL(pdata,8);
+
+		if (offset + length < offset) {
+			/* No 64-bit integer wrap. */
+			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+			return;
+		}
+
+		status = vfs_stat_fsp(fsp);
+		if (!NT_STATUS_IS_OK(status)) {
+			reply_nterror(req, status);
+			return;
+		}
+
+		if (offset > fsp->fsp_name->st.st_ex_size ||
+				fsp->fsp_name->st.st_ex_size == 0 ||
+				length == 0) {
+			send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
+		} else {
+			uint64_t end = offset + length;
+			end = MIN(end, fsp->fsp_name->st.st_ex_size);
+			SBVAL(pdata,0,0);
+			SBVAL(pdata,8,end);
+			send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
+				pdata, 16);
+		}
+		return;
+	}
 	default:
 		if (!logged_ioctl_message) {
 			logged_ioctl_message = true; /* Only print this once... */


More information about the samba-technical mailing list