diff options
author | joyce mcintosh <Joyce.McIntosh@Sun.COM> | 2010-08-11 16:48:54 -0700 |
---|---|---|
committer | joyce mcintosh <Joyce.McIntosh@Sun.COM> | 2010-08-11 16:48:54 -0700 |
commit | fd9ee8b58485b20072eeef1310a88ff348d5e7fa (patch) | |
tree | 74e8f3fc5f5409cdc6be3dae5631f8d0c672260a /usr/src/uts/common/fs | |
parent | e2c5185af3c50d9510e5df68aa37abdc6c0d3aac (diff) | |
download | illumos-joyent-fd9ee8b58485b20072eeef1310a88ff348d5e7fa.tar.gz |
6972305 Preferred DC not selected after setting pdc via sharectl
6971047 smbd hang during FVT regression test
6711195 Sparc:Get error "Windows Explorer has stopped working" once click on Details fr Properties on Vista
PSARC/2009/464 Offline attribute
6972515 Offline attribute - PSARC 2009/464
PSARC/2010/037 Windows Sparse Attribute
6972519 Windows Sparse Attribute - PSARC 2010/037
6719444 [CLI] - idmap help's output is not consistent with man pages's
6975449 idmap test suite needs idmap_cache_get_data() from libidmap
6974351 OpenSSL still taking smbd down
--HG--
rename : usr/src/lib/libidmap/common/idmap_priv.h => usr/src/cmd/idmap/idmap/namemaps.h
Diffstat (limited to 'usr/src/uts/common/fs')
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_common_transact.c | 11 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_fsinfo.c | 6 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c | 198 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_tree.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_vops.c | 27 | ||||
-rw-r--r-- | usr/src/uts/common/fs/xattr.c | 26 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/sys/zfs_znode.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_log.c | 6 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_replay.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_vnops.c | 14 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_znode.c | 22 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zut/zut.c | 9 |
12 files changed, 308 insertions, 20 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); } |