Skip to content

Commit

Permalink
Support Win7 32bit delete not empty directory
Browse files Browse the repository at this point in the history
  • Loading branch information
huang96962 committed May 8, 2015
1 parent 83f201a commit d6e25be
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 4 deletions.
6 changes: 6 additions & 0 deletions usr/src/uts/common/fs/smbsrv/smb_fsops.c
Expand Up @@ -899,6 +899,12 @@ smb_fsop_rmdir(
return (rc);
}

int
smb_fsop_dir_is_empty(vnode_t *dnode, cred_t *cr)
{
return smb_vop_dir_is_empty(dnode, cr);
}

/*
* smb_fsop_getattr
*
Expand Down
6 changes: 6 additions & 0 deletions usr/src/uts/common/fs/smbsrv/smb_node.c
Expand Up @@ -619,6 +619,12 @@ smb_node_set_delete_on_close(smb_node_t *node, cred_t *cr, uint32_t flags)
return (-1);
}

if (smb_node_is_dir(node)) {
if (smb_fsop_dir_is_empty(node->vp, cr) == 0) {
return (ERROR_DIR_NOT_EMPTY);
}
}

mutex_enter(&node->n_mutex);
if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
rc = -1;
Expand Down
15 changes: 11 additions & 4 deletions usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c
Expand Up @@ -699,13 +699,20 @@ smb_set_disposition_info(smb_request_t *sr, smb_setinfo_t *sinfo)
}

if (mark_delete) {
int rc;
if (SMB_TREE_SUPPORTS_CATIA(sr))
flags |= SMB_CATIA;

if (smb_node_set_delete_on_close(sinfo->si_node,
sr->user_cr, flags)) {
smbsr_error(sr, NT_STATUS_CANNOT_DELETE,
ERRDOS, ERROR_ACCESS_DENIED);
if (rc = smb_node_set_delete_on_close(sinfo->si_node,
sr->user_cr, flags)) {
if (rc == ERROR_DIR_NOT_EMPTY) {
smbsr_error(sr, NT_STATUS_DIRECTORY_NOT_EMPTY,
ERRDOS, ERROR_DIR_NOT_EMPTY);
}
else {
smbsr_error(sr, NT_STATUS_CANNOT_DELETE,
ERRDOS, ERROR_ACCESS_DENIED);
}
return (-1);
}
} else {
Expand Down
65 changes: 65 additions & 0 deletions usr/src/uts/common/fs/smbsrv/smb_vops.c
Expand Up @@ -828,6 +828,71 @@ smb_vop_rmdir(vnode_t *dvp, char *name, int flags, cred_t *cr)
return (error);
}

int
smb_vop_dir_is_empty(vnode_t *vp, cred_t *cr)
{
#define DIR_BUF_SIZE 1024

int error;
char *buf;
int rc = 1;
struct uio auio;
struct iovec aiov;
int eof, flags;

buf = kmem_alloc(DIR_BUF_SIZE, KM_SLEEP);
if (buf == NULL)
return 0;

if (vfs_has_feature(vp->v_vfsp, VFSFT_DIRENTFLAGS)) {
flags = V_RDDIR_ENTFLAGS;
}
else {
flags = 0;
}
aiov.iov_base = buf;
aiov.iov_len = DIR_BUF_SIZE;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_loffset = 0;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_extflg = UIO_COPY_DEFAULT;
auio.uio_resid = DIR_BUF_SIZE;
auio.uio_fmode = 0;

(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, &smb_ct);
error = VOP_READDIR(vp, &auio, cr, &eof, &smb_ct, flags);
VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, &smb_ct);

if (error != 0) {
rc = 0;
} else {
int reclen = 0;
char *name;
while (reclen < DIR_BUF_SIZE - auio.uio_resid) {
if (flags = V_RDDIR_ENTFLAGS) {
edirent_t *edp = (edirent_t *)(buf + reclen);
reclen += edp->ed_reclen;
name = edp->ed_name;
}
else {
dirent64_t *dp = (dirent64_t *)(buf + reclen);
reclen += dp->d_reclen;
name = dp->d_name;
}
if ((name[0] == '.') && (name[1] == 0))
continue;
if ((name[0] == '.') && (name[1] == '.') && (name[2] == 0))
continue;
rc = 0;
break;
}
}

kmem_free(buf, DIR_BUF_SIZE);
return rc;
}

int
smb_vop_commit(vnode_t *vp, cred_t *cr)
{
Expand Down
2 changes: 2 additions & 0 deletions usr/src/uts/common/smbsrv/smb_fsops.h
Expand Up @@ -60,6 +60,8 @@ int smb_fsop_remove(smb_request_t *sr, cred_t *cr, smb_node_t *,

int smb_fsop_rmdir(smb_request_t *, cred_t *, smb_node_t *, char *, uint32_t);

int smb_fsop_dir_is_empty(vnode_t *dnode, cred_t *cr);

int smb_fsop_getattr(smb_request_t *, cred_t *, smb_node_t *, smb_attr_t *);

int smb_maybe_mangled_name(char *);
Expand Down
1 change: 1 addition & 0 deletions usr/src/uts/common/smbsrv/smb_vops.h
Expand Up @@ -141,6 +141,7 @@ int smb_vop_rename(vnode_t *, char *, vnode_t *, char *, int, cred_t *);
int smb_vop_mkdir(vnode_t *, char *, smb_attr_t *, vnode_t **, int, cred_t *,
vsecattr_t *);
int smb_vop_rmdir(vnode_t *, char *, int, cred_t *);
int smb_vop_dir_is_empty(vnode_t *vp, cred_t *cr);
int smb_vop_readdir(vnode_t *, uint32_t, void *, int *, int *,
uint32_t, cred_t *);
int smb_vop_commit(vnode_t *, cred_t *);
Expand Down

0 comments on commit d6e25be

Please sign in to comment.