diff options
Diffstat (limited to 'usr/src/uts/common')
20 files changed, 458 insertions, 47 deletions
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c index ce95e1c809..21dff73b3c 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c +++ b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c @@ -1007,7 +1007,8 @@ smb_trans_net_workstation_getinfo(struct smb_request *sr, struct smb_xa *xa) (void) smb_mbc_encodef(&xa->rep_data_mb, "l", MBC_LENGTH(&str_mb)); (void) smb_mbc_encodef(&str_mb, "s", domain); (void) smb_mbc_encodef(&xa->rep_data_mb, "bbl", - sr->sr_cfg->skc_version.sv_major, sr->sr_cfg->skc_version.sv_minor, + (uint8_t)sr->sr_cfg->skc_version.sv_major, + (uint8_t)sr->sr_cfg->skc_version.sv_minor, MBC_LENGTH(&str_mb)); (void) smb_mbc_encodef(&str_mb, "s", domain); (void) smb_mbc_encodef(&xa->rep_data_mb, "l", MBC_LENGTH(&str_mb)); @@ -1070,8 +1071,8 @@ smb_trans_net_server_getinfo(struct smb_request *sr, struct smb_xa *xa) (void) smb_mbc_encodef(&str_mb, "s", sr->sr_cfg->skc_system_comment); (void) smb_mbc_encodef(&xa->rep_data_mb, "16cbbll", server_name, - sr->sr_cfg->skc_version.sv_major, - sr->sr_cfg->skc_version.sv_minor, + (uint8_t)sr->sr_cfg->skc_version.sv_major, + (uint8_t)sr->sr_cfg->skc_version.sv_minor, MY_SERVER_TYPE, max_data - MBC_LENGTH(&str_mb)); break; @@ -1315,8 +1316,8 @@ smb_trans_net_server_enum2(struct smb_request *sr, struct smb_xa *xa) (void) smb_mbc_encodef(&xa->rep_data_mb, "16c", hostname); if (level == 1) { (void) smb_mbc_encodef(&xa->rep_data_mb, "bbll", - sr->sr_cfg->skc_version.sv_major, - sr->sr_cfg->skc_version.sv_minor, + (uint8_t)sr->sr_cfg->skc_version.sv_major, + (uint8_t)sr->sr_cfg->skc_version.sv_minor, MY_SERVER_TYPE, MBC_LENGTH(&str_mb)); (void) smb_mbc_encodef(&str_mb, "s", si->skc_system_comment); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_fsinfo.c b/usr/src/uts/common/fs/smbsrv/smb_fsinfo.c index eb408b34e0..519bc1ff1f 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_fsinfo.c +++ b/usr/src/uts/common/fs/smbsrv/smb_fsinfo.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <smbsrv/smb_kproto.h> @@ -336,6 +335,9 @@ smb_com_trans2_query_fs_information(smb_request_t *sr, smb_xa_t *xa) if (tree->t_flags & SMB_TREE_QUOTA) flags |= FILE_VOLUME_QUOTAS; + if (tree->t_flags & SMB_TREE_SPARSE) + flags |= FILE_SUPPORTS_SPARSE_FILES; + (void) smb_mbc_encodef(&xa->rep_data_mb, encode_str, sr, flags, MAXNAMELEN, /* max name */ diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c index 1caab2937a..f214b41310 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c +++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c @@ -27,8 +27,11 @@ static uint32_t smb_nt_trans_ioctl_noop(smb_request_t *, smb_xa_t *); -static uint32_t smb_nt_trans_ioctl_invalid_parm(smb_request_t *, +static uint32_t smb_nt_trans_ioctl_invalid_parm(smb_request_t *, smb_xa_t *); +static uint32_t smb_nt_trans_ioctl_set_sparse(smb_request_t *, smb_xa_t *); +static uint32_t smb_nt_trans_ioctl_query_alloc_ranges(smb_request_t *, smb_xa_t *); +static uint32_t smb_nt_trans_ioctl_set_zero_data(smb_request_t *, smb_xa_t *); /* * This table defines the list of FSCTL values for which we'll @@ -43,9 +46,10 @@ static struct { uint32_t (*ioctl_func)(smb_request_t *sr, smb_xa_t *xa); } ioctl_ret_tbl[] = { { FSCTL_GET_OBJECT_ID, smb_nt_trans_ioctl_invalid_parm }, - { FSCTL_QUERY_ALLOCATED_RANGES, smb_nt_trans_ioctl_invalid_parm }, + { FSCTL_QUERY_ALLOCATED_RANGES, smb_nt_trans_ioctl_query_alloc_ranges }, + { FSCTL_SET_ZERO_DATA, smb_nt_trans_ioctl_set_zero_data }, { FSCTL_SRV_ENUMERATE_SNAPSHOTS, smb_vss_ioctl_enumerate_snaps }, - { FSCTL_SET_SPARSE, smb_nt_trans_ioctl_noop }, + { FSCTL_SET_SPARSE, smb_nt_trans_ioctl_set_sparse }, { FSCTL_FIND_FILES_BY_SID, smb_nt_trans_ioctl_noop } }; @@ -84,13 +88,12 @@ smb_nt_transact_ioctl(smb_request_t *sr, smb_xa_t *xa) { uint32_t status = NT_STATUS_NOT_SUPPORTED; uint32_t fcode; - unsigned short fid; unsigned char is_fsctl; unsigned char is_flags; int i; if (smb_mbc_decodef(&xa->req_setup_mb, "lwbb", - &fcode, &fid, &is_fsctl, &is_flags) != 0) { + &fcode, &sr->smb_fid, &is_fsctl, &is_flags) != 0) { smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0); return (SDRC_ERROR); } @@ -129,3 +132,188 @@ smb_nt_trans_ioctl_invalid_parm(smb_request_t *sr, smb_xa_t *xa) { return (NT_STATUS_INVALID_PARAMETER); } + +/* + * smb_nt_trans_ioctl_set_sparse + * + * There may, or may not be a data block in this request. + * If there IS a data block, the first byte is a boolean + * specifying whether to set (non zero) or clear (zero) + * the sparse attribute of the file. + * If there is no data block, this indicates a request to + * set the sparse attribute. + */ +static uint32_t +smb_nt_trans_ioctl_set_sparse(smb_request_t *sr, smb_xa_t *xa) +{ + int rc = 0; + uint8_t set = 1; + smb_node_t *node; + smb_attr_t attr; + + if (SMB_TREE_IS_READONLY(sr)) + return (NT_STATUS_ACCESS_DENIED); + + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) + return (NT_STATUS_INVALID_PARAMETER); + + smbsr_lookup_file(sr); + if (sr->fid_ofile == NULL) + return (NT_STATUS_INVALID_HANDLE); + + if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) { + smbsr_release_file(sr); + return (NT_STATUS_INVALID_PARAMETER); + } + + node = sr->fid_ofile->f_node; + if (smb_node_is_dir(node)) { + smbsr_release_file(sr); + return (NT_STATUS_INVALID_PARAMETER); + } + + if (smbsr_decode_data_avail(sr)) { + if (smb_mbc_decodef(&xa->req_data_mb, "b", &set) != 0) { + smbsr_release_file(sr); + return (sr->smb_error.status); + } + } + + bzero(&attr, sizeof (smb_attr_t)); + attr.sa_mask = SMB_AT_DOSATTR; + if ((rc = smb_node_getattr(sr, node, &attr)) != 0) { + smbsr_errno(sr, rc); + smbsr_release_file(sr); + return (sr->smb_error.status); + } + + attr.sa_mask = 0; + if ((set == 0) && + (attr.sa_dosattr & FILE_ATTRIBUTE_SPARSE_FILE)) { + attr.sa_dosattr &= ~FILE_ATTRIBUTE_SPARSE_FILE; + attr.sa_mask = SMB_AT_DOSATTR; + } else if ((set != 0) && + !(attr.sa_dosattr & FILE_ATTRIBUTE_SPARSE_FILE)) { + attr.sa_dosattr |= FILE_ATTRIBUTE_SPARSE_FILE; + attr.sa_mask = SMB_AT_DOSATTR; + } + + if (attr.sa_mask != 0) { + rc = smb_node_setattr(sr, node, sr->user_cr, NULL, &attr); + if (rc != 0) { + smbsr_errno(sr, rc); + smbsr_release_file(sr); + return (sr->smb_error.status); + } + } + + smbsr_release_file(sr); + return (NT_STATUS_SUCCESS); +} + +/* + * smb_nt_trans_ioctl_set_zero_data + * + * Check that the request is valid on the specified file. + * The implementation is a noop. + */ +/* ARGSUSED */ +static uint32_t +smb_nt_trans_ioctl_set_zero_data(smb_request_t *sr, smb_xa_t *xa) +{ + smb_node_t *node; + + if (SMB_TREE_IS_READONLY(sr)) + return (NT_STATUS_ACCESS_DENIED); + + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) + return (NT_STATUS_INVALID_PARAMETER); + + smbsr_lookup_file(sr); + if (sr->fid_ofile == NULL) + return (NT_STATUS_INVALID_HANDLE); + + if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) { + smbsr_release_file(sr); + return (NT_STATUS_INVALID_PARAMETER); + } + + node = sr->fid_ofile->f_node; + if (smb_node_is_dir(node)) { + smbsr_release_file(sr); + return (NT_STATUS_INVALID_PARAMETER); + } + + smbsr_release_file(sr); + return (NT_STATUS_SUCCESS); +} + +/* + * smb_nt_trans_ioctl_query_alloc_ranges + * + * Responds with either: + * - no data if the file is zero size + * - a single range containing the starting point and length requested + */ +static uint32_t +smb_nt_trans_ioctl_query_alloc_ranges(smb_request_t *sr, smb_xa_t *xa) +{ + int rc; + uint64_t offset, len; + smb_node_t *node; + smb_attr_t attr; + + if (STYPE_ISIPC(sr->tid_tree->t_res_type)) + return (NT_STATUS_INVALID_PARAMETER); + + smbsr_lookup_file(sr); + if (sr->fid_ofile == NULL) + return (NT_STATUS_INVALID_HANDLE); + + if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) { + smbsr_release_file(sr); + return (NT_STATUS_INVALID_PARAMETER); + } + + node = sr->fid_ofile->f_node; + if (smb_node_is_dir(node)) { + smbsr_release_file(sr); + return (NT_STATUS_INVALID_PARAMETER); + } + + /* If zero size file don't return any data */ + bzero(&attr, sizeof (smb_attr_t)); + attr.sa_mask = SMB_AT_SIZE; + if ((rc = smb_node_getattr(sr, node, &attr)) != 0) { + smbsr_errno(sr, rc); + smbsr_release_file(sr); + return (sr->smb_error.status); + } + + if (attr.sa_vattr.va_size == 0) { + smbsr_release_file(sr); + return (NT_STATUS_SUCCESS); + } + + if (smb_mbc_decodef(&xa->req_data_mb, "qq", &offset, &len) != 0) { + smbsr_release_file(sr); + return (sr->smb_error.status); + } + + /* + * Return a single range regardless of whether the file + * is sparse or not. + */ + if (MBC_ROOM_FOR(&xa->rep_data_mb, 16) == 0) { + smbsr_release_file(sr); + return (NT_STATUS_BUFFER_TOO_SMALL); + } + + if (smb_mbc_encodef(&xa->rep_data_mb, "qq", offset, len) != 0) { + smbsr_release_file(sr); + return (sr->smb_error.status); + } + + smbsr_release_file(sr); + return (NT_STATUS_SUCCESS); +} diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree.c b/usr/src/uts/common/fs/smbsrv/smb_tree.c index 3b4b0b0c98..03a4e856c1 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_tree.c +++ b/usr/src/uts/common/fs/smbsrv/smb_tree.c @@ -1107,7 +1107,8 @@ smb_tree_get_flags(const smb_kshare_t *si, vfs_t *vfsp, smb_tree_t *tree) } smb_mtype_t; static smb_mtype_t smb_mtype[] = { - { "zfs", 3, SMB_TREE_UNICODE_ON_DISK | SMB_TREE_QUOTA }, + { "zfs", 3, SMB_TREE_UNICODE_ON_DISK | + SMB_TREE_QUOTA | SMB_TREE_SPARSE}, { "ufs", 3, SMB_TREE_UNICODE_ON_DISK }, { "nfs", 3, SMB_TREE_NFS_MOUNTED }, { "tmpfs", 5, SMB_TREE_NO_EXPORT } diff --git a/usr/src/uts/common/fs/smbsrv/smb_vops.c b/usr/src/uts/common/fs/smbsrv/smb_vops.c index 41291b290f..197a3b7bc2 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_vops.c +++ b/usr/src/uts/common/fs/smbsrv/smb_vops.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/types.h> @@ -328,6 +327,8 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr, XVA_SET_REQ(&tmp_xvattr, XAT_ARCHIVE); XVA_SET_REQ(&tmp_xvattr, XAT_CREATETIME); XVA_SET_REQ(&tmp_xvattr, XAT_REPARSE); + XVA_SET_REQ(&tmp_xvattr, XAT_OFFLINE); + XVA_SET_REQ(&tmp_xvattr, XAT_SPARSE); error = VOP_GETATTR(use_vp, &tmp_xvattr.xva_vattr, flags, cr, &smb_ct); @@ -367,6 +368,17 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr, FILE_ATTRIBUTE_REPARSE_POINT; } + if ((XVA_ISSET_RTN(&tmp_xvattr, XAT_OFFLINE)) && + (xoap->xoa_offline)) { + ret_attr->sa_dosattr |= FILE_ATTRIBUTE_OFFLINE; + } + + if ((XVA_ISSET_RTN(&tmp_xvattr, XAT_SPARSE)) && + (xoap->xoa_sparse)) { + ret_attr->sa_dosattr |= + FILE_ATTRIBUTE_SPARSE_FILE; + } + ret_attr->sa_crtime = xoap->xoa_createtime; } else { ret_attr->sa_crtime = ret_attr->sa_vattr.va_mtime; @@ -442,7 +454,8 @@ smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *attr, if (attr->sa_mask & SMB_AT_DOSATTR) { attr->sa_dosattr &= (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY | - FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM); + FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_SPARSE_FILE); } if (unnamed_vp) { @@ -860,6 +873,8 @@ smb_vop_setup_xvattr(smb_attr_t *smb_attr, xvattr_t *xvattr) XVA_SET_REQ(xvattr, XAT_SYSTEM); XVA_SET_REQ(xvattr, XAT_READONLY); XVA_SET_REQ(xvattr, XAT_HIDDEN); + XVA_SET_REQ(xvattr, XAT_OFFLINE); + XVA_SET_REQ(xvattr, XAT_SPARSE); /* * smb_attr->sa_dosattr: If a given bit is not set, @@ -879,6 +894,12 @@ smb_vop_setup_xvattr(smb_attr_t *smb_attr, xvattr_t *xvattr) if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_HIDDEN) xoap->xoa_hidden = 1; + + if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_OFFLINE) + xoap->xoa_offline = 1; + + if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_SPARSE_FILE) + xoap->xoa_sparse = 1; } if (smb_attr->sa_mask & SMB_AT_CRTIME) { diff --git a/usr/src/uts/common/fs/xattr.c b/usr/src/uts/common/fs/xattr.c index 1657f25549..a1173e69f5 100644 --- a/usr/src/uts/common/fs/xattr.c +++ b/usr/src/uts/common/fs/xattr.c @@ -228,6 +228,12 @@ xattr_fill_nvlist(vnode_t *vp, xattr_view_t xattr_view, nvlist_t *nvlp, case F_GEN: XVA_SET_REQ(&xvattr, XAT_GEN); break; + case F_OFFLINE: + XVA_SET_REQ(&xvattr, XAT_OFFLINE); + break; + case F_SPARSE: + XVA_SET_REQ(&xvattr, XAT_SPARSE); + break; default: break; } @@ -320,6 +326,16 @@ xattr_fill_nvlist(vnode_t *vp, xattr_view_t xattr_view, nvlist_t *nvlp, attr_to_name(F_GEN), xoap->xoa_generation) == 0); } + if (XVA_ISSET_RTN(&xvattr, XAT_OFFLINE)) { + VERIFY(nvlist_add_boolean_value(nvlp, + attr_to_name(F_OFFLINE), + xoap->xoa_offline) == 0); + } + if (XVA_ISSET_RTN(&xvattr, XAT_SPARSE)) { + VERIFY(nvlist_add_boolean_value(nvlp, + attr_to_name(F_SPARSE), + xoap->xoa_sparse) == 0); + } } /* * Check for optional ownersid/groupsid @@ -697,6 +713,14 @@ xattr_file_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, XVA_SET_REQ(&xvattr, XAT_REPARSE); xoap->xoa_reparse = value; break; + case F_OFFLINE: + XVA_SET_REQ(&xvattr, XAT_OFFLINE); + xoap->xoa_offline = value; + break; + case F_SPARSE: + XVA_SET_REQ(&xvattr, XAT_SPARSE); + xoap->xoa_sparse = value; + break; default: break; } @@ -838,6 +862,8 @@ xattr_copy(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, XVA_SET_REQ(&xvattr, XAT_AV_QUARANTINED); XVA_SET_REQ(&xvattr, XAT_CREATETIME); XVA_SET_REQ(&xvattr, XAT_REPARSE); + XVA_SET_REQ(&xvattr, XAT_OFFLINE); + XVA_SET_REQ(&xvattr, XAT_SPARSE); pdvp = gfs_file_parent(sdvp); error = VOP_GETATTR(pdvp, &xvattr.xva_vattr, 0, cr, ct); diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_znode.h b/usr/src/uts/common/fs/zfs/sys/zfs_znode.h index b51287d565..3e9621a0ee 100644 --- a/usr/src/uts/common/fs/zfs/sys/zfs_znode.h +++ b/usr/src/uts/common/fs/zfs/sys/zfs_znode.h @@ -60,6 +60,8 @@ extern "C" { #define ZFS_AV_QUARANTINED 0x0000020000000000 #define ZFS_AV_MODIFIED 0x0000040000000000 #define ZFS_REPARSE 0x0000080000000000 +#define ZFS_OFFLINE 0x0000100000000000 +#define ZFS_SPARSE 0x0000200000000000 #define ZFS_ATTR_SET(zp, attr, value, pflags, tx) \ { \ diff --git a/usr/src/uts/common/fs/zfs/zfs_log.c b/usr/src/uts/common/fs/zfs/zfs_log.c index 70368481cc..26ab78279b 100644 --- a/usr/src/uts/common/fs/zfs/zfs_log.c +++ b/usr/src/uts/common/fs/zfs/zfs_log.c @@ -169,6 +169,12 @@ zfs_log_xvattr(lr_attr_t *lrattr, xvattr_t *xvap) if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) *attrs |= (xoap->xoa_reparse == 0) ? 0 : XAT0_REPARSE; + if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) + *attrs |= (xoap->xoa_offline == 0) ? 0 : + XAT0_OFFLINE; + if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) + *attrs |= (xoap->xoa_sparse == 0) ? 0 : + XAT0_SPARSE; } static void * diff --git a/usr/src/uts/common/fs/zfs/zfs_replay.c b/usr/src/uts/common/fs/zfs/zfs_replay.c index f4fb5aceb6..9fb3368569 100644 --- a/usr/src/uts/common/fs/zfs/zfs_replay.c +++ b/usr/src/uts/common/fs/zfs/zfs_replay.c @@ -128,6 +128,10 @@ zfs_replay_xvattr(lr_attr_t *lrattr, xvattr_t *xvap) bcopy(scanstamp, xoap->xoa_av_scanstamp, AV_SCANSTAMP_SZ); if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) xoap->xoa_reparse = ((*attrs & XAT0_REPARSE) != 0); + if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) + xoap->xoa_offline = ((*attrs & XAT0_OFFLINE) != 0); + if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) + xoap->xoa_sparse = ((*attrs & XAT0_SPARSE) != 0); } static int diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index 94234f3a25..7e3d85577a 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -2543,6 +2543,18 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, xoap->xoa_generation = zp->z_gen; XVA_SET_RTN(xvap, XAT_GEN); } + + if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) { + xoap->xoa_offline = + ((zp->z_pflags & ZFS_OFFLINE) != 0); + XVA_SET_RTN(xvap, XAT_OFFLINE); + } + + if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) { + xoap->xoa_sparse = + ((zp->z_pflags & ZFS_SPARSE) != 0); + XVA_SET_RTN(xvap, XAT_SPARSE); + } } ZFS_TIME_DECODE(&vap->va_atime, zp->z_atime); @@ -2720,6 +2732,8 @@ top: ((mask & AT_XVATTR) && (XVA_ISSET_REQ(xvap, XAT_HIDDEN) || XVA_ISSET_REQ(xvap, XAT_READONLY) || XVA_ISSET_REQ(xvap, XAT_ARCHIVE) || + XVA_ISSET_REQ(xvap, XAT_OFFLINE) || + XVA_ISSET_REQ(xvap, XAT_SPARSE) || XVA_ISSET_REQ(xvap, XAT_CREATETIME) || XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) { need_policy = zfs_zaccess(zp, ACE_WRITE_ATTRIBUTES, 0, diff --git a/usr/src/uts/common/fs/zfs/zfs_znode.c b/usr/src/uts/common/fs/zfs/zfs_znode.c index 292912d382..e1e4e9e03a 100644 --- a/usr/src/uts/common/fs/zfs/zfs_znode.c +++ b/usr/src/uts/common/fs/zfs/zfs_znode.c @@ -1088,6 +1088,16 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) zp->z_pflags, tx); XVA_SET_RTN(xvap, XAT_REPARSE); } + if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) { + ZFS_ATTR_SET(zp, ZFS_OFFLINE, xoap->xoa_offline, + zp->z_pflags, tx); + XVA_SET_RTN(xvap, XAT_OFFLINE); + } + if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) { + ZFS_ATTR_SET(zp, ZFS_SPARSE, xoap->xoa_sparse, + zp->z_pflags, tx); + XVA_SET_RTN(xvap, XAT_SPARSE); + } } int @@ -1564,6 +1574,8 @@ zfs_trunc(znode_t *zp, uint64_t end) dmu_tx_t *tx; rl_t *rl; int error; + sa_bulk_attr_t bulk[2]; + int count = 0; /* * We will change zp_size, lock the whole file. @@ -1600,9 +1612,15 @@ top: } zp->z_size = end; + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), + NULL, &zp->z_size, sizeof (zp->z_size)); - VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SIZE(zp->z_zfsvfs), - &zp->z_size, sizeof (zp->z_size), tx)); + if (end == 0) { + zp->z_pflags &= ~ZFS_SPARSE; + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), + NULL, &zp->z_pflags, 8); + } + VERIFY(sa_bulk_update(zp->z_sa_hdl, bulk, count, tx) == 0); dmu_tx_commit(tx); diff --git a/usr/src/uts/common/fs/zut/zut.c b/usr/src/uts/common/fs/zut/zut.c index c655585968..a1c5555a39 100644 --- a/usr/src/uts/common/fs/zut/zut.c +++ b/usr/src/uts/common/fs/zut/zut.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/conf.h> @@ -218,6 +217,8 @@ zut_stat64(vnode_t *vp, struct stat64 *sb, uint64_t *xvs, int flag, cred_t *cr) XVA_SET_REQ(&xv, XAT_AV_QUARANTINED); XVA_SET_REQ(&xv, XAT_AV_MODIFIED); XVA_SET_REQ(&xv, XAT_REPARSE); + XVA_SET_REQ(&xv, XAT_OFFLINE); + XVA_SET_REQ(&xv, XAT_SPARSE); xv.xva_vattr.va_mask |= AT_STAT | AT_NBLOCKS | AT_BLKSIZE | AT_SIZE; if (error = VOP_GETATTR(vp, &xv.xva_vattr, flag, cr, NULL)) @@ -266,6 +267,10 @@ zut_stat64(vnode_t *vp, struct stat64 *sb, uint64_t *xvs, int flag, cred_t *cr) *xvs |= (1 << F_AV_MODIFIED); if (XVA_ISSET_RTN(&xv, XAT_REPARSE) && xoap->xoa_reparse) *xvs |= (1 << F_REPARSE); + if (XVA_ISSET_RTN(&xv, XAT_OFFLINE) && xoap->xoa_offline) + *xvs |= (1 << F_OFFLINE); + if (XVA_ISSET_RTN(&xv, XAT_SPARSE) && xoap->xoa_sparse) + *xvs |= (1 << F_SPARSE); return (0); } diff --git a/usr/src/uts/common/os/policy.c b/usr/src/uts/common/os/policy.c index e68565f141..573ebbc367 100644 --- a/usr/src/uts/common/os/policy.c +++ b/usr/src/uts/common/os/policy.c @@ -1296,7 +1296,9 @@ secpolicy_xvattr(xvattr_t *xvap, uid_t owner, cred_t *cr, vtype_t vtype) XVA_ISSET_REQ(xvap, XAT_HIDDEN) || XVA_ISSET_REQ(xvap, XAT_READONLY) || XVA_ISSET_REQ(xvap, XAT_SYSTEM) || - XVA_ISSET_REQ(xvap, XAT_CREATETIME)) { + XVA_ISSET_REQ(xvap, XAT_CREATETIME) || + XVA_ISSET_REQ(xvap, XAT_OFFLINE) || + XVA_ISSET_REQ(xvap, XAT_SPARSE)) { if ((error = secpolicy_vnode_owner(cr, owner)) != 0) return (error); } diff --git a/usr/src/uts/common/smbsrv/ndl/lsarpc.ndl b/usr/src/uts/common/smbsrv/ndl/lsarpc.ndl index bee3b9f02e..2d89687a6a 100644 --- a/usr/src/uts/common/smbsrv/ndl/lsarpc.ndl +++ b/usr/src/uts/common/smbsrv/ndl/lsarpc.ndl @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _MLSVC_LSA_NDL_ @@ -519,7 +518,7 @@ struct mslsa_LookupSids { OUT struct mslsa_domain_table *domain_table; INOUT struct mslsa_name_table name_table; - IN DWORD lookup_level; + IN WORD lookup_level; INOUT DWORD mapped_count; OUT DWORD status; }; @@ -577,15 +576,15 @@ struct mslsa_rid_table { OPERATION(LSARPC_OPNUM_LookupNames) struct mslsa_LookupNames { - IN mslsa_handle_t handle; + IN mslsa_handle_t handle; IN REFERENCE struct mslsa_lup_name_table *name_table; - OUT struct mslsa_domain_table *domain_table; + OUT struct mslsa_domain_table *domain_table; INOUT struct mslsa_rid_table translated_sids; - IN DWORD lookup_level; + IN WORD lookup_level; INOUT DWORD mapped_count; - OUT DWORD status; + OUT DWORD status; }; @@ -879,7 +878,7 @@ struct lsar_lookup_sids2 { IN struct mslsa_lup_sid_table lup_sid_table; OUT struct mslsa_domain_table *domain_table; INOUT struct lsar_name_table2 name_table; - IN DWORD lookup_level; + IN WORD lookup_level; INOUT DWORD mapped_count; IN DWORD lookup_options; IN DWORD client_revision; @@ -891,7 +890,7 @@ struct lsar_lookup_sids3 { IN struct mslsa_lup_sid_table lup_sid_table; OUT struct mslsa_domain_table *domain_table; INOUT lsar_translated_names_ex_t name_table; - IN DWORD lookup_level; + IN WORD lookup_level; INOUT DWORD mapped_count; IN DWORD lookup_options; IN DWORD client_revision; @@ -930,7 +929,7 @@ struct lsar_LookupNames2 { IN REFERENCE struct mslsa_lup_name_table *name_table; OUT struct mslsa_domain_table *domain_table; INOUT struct lsar_rid_table2 translated_sids; - IN DWORD lookup_level; + IN WORD lookup_level; INOUT DWORD mapped_count; IN DWORD lookup_options; IN DWORD client_revision; @@ -959,7 +958,7 @@ struct lsar_LookupNames3 { IN REFERENCE struct mslsa_lup_name_table *name_table; OUT struct mslsa_domain_table *domain_table; INOUT struct lsar_sid_ex2_table translated_sids; - IN DWORD lookup_level; + IN WORD lookup_level; INOUT DWORD mapped_count; IN DWORD lookup_options; IN DWORD client_revision; @@ -971,7 +970,7 @@ struct lsar_LookupNames4 { IN REFERENCE struct mslsa_lup_name_table *name_table; OUT struct mslsa_domain_table *domain_table; INOUT struct lsar_sid_ex2_table translated_sids; - IN DWORD lookup_level; + IN WORD lookup_level; INOUT DWORD mapped_count; IN DWORD lookup_options; IN DWORD client_revision; diff --git a/usr/src/uts/common/smbsrv/ndl/spoolss.ndl b/usr/src/uts/common/smbsrv/ndl/spoolss.ndl index f614a5759c..a467b5638c 100644 --- a/usr/src/uts/common/smbsrv/ndl/spoolss.ndl +++ b/usr/src/uts/common/smbsrv/ndl/spoolss.ndl @@ -34,6 +34,7 @@ #define TABLE_DEVMODE 4 #define TABLE_SECURITY_DESCRIPTOR 5 +#define SPOOLSS_OPNUM_EnumPrinters 0x00 #define SPOOLSS_OPNUM_OpenPrinter 0x01 #define SPOOLSS_OPNUM_GetJob 0x03 #define SPOOLSS_OPNUM_EnumJobs 0x04 @@ -50,18 +51,27 @@ #define SPOOLSS_OPNUM_ScheduleJob 0x19 #define SPOOLSS_OPNUM_GetPrinterData 0x1a #define SPOOLSS_OPNUM_ClosePrinter 0x1d +#define SPOOLSS_OPNUM_AddForm 0x1e +#define SPOOLSS_OPNUM_DeleteForm 0x1f #define SPOOLSS_OPNUM_EndDocPrinter 0x17 #define SPOOLSS_OPNUM_EnumForms 0x22 +#define SPOOLSS_OPNUM_EnumPorts 0x23 +#define SPOOLSS_OPNUM_EnumMonitor 0x24 +#define SPOOLSS_OPNUM_DeletePort 0x27 #define SPOOLSS_OPNUM_CreatePrinterIC 0x28 +#define SPOOLSS_OPNUM_AddMonitor 0x2e +#define SPOOLSS_OPNUM_DeleteMonitor 0x2f #define SPOOLSS_OPNUM_ResetPrinter 0x34 #define SPOOLSS_OPNUM_GetPrinterDriver2 0x35 #define SPOOLSS_OPNUM_FCPN 0x38 #define SPOOLSS_OPNUM_ReplyOpenPrinter 0x3a #define SPOOLSS_OPNUM_ReplyClosePrinter 0x3c +#define SPOOLSS_OPNUM_AddPortEx 0x3d #define SPOOLSS_OPNUM_RFFPCNEX 0x41 #define SPOOLSS_OPNUM_RRPCN 0x42 #define SPOOLSS_OPNUM_RFNPCNEX 0x43 #define SPOOLSS_OPNUM_OpenPrinterEx 0x45 +#define SPOOLSS_OPNUM_SetPort 0x47 #define SPOOLSS_OPNUM_EnumPrinterData 0x48 #define SPOOLSS_OPNUM_EnumPrinterDataEx 0x4f #define SPOOLSS_OPNUM_EnumPrinterKey 0x50 @@ -126,8 +136,8 @@ struct spoolss_OpenPrinter { IN LPTSTR printer_name; OUT spoolss_handle_t handle; IN LPTSTR data_type; - IN struct spoolssDevmodeContainer dmodeContainer; - IN DWORD AccessRequired; + /* IN struct spoolssDevmodeContainer dmodeContainer; */ + /* IN DWORD AccessRequired; */ OUT DWORD status; }; @@ -451,8 +461,8 @@ struct spoolss_GetPrinterData { IN spoolss_handle_t handle; IN REFERENCE LPTSTR pValueName; OUT DWORD pType; - SIZE_IS(Size) - OUT LPBYTE Buf; + SIZE_IS(Size) + OUT REFERENCE LPBYTE Buf; IN DWORD Size; OUT DWORD Needed; OUT DWORD status; @@ -498,6 +508,54 @@ struct spoolss_AbortPrinter { OUT DWORD status; }; +OPERATION(SPOOLSS_OPNUM_EnumPorts) +struct spoolss_EnumPorts { + IN LPTSTR name; + IN DWORD level; + OUT DWORD needed; + OUT DWORD returned; + OUT DWORD status; +}; + +OPERATION(SPOOLSS_OPNUM_DeletePort) +struct spoolss_DeletePort { + IN LPTSTR name; + OUT DWORD status; +}; + +OPERATION(SPOOLSS_OPNUM_AddPortEx) +struct spoolss_AddPortEx { + IN LPTSTR name; + OUT DWORD status; +}; + +OPERATION(SPOOLSS_OPNUM_SetPort) +struct spoolss_SetPort { + IN LPTSTR name; + OUT DWORD status; +}; + +OPERATION(SPOOLSS_OPNUM_EnumMonitor) +struct spoolss_EnumMonitor { + IN LPTSTR name; + IN DWORD level; + OUT DWORD needed; + OUT DWORD returned; + OUT DWORD status; +}; + +OPERATION(SPOOLSS_OPNUM_AddMonitor) +struct spoolss_AddMonitor { + IN LPTSTR name; + OUT DWORD status; +}; + +OPERATION(SPOOLSS_OPNUM_DeleteMonitor) +struct spoolss_DeleteMonitor { + IN LPTSTR name; + OUT DWORD status; +}; + OPERATION(SPOOLSS_OPNUM_ResetPrinter) struct spoolss_ResetPrinter { IN spoolss_handle_t handle; @@ -570,6 +628,20 @@ struct spoolss_EndDocPrinter { OUT DWORD status; }; +OPERATION(SPOOLSS_OPNUM_AddForm) +struct spoolss_AddForm { + IN spoolss_handle_t handle; + /* FORM_CONTAINER *form_container; */ + OUT DWORD status; +}; + +OPERATION(SPOOLSS_OPNUM_DeleteForm) +struct spoolss_DeleteForm { + IN spoolss_handle_t handle; + /* IN REFERENCE LPTSTR form_name; */ + OUT DWORD status; +}; + OPERATION(SPOOLSS_OPNUM_EnumForms) struct spoolss_EnumForms { IN spoolss_handle_t handle; @@ -637,6 +709,10 @@ OPERATION(SPOOLSS_OPNUM_OpenPrinterEx) struct spoolss_OpenPrinterEx { IN LPTSTR printer_name; OUT spoolss_handle_t handle; + IN LPTSTR data_type; + /* IN struct spoolssDevmodeContainer dmodeContainer; */ + /* IN DWORD AccessRequired; */ + /* IN CLIENT_CONTAINER client_info; */ OUT DWORD status; }; @@ -692,7 +768,16 @@ union spoolss_interface { CASE(SPOOLSS_OPNUM_ResetPrinter) struct spoolss_ResetPrinter ResetPrinter; - + + CASE(SPOOLSS_OPNUM_EnumMonitor) + struct spoolss_EnumMonitor EnumMonitor; + + CASE(SPOOLSS_OPNUM_AddMonitor) + struct spoolss_AddMonitor AddMonitor; + + CASE(SPOOLSS_OPNUM_DeleteMonitor) + struct spoolss_DeleteMonitor DeleteMonitor; + CASE(SPOOLSS_OPNUM_WritePrinter) struct spoolss_WritePrinter WritePrinter; @@ -717,12 +802,27 @@ union spoolss_interface { CASE(SPOOLSS_OPNUM_ScheduleJob) struct spoolss_ScheduleJob ScheduleJob; + CASE(SPOOLSS_OPNUM_AddForm) + struct spoolss_AddForm AddForm; + + CASE(SPOOLSS_OPNUM_DeleteForm) + struct spoolss_DeleteForm DeleteForm; + CASE(SPOOLSS_OPNUM_EnumForms) struct spoolss_EnumForms EnumForms; - CASE(SPOOLSS_OPNUM_EnumJobs) - struct spoolss_EnumJobs EnumJobs; - + CASE(SPOOLSS_OPNUM_EnumPorts) + struct spoolss_EnumPorts EnumPorts; + + CASE(SPOOLSS_OPNUM_DeletePort) + struct spoolss_DeletePort DeletePort; + + CASE(SPOOLSS_OPNUM_AddPortEx) + struct spoolss_AddPortEx AddPortEx; + + CASE(SPOOLSS_OPNUM_SetPort) + struct spoolss_SetPort SetPort; + CASE(SPOOLSS_OPNUM_RFNPCNEX) struct spoolss_RFNPCNEX RFNPCNEX; diff --git a/usr/src/uts/common/smbsrv/smb_ktypes.h b/usr/src/uts/common/smbsrv/smb_ktypes.h index c69226154d..4774790446 100644 --- a/usr/src/uts/common/smbsrv/smb_ktypes.h +++ b/usr/src/uts/common/smbsrv/smb_ktypes.h @@ -1050,6 +1050,7 @@ typedef struct smb_user { #define SMB_TREE_ABE 0x00008000 #define SMB_TREE_QUOTA 0x00010000 #define SMB_TREE_DFSROOT 0x00020000 +#define SMB_TREE_SPARSE 0x00040000 typedef enum { SMB_TREE_STATE_CONNECTED = 0, diff --git a/usr/src/uts/common/smbsrv/smb_share.h b/usr/src/uts/common/smbsrv/smb_share.h index 7e833366e5..6a66853dfc 100644 --- a/usr/src/uts/common/smbsrv/smb_share.h +++ b/usr/src/uts/common/smbsrv/smb_share.h @@ -235,7 +235,7 @@ typedef struct smb_shr_execinfo { */ int smb_shr_start(void); void smb_shr_stop(void); -int smb_shr_load(void); +void *smb_shr_load(void *); void smb_shr_iterinit(smb_shriter_t *); smb_share_t *smb_shr_iterate(smb_shriter_t *); void smb_shr_list(int, smb_shrlist_t *); diff --git a/usr/src/uts/common/smbsrv/smbinfo.h b/usr/src/uts/common/smbsrv/smbinfo.h index 0673551d58..18e259c980 100644 --- a/usr/src/uts/common/smbsrv/smbinfo.h +++ b/usr/src/uts/common/smbsrv/smbinfo.h @@ -102,9 +102,16 @@ extern "C" { */ #define SMB_PI_MAX_WORKERS_MIN 64 +/* + * sv_size is used by the RPC services and should be set to + * sizeof (smb_version_t). + */ typedef struct smb_version { - uint8_t sv_major; - uint8_t sv_minor; + uint32_t sv_size; + uint32_t sv_major; + uint32_t sv_minor; + uint32_t sv_build_number; + uint32_t sv_platform_id; } smb_version_t; typedef struct smb_kmod_cfg { @@ -137,13 +144,14 @@ typedef struct smb_kmod_cfg { /* * Major version numbers */ -#define SMB_MAJOR_NT 4 +#define SMB_MAJOR_NT 4 /* Windows 95/98/Me, Windows NT4.0 */ #define SMB_MAJOR_2000 5 #define SMB_MAJOR_XP 5 #define SMB_MAJOR_2003 5 #define SMB_MAJOR_VISTA 6 #define SMB_MAJOR_2008 6 #define SMB_MAJOR_2008R2 6 +#define SMB_MAJOR_7 6 /* * Minor version numbers @@ -155,6 +163,7 @@ typedef struct smb_kmod_cfg { #define SMB_MINOR_VISTA 0 #define SMB_MINOR_2008 0 #define SMB_MINOR_2008R2 1 +#define SMB_MINOR_7 1 /* * Max version length in string format diff --git a/usr/src/uts/common/sys/attr.h b/usr/src/uts/common/sys/attr.h index 2b049d9cc1..57c579bc5b 100644 --- a/usr/src/uts/common/sys/attr.h +++ b/usr/src/uts/common/sys/attr.h @@ -55,6 +55,8 @@ extern "C" { #define A_GROUPSID "groupsid" #define A_REPARSE_POINT "reparse" #define A_GEN "generation" +#define A_OFFLINE "offline" +#define A_SPARSE "sparse" /* Attribute option for utilities */ #define O_HIDDEN "H" @@ -68,6 +70,8 @@ extern "C" { #define O_AV_QUARANTINED "q" #define O_AV_MODIFIED "m" #define O_REPARSE_POINT "r" +#define O_OFFLINE "O" +#define O_SPARSE "s" #define O_NONE "" /* ownersid and groupsid are composed of two nvpairs */ @@ -94,6 +98,8 @@ typedef enum { F_FSID, F_REPARSE, F_GEN, + F_OFFLINE, + F_SPARSE, F_ATTR_ALL } f_attr_t; diff --git a/usr/src/uts/common/sys/vnode.h b/usr/src/uts/common/sys/vnode.h index 1216983e2d..d29152346e 100644 --- a/usr/src/uts/common/sys/vnode.h +++ b/usr/src/uts/common/sys/vnode.h @@ -399,6 +399,8 @@ typedef struct xoptattr { uint8_t xoa_av_scanstamp[AV_SCANSTAMP_SZ]; uint8_t xoa_reparse; uint64_t xoa_generation; + uint8_t xoa_offline; + uint8_t xoa_sparse; } xoptattr_t; /* @@ -579,11 +581,13 @@ typedef vattr_t vattr32_t; #define XAT0_AV_SCANSTAMP 0x00001000 /* anti-virus scanstamp */ #define XAT0_REPARSE 0x00002000 /* FS reparse point */ #define XAT0_GEN 0x00004000 /* object generation number */ +#define XAT0_OFFLINE 0x00008000 /* offline */ +#define XAT0_SPARSE 0x00010000 /* sparse */ #define XAT0_ALL_ATTRS (XAT0_CREATETIME|XAT0_ARCHIVE|XAT0_SYSTEM| \ XAT0_READONLY|XAT0_HIDDEN|XAT0_NOUNLINK|XAT0_IMMUTABLE|XAT0_APPENDONLY| \ - XAT0_NODUMP|XAT0_OPAQUE|XAT0_AV_QUARANTINED| \ - XAT0_AV_MODIFIED|XAT0_AV_SCANSTAMP|XAT0_REPARSE|XAT0_GEN) + XAT0_NODUMP|XAT0_OPAQUE|XAT0_AV_QUARANTINED| XAT0_AV_MODIFIED| \ + XAT0_AV_SCANSTAMP|XAT0_REPARSE|XATO_GEN|XAT0_OFFLINE|XAT0_SPARSE) /* Support for XAT_* optional attributes */ #define XVA_MASK 0xffffffff /* Used to mask off 32 bits */ @@ -618,6 +622,8 @@ typedef vattr_t vattr32_t; #define XAT_AV_SCANSTAMP ((XAT0_INDEX << XVA_SHFT) | XAT0_AV_SCANSTAMP) #define XAT_REPARSE ((XAT0_INDEX << XVA_SHFT) | XAT0_REPARSE) #define XAT_GEN ((XAT0_INDEX << XVA_SHFT) | XAT0_GEN) +#define XAT_OFFLINE ((XAT0_INDEX << XVA_SHFT) | XAT0_OFFLINE) +#define XAT_SPARSE ((XAT0_INDEX << XVA_SHFT) | XAT0_SPARSE) /* * The returned attribute map array (xva_rtnattrmap[]) is located past the |