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