mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
Shadow copy API - Original work by "Ken Cross" <kcross@nssolutions.com>, adapted
into a patch by "Stefan (metze) Metzmacher" <metze@metzemix.de>.
Jeremy.
(This used to be commit ce5c91d35d
)
This commit is contained in:
parent
3bbe9c0869
commit
a83bac7571
@ -23,6 +23,8 @@
|
||||
we only need the sparse flag
|
||||
*/
|
||||
|
||||
#ifndef _NTIOCTL_H
|
||||
#define _NTIOCTL_H
|
||||
|
||||
/* IOCTL information */
|
||||
/* List of ioctl function codes that look to be of interest to remote clients like this. */
|
||||
@ -53,6 +55,8 @@
|
||||
#define FSCTL_SIS_COPYFILE 0x00090100
|
||||
#define FSCTL_SIS_LINK_FILES 0x0009C104
|
||||
|
||||
#define FSCTL_GET_SHADOW_COPY_DATA 0x00144064 /* KJC -- Shadow Copy information */
|
||||
|
||||
#if 0
|
||||
#define FSCTL_SECURITY_ID_CHECK
|
||||
#define FSCTL_DISMOUNT_VOLUME
|
||||
@ -66,3 +70,18 @@
|
||||
#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
|
||||
#define IO_REPARSE_TAG_HSM 0xC0000004
|
||||
#define IO_REPARSE_TAG_SIS 0x80000007
|
||||
|
||||
|
||||
/* For FSCTL_GET_SHADOW_COPY_DATA ...*/
|
||||
typedef char SHADOW_COPY_LABEL[25];
|
||||
|
||||
typedef struct shadow_copy_data {
|
||||
TALLOC_CTX *mem_ctx;
|
||||
/* Total number of shadow volumes currently mounted */
|
||||
uint32 num_volumes;
|
||||
/* Concatenated list of labels */
|
||||
SHADOW_COPY_LABEL *labels;
|
||||
} SHADOW_COPY_DATA;
|
||||
|
||||
|
||||
#endif /* _NTIOCTL_H */
|
||||
|
@ -77,6 +77,12 @@
|
||||
#define OPEN_CONN(conn) ((conn) && (conn)->open)
|
||||
#define IS_IPC(conn) ((conn) && (conn)->ipc)
|
||||
#define IS_PRINT(conn) ((conn) && (conn)->printer)
|
||||
#define FSP_BELONGS_CONN(fsp,conn) do {\
|
||||
extern struct current_user current_user;\
|
||||
if (!((fsp) && (conn) && ((conn)==(fsp)->conn) && (current_user.vuid==(fsp)->vuid))) \
|
||||
return(ERROR_DOS(ERRDOS,ERRbadfid));\
|
||||
} while(0)
|
||||
|
||||
#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid)
|
||||
|
||||
#define CHECK_FSP(fsp,conn) do {\
|
||||
|
@ -50,8 +50,8 @@
|
||||
/* Changed to version 6 for the new module system, fixed cascading and quota functions. --metze */
|
||||
/* Changed to version 7 to include the get_nt_acl info parameter. JRA. */
|
||||
/* Changed to version 8 includes EA calls. JRA. */
|
||||
|
||||
#define SMB_VFS_INTERFACE_VERSION 8
|
||||
/* Changed to version 9 to include the get_shadow_data call. --metze */
|
||||
#define SMB_VFS_INTERFACE_VERSION 9
|
||||
|
||||
|
||||
/* to bug old modules witch are trying to compile with the old functions */
|
||||
@ -91,6 +91,8 @@ typedef enum _vfs_op_type {
|
||||
SMB_VFS_OP_DISK_FREE,
|
||||
SMB_VFS_OP_GET_QUOTA,
|
||||
SMB_VFS_OP_SET_QUOTA,
|
||||
SMB_VFS_OP_GET_SHADOW_COPY_DATA,
|
||||
|
||||
|
||||
/* Directory operations */
|
||||
|
||||
@ -196,6 +198,7 @@ struct vfs_ops {
|
||||
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
|
||||
int (*get_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
|
||||
int (*set_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
|
||||
int (*get_shadow_copy_data)(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels);
|
||||
|
||||
/* Directory operations */
|
||||
|
||||
@ -293,6 +296,7 @@ struct vfs_ops {
|
||||
struct vfs_handle_struct *disk_free;
|
||||
struct vfs_handle_struct *get_quota;
|
||||
struct vfs_handle_struct *set_quota;
|
||||
struct vfs_handle_struct *get_shadow_copy_data;
|
||||
|
||||
/* Directory operations */
|
||||
|
||||
@ -379,6 +383,7 @@ struct vfs_ops {
|
||||
struct vfs_handle_struct *setxattr;
|
||||
struct vfs_handle_struct *lsetxattr;
|
||||
struct vfs_handle_struct *fsetxattr;
|
||||
|
||||
} handles;
|
||||
};
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#define SMB_VFS_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs.ops.disk_free((conn)->vfs.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
|
||||
#define SMB_VFS_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.get_quota((conn)->vfs.handles.get_quota, (conn), (qtype), (id), (qt)))
|
||||
#define SMB_VFS_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.set_quota((conn)->vfs.handles.set_quota, (conn), (qtype), (id), (qt)))
|
||||
#define SMB_VFS_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs.ops.get_shadow_copy_data((fsp)->conn->vfs.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
|
||||
|
||||
/* Directory operations */
|
||||
#define SMB_VFS_OPENDIR(conn, fname) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname)))
|
||||
@ -128,6 +129,7 @@
|
||||
#define SMB_VFS_OPAQUE_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs_opaque.ops.disk_free((conn)->vfs_opaque.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
|
||||
#define SMB_VFS_OPAQUE_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.get_quota((conn)->vfs_opaque.handles.get_quota, (conn), (qtype), (id), (qt)))
|
||||
#define SMB_VFS_OPAQUE_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.set_quota((conn)->vfs_opaque.handles.set_quota, (conn), (qtype), (id), (qt)))
|
||||
#define SMB_VFS_OPAQUE_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs_opaque.ops.get_shadow_copy_data((fsp)->conn->vfs_opaque.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
|
||||
|
||||
/* Directory operations */
|
||||
#define SMB_VFS_OPAQUE_OPENDIR(conn, fname) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname)))
|
||||
@ -223,6 +225,7 @@
|
||||
#define SMB_VFS_NEXT_DISK_FREE(handle, conn, path, small_query, bsize, dfree ,dsize) ((handle)->vfs_next.ops.disk_free((handle)->vfs_next.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
|
||||
#define SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.get_quota((handle)->vfs_next.handles.get_quota, (conn), (qtype), (id), (qt)))
|
||||
#define SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.set_quota((handle)->vfs_next.handles.set_quota, (conn), (qtype), (id), (qt)))
|
||||
#define SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data ,labels) ((handle)->vfs_next.ops.get_shadow_copy_data((handle)->vfs_next.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
|
||||
|
||||
/* Directory operations */
|
||||
#define SMB_VFS_NEXT_OPENDIR(handle, conn, fname) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname)))
|
||||
|
@ -1724,7 +1724,11 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
|
||||
char **ppparams, uint32 parameter_count,
|
||||
char **ppdata, uint32 data_count)
|
||||
{
|
||||
unsigned fnum, control;
|
||||
uint32 function;
|
||||
uint16 fidnum;
|
||||
files_struct *fsp;
|
||||
uint8 isFSctl;
|
||||
uint8 compfilter;
|
||||
static BOOL logged_message;
|
||||
char *pdata = *ppdata;
|
||||
|
||||
@ -1733,19 +1737,26 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
|
||||
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
fnum = SVAL(*ppsetup, 4);
|
||||
control = IVAL(*ppsetup, 0);
|
||||
function = IVAL(*ppsetup, 0);
|
||||
fidnum = SVAL(*ppsetup, 4);
|
||||
isFSctl = CVAL(*ppsetup, 6);
|
||||
compfilter = CVAL(*ppsetup, 7);
|
||||
|
||||
DEBUG(10,("call_nt_transact_ioctl: fnum=%d control=0x%08x\n",
|
||||
fnum, control));
|
||||
DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n",
|
||||
function, fidnum, isFSctl, compfilter));
|
||||
|
||||
switch (control) {
|
||||
fsp=file_fsp(*ppsetup, 4);
|
||||
/* this check is done in each implemented function case for now
|
||||
because I don't want to break anything... --metze
|
||||
FSP_BELONGS_CONN(fsp,conn);*/
|
||||
|
||||
switch (function) {
|
||||
case FSCTL_SET_SPARSE:
|
||||
/* pretend this succeeded - tho strictly we should
|
||||
mark the file sparse (if the local fs supports it)
|
||||
so we can know if we need to pre-allocate or not */
|
||||
|
||||
DEBUG(10,("FSCTL_SET_SPARSE: fnum=%d control=0x%08x\n",fnum,control));
|
||||
DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
|
||||
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
|
||||
return -1;
|
||||
|
||||
@ -1754,7 +1765,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
|
||||
but works ok like this --metze
|
||||
*/
|
||||
|
||||
DEBUG(10,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
|
||||
DEBUG(10,("FSCTL_0x000900C0: called on FID[0x%04X](but not implemented)\n",fidnum));
|
||||
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
|
||||
return -1;
|
||||
|
||||
@ -1763,7 +1774,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
|
||||
* --metze
|
||||
*/
|
||||
|
||||
DEBUG(10,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
|
||||
DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
|
||||
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
|
||||
return -1;
|
||||
|
||||
@ -1772,10 +1783,125 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
|
||||
* --metze
|
||||
*/
|
||||
|
||||
DEBUG(10,("FSCTL_SET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
|
||||
DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
|
||||
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
|
||||
return -1;
|
||||
|
||||
case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/
|
||||
{
|
||||
/*
|
||||
* This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
|
||||
* and return their volume names. If max_data_count is 16, then it is just
|
||||
* asking for the number of volumes and length of the combined names.
|
||||
*
|
||||
* pdata is the data allocated by our caller, but that uses
|
||||
* total_data_count (which is 0 in our case) rather than max_data_count.
|
||||
* Allocate the correct amount and return the pointer to let
|
||||
* it be deallocated when we return.
|
||||
*/
|
||||
uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
|
||||
SHADOW_COPY_DATA *shadow_data = NULL;
|
||||
TALLOC_CTX *shadow_mem_ctx = NULL;
|
||||
BOOL labels = False;
|
||||
uint32 labels_data_count = 0;
|
||||
uint32 i;
|
||||
char *cur_pdata;
|
||||
|
||||
FSP_BELONGS_CONN(fsp,conn);
|
||||
|
||||
if (max_data_count < 16) {
|
||||
DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
|
||||
max_data_count));
|
||||
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
if (max_data_count > 16) {
|
||||
labels = True;
|
||||
}
|
||||
|
||||
shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
|
||||
if (shadow_mem_ctx == NULL) {
|
||||
DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
|
||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
shadow_data = (SHADOW_COPY_DATA *)talloc_zero(shadow_mem_ctx,sizeof(SHADOW_COPY_DATA));
|
||||
if (shadow_data == NULL) {
|
||||
DEBUG(0,("talloc_zero() failed!\n"));
|
||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
shadow_data->mem_ctx = shadow_mem_ctx;
|
||||
|
||||
/*
|
||||
* Call the VFS routine to actually do the work.
|
||||
*/
|
||||
if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
|
||||
talloc_destroy(shadow_data->mem_ctx);
|
||||
if (errno == ENOSYS) {
|
||||
DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
|
||||
conn->connectpath));
|
||||
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
|
||||
} else {
|
||||
DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
|
||||
conn->connectpath));
|
||||
return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
}
|
||||
|
||||
labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2;
|
||||
|
||||
if (!labels) {
|
||||
data_count = 16;
|
||||
} else {
|
||||
data_count = 12+labels_data_count+4;
|
||||
}
|
||||
|
||||
if (max_data_count<data_count) {
|
||||
DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
|
||||
max_data_count,data_count));
|
||||
talloc_destroy(shadow_data->mem_ctx);
|
||||
return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
|
||||
}
|
||||
|
||||
pdata = nttrans_realloc(ppdata, data_count);
|
||||
if (pdata == NULL) {
|
||||
talloc_destroy(shadow_data->mem_ctx);
|
||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
cur_pdata = pdata;
|
||||
|
||||
/* num_volumes 4 bytes */
|
||||
SIVAL(pdata,0,shadow_data->num_volumes);
|
||||
|
||||
if (labels) {
|
||||
/* num_labels 4 bytes */
|
||||
SIVAL(pdata,4,shadow_data->num_volumes);
|
||||
}
|
||||
|
||||
/* needed_data_count 4 bytes */
|
||||
SIVAL(pdata,8,labels_data_count);
|
||||
|
||||
cur_pdata+=12;
|
||||
|
||||
DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
|
||||
shadow_data->num_volumes,fsp->fsp_name));
|
||||
if (labels && shadow_data->labels) {
|
||||
for (i=0;i<shadow_data->num_volumes;i++) {
|
||||
srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE);
|
||||
cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
|
||||
DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
|
||||
}
|
||||
}
|
||||
|
||||
talloc_destroy(shadow_data->mem_ctx);
|
||||
|
||||
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, pdata, data_count);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
|
||||
{
|
||||
/* pretend this succeeded -
|
||||
@ -1783,24 +1909,24 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
|
||||
* we have to send back a list with all files owned by this SID
|
||||
*
|
||||
* but I have to check that --metze
|
||||
*/
|
||||
|
||||
*/
|
||||
DOM_SID sid;
|
||||
uid_t uid;
|
||||
size_t sid_len=SID_MAX_SIZE;
|
||||
size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
|
||||
|
||||
DEBUG(10,("FSCTL_FIND_FILES_BY_SID: fnum=%d control=0x%08x\n",fnum,control));
|
||||
|
||||
/* this is not the length of the sid :-( so unknown 4 bytes */
|
||||
/*sid_len = IVAL(pdata,0);
|
||||
DEBUGADD(0,("sid_len: (%u)\n",sid_len));*/
|
||||
DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
|
||||
|
||||
FSP_BELONGS_CONN(fsp,conn);
|
||||
|
||||
/* unknown 4 bytes: this is not the length of the sid :-( */
|
||||
/*unknown = IVAL(pdata,0);*/
|
||||
|
||||
sid_parse(pdata+4,sid_len,&sid);
|
||||
DEBUGADD(10,("SID: %s\n",sid_string_static(&sid)));
|
||||
DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
|
||||
|
||||
if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &uid))) {
|
||||
DEBUG(0,("sid_to_uid: failed, sid[%s]\n",
|
||||
sid_string_static(&sid)));
|
||||
DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%u]\n",
|
||||
sid_string_static(&sid),sid_len));
|
||||
uid = (-1);
|
||||
}
|
||||
|
||||
@ -1813,6 +1939,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
|
||||
* for each file
|
||||
*
|
||||
* but I don't know how to deal with the paged results
|
||||
* (maybe we can hang the result anywhere in the fsp struct)
|
||||
*
|
||||
* we don't send all files at once
|
||||
* and at the next we should *not* start from the beginning,
|
||||
@ -1829,7 +1956,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
|
||||
if (!logged_message) {
|
||||
logged_message = True; /* Only print this once... */
|
||||
DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
|
||||
control));
|
||||
function));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,42 @@ SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *con
|
||||
result = sys_disk_free(path, small_query, bsize, dfree, dsize);
|
||||
return result;
|
||||
}
|
||||
|
||||
int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
|
||||
{
|
||||
#ifdef HAVE_SYS_QUOTAS
|
||||
int result;
|
||||
|
||||
START_PROFILE(syscall_get_quota);
|
||||
result = sys_get_quota(conn->connectpath, qtype, id, qt);
|
||||
END_PROFILE(syscall_get_quota);
|
||||
return result;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
|
||||
{
|
||||
#ifdef HAVE_SYS_QUOTAS
|
||||
int result;
|
||||
|
||||
START_PROFILE(syscall_set_quota);
|
||||
result = sys_set_quota(conn->connectpath, qtype, id, qt);
|
||||
END_PROFILE(syscall_set_quota);
|
||||
return result;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1; /* Not implemented. */
|
||||
}
|
||||
|
||||
/* Directory operations */
|
||||
|
||||
@ -756,36 +792,6 @@ int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct
|
||||
return sys_acl_free_qualifier(qualifier, tagtype);
|
||||
}
|
||||
|
||||
int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
|
||||
{
|
||||
#ifdef HAVE_SYS_QUOTAS
|
||||
int result;
|
||||
|
||||
START_PROFILE(syscall_get_quota);
|
||||
result = sys_get_quota(conn->connectpath, qtype, id, qt);
|
||||
END_PROFILE(syscall_get_quota);
|
||||
return result;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
|
||||
{
|
||||
#ifdef HAVE_SYS_QUOTAS
|
||||
int result;
|
||||
|
||||
START_PROFILE(syscall_set_quota);
|
||||
result = sys_set_quota(conn->connectpath, qtype, id, qt);
|
||||
END_PROFILE(syscall_set_quota);
|
||||
return result;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Extended attribute operations.
|
||||
*****************************************************************/
|
||||
|
@ -56,6 +56,7 @@ static struct vfs_ops default_vfs = {
|
||||
vfswrap_disk_free,
|
||||
vfswrap_get_quota,
|
||||
vfswrap_set_quota,
|
||||
vfswrap_get_shadow_copy_data,
|
||||
|
||||
/* Directory operations */
|
||||
|
||||
@ -140,7 +141,6 @@ static struct vfs_ops default_vfs = {
|
||||
vfswrap_setxattr,
|
||||
vfswrap_lsetxattr,
|
||||
vfswrap_fsetxattr
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user