diff options
author | Ralph Boehme <slow@samba.org> | 2016-12-08 19:12:32 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2017-03-06 19:40:21 +0100 |
commit | a55528b981985d0ee6f336bf2dce0a6c6daf84ff (patch) | |
tree | c3290d873a71daea059357c94ad1d280a996ab9d | |
parent | db79f8940fab6dd83ec44f7f237f537af3cdffff (diff) | |
download | samba-a55528b981985d0ee6f336bf2dce0a6c6daf84ff.tar.gz |
vfs_fruit: rework struct adouble API
o factor out ad_open(), opens an fd to be used with IO on the metadata
streams
o rename ad_write() to ad_set() as this aligns nicely with the existing
ad_get. This is the pathname based version used to solely set metadata
on a file, there's also a handle based version:
o add ad_fset(), a handle based version that can be used to set metadata
and to update the AppleDouble header in a ._ AppleDouble file
o remove fruit_fsp_recheck(), looking at it more closely, it is not
needed
This commit *compiles*, but all callers in the VFS ops must now be
updated to use the new semantics, this comes next...
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12427
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Uri Simchoni <uri@samba.org>
(cherry picked from commit 1d1203574328570288806fffefabb550ecc4e95d)
-rw-r--r-- | source3/modules/vfs_fruit.c | 713 |
1 files changed, 423 insertions, 290 deletions
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index 8a448fa02f8..6bdde6e6934 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -349,7 +349,8 @@ struct ad_entry { struct adouble { vfs_handle_struct *ad_handle; - files_struct *ad_fsp; + int ad_fd; + bool ad_opened; adouble_type_t ad_type; uint32_t ad_magic; uint32_t ad_version; @@ -402,12 +403,21 @@ static const uint32_t set_eid[] = { AD_DEV, AD_INO, AD_SYN, AD_ID }; +struct fio { + /* tcon config handle */ + struct fruit_config_data *config; + + /* Denote stream type, meta or rsrc */ + adouble_type_t type; +}; + /* * Forward declarations */ static struct adouble *ad_init(TALLOC_CTX *ctx, vfs_handle_struct *handle, - adouble_type_t type, files_struct *fsp); -static int ad_write(struct adouble *ad, const char *path); + adouble_type_t type); +static int ad_set(struct adouble *ad, const char *path); +static int ad_fset(struct adouble *ad, files_struct *fsp); static int adouble_path(TALLOC_CTX *ctx, const char *path_in, char **path_out); /** @@ -769,7 +779,7 @@ exit: /** * Read and parse Netatalk AppleDouble metadata xattr **/ -static ssize_t ad_header_read_meta(struct adouble *ad, const char *path) +static ssize_t ad_read_meta(struct adouble *ad, const char *path) { int rc = 0; ssize_t ealen; @@ -841,196 +851,220 @@ exit: return ealen; } -/** - * Read and parse resource fork, either ._ AppleDouble file or xattr - **/ -static ssize_t ad_header_read_rsrc(struct adouble *ad, const char *path) +static int ad_open_meta(const char *path, int flags, mode_t mode) +{ + return open(path, flags, mode); +} + +static int ad_open_rsrc_xattr(const char *path, int flags, mode_t mode) +{ +#ifdef HAVE_ATTROPEN + /* FIXME: direct Solaris xattr syscall */ + return attropen(path, AFPRESOURCE_EA_NETATALK, flags, mode); +#else + errno = ENOSYS; + return -1; +#endif +} + +static int ad_open_rsrc_adouble(const char *path, int flags, mode_t mode) +{ + char *adp = NULL; + int ret; + int fd; + + ret = adouble_path(talloc_tos(), path, &adp); + if (ret != 0) { + return -1; + } + + fd = open(adp, flags, mode); + TALLOC_FREE(adp); + + return fd; +} + +static int ad_open_rsrc(vfs_handle_struct *handle, + const char *path, + int flags, + mode_t mode) { struct fruit_config_data *config = NULL; - int fd = -1; - int rc = 0; - ssize_t len; - char *adpath = NULL; - bool opened = false; - int mode; - struct adouble *meta_ad = NULL; - SMB_STRUCT_STAT sbuf; - bool ok; - int saved_errno = 0; + int fd; - SMB_VFS_HANDLE_GET_DATA(ad->ad_handle, config, + SMB_VFS_HANDLE_GET_DATA(handle, config, struct fruit_config_data, return -1); - /* Try rw first so we can use the fd in ad_convert() */ - mode = O_RDWR; - - if (ad->ad_fsp && ad->ad_fsp->fh && (ad->ad_fsp->fh->fd != -1)) { - fd = ad->ad_fsp->fh->fd; + if (config->rsrc == FRUIT_RSRC_XATTR) { + fd = ad_open_rsrc_xattr(path, flags, mode); } else { - if (config->rsrc == FRUIT_RSRC_XATTR) { - adpath = talloc_strdup(talloc_tos(), path); - } else { - rc = adouble_path(talloc_tos(), path, &adpath); - if (rc != 0) { - goto exit; - } - } + fd = ad_open_rsrc_adouble(path, flags, mode); + } - retry: - if (config->rsrc == FRUIT_RSRC_XATTR) { -#ifndef HAVE_ATTROPEN - errno = ENOSYS; - rc = -1; - goto exit; -#else - /* FIXME: direct Solaris xattr syscall */ - fd = attropen(adpath, AFPRESOURCE_EA_NETATALK, - mode, 0); -#endif - } else { - /* FIXME: direct open(), don't have an fsp */ - fd = open(adpath, mode); - } + return fd; +} - if (fd == -1) { - switch (errno) { - case EROFS: - case EACCES: - if (mode == O_RDWR) { - mode = O_RDONLY; - goto retry; - } - /* fall through ... */ - default: - DEBUG(2, ("open AppleDouble: %s, %s\n", - adpath, strerror(errno))); - rc = -1; - goto exit; - } - } - opened = true; +static int ad_open(vfs_handle_struct *handle, + struct adouble *ad, + const char *path, + adouble_type_t t, + int flags, + mode_t mode) +{ + int fd; + + DBG_DEBUG("Path [%s] type [%s]\n", + path, t == ADOUBLE_META ? "meta" : "rsrc"); + + if (t == ADOUBLE_META) { + fd = ad_open_meta(path, flags, mode); + } else { + fd = ad_open_rsrc(handle, path, flags, mode); } - if (config->rsrc == FRUIT_RSRC_XATTR) { - /* FIXME: direct sys_fstat(), don't have an fsp */ - rc = sys_fstat( - fd, &sbuf, + if (fd != -1) { + ad->ad_opened = true; + ad->ad_fd = fd; + } + + DBG_DEBUG("Path [%s] type [%s] fd [%d]\n", + path, t == ADOUBLE_META ? "meta" : "rsrc", fd); + + return fd; +} + +static ssize_t ad_read_rsrc_xattr(struct adouble *ad, + const char *path) +{ + int ret; + SMB_STRUCT_STAT st; + + /* FIXME: direct sys_fstat(), don't have an fsp */ + ret = sys_fstat(ad->ad_fd, &st, lp_fake_directory_create_times( SNUM(ad->ad_handle->conn))); - if (rc != 0) { - goto exit; - } - len = sbuf.st_ex_size; - ad_setentrylen(ad, ADEID_RFORK, len); - } else { - /* FIXME: direct sys_pread(), don't have an fsp */ - len = sys_pread(fd, ad->ad_data, AD_DATASZ_DOT_UND, 0); - if (len != AD_DATASZ_DOT_UND) { - DEBUG(2, ("%s: bad size: %zd\n", - strerror(errno), len)); - rc = -1; - goto exit; - } + if (ret != 0) { + return -1; + } - /* FIXME: direct sys_fstat(), we don't have an fsp */ - rc = sys_fstat(fd, &sbuf, - lp_fake_directory_create_times( - SNUM(ad->ad_handle->conn))); - if (rc != 0) { - goto exit; - } + ad_setentrylen(ad, ADEID_RFORK, st.st_ex_size); + return st.st_ex_size; +} - /* Now parse entries */ - ok = ad_unpack(ad, ADEID_NUM_DOT_UND, sbuf.st_ex_size); - if (!ok) { - DEBUG(1, ("invalid AppleDouble resource %s\n", path)); - errno = EINVAL; - rc = -1; - goto exit; - } +static ssize_t ad_read_rsrc_adouble(struct adouble *ad, + const char *path) +{ + struct adouble *meta_ad = NULL; + SMB_STRUCT_STAT sbuf; + char *p_ad = NULL; + char *p_meta_ad = NULL; + ssize_t len; + int ret; + bool ok; - if ((ad_getentryoff(ad, ADEID_FINDERI) - != ADEDOFF_FINDERI_DOT_UND) - || (ad_getentrylen(ad, ADEID_FINDERI) - < ADEDLEN_FINDERI) - || (ad_getentryoff(ad, ADEID_RFORK) - < ADEDOFF_RFORK_DOT_UND)) { - DEBUG(2, ("invalid AppleDouble resource %s\n", path)); - errno = EINVAL; - rc = -1; - goto exit; - } + len = sys_pread(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0); + if (len != AD_DATASZ_DOT_UND) { + DBG_NOTICE("%s %s: bad size: %zd\n", + path, strerror(errno), len); + return -1; + } - if ((mode == O_RDWR) - && (ad_getentrylen(ad, ADEID_FINDERI) > ADEDLEN_FINDERI)) { - char *p_ad = NULL; - char *p_meta_ad = NULL; + ret = sys_fstat(ad->ad_fd, &sbuf, lp_fake_directory_create_times( + SNUM(ad->ad_handle->conn))); + if (ret != 0) { + return -1; + } - rc = ad_convert(ad, fd); - if (rc != 0) { - rc = -1; - goto exit; - } - /* - * Can't use ad_write() because we might not have a fsp - */ - ok = ad_pack(ad); - if (!ok) { - rc = -1; - goto exit; - } - /* FIXME: direct sys_pwrite(), don't have an fsp */ - len = sys_pwrite(fd, ad->ad_data, - AD_DATASZ_DOT_UND, 0); - if (len != AD_DATASZ_DOT_UND) { - DEBUG(2, ("%s: bad size: %zd\n", adpath, len)); - rc = -1; - goto exit; - } + /* Now parse entries */ + ok = ad_unpack(ad, ADEID_NUM_DOT_UND, sbuf.st_ex_size); + if (!ok) { + DBG_ERR("invalid AppleDouble resource %s\n", path); + errno = EINVAL; + return -1; + } - meta_ad = ad_init(talloc_tos(), ad->ad_handle, - ADOUBLE_META, NULL); - if (meta_ad == NULL) { - rc = -1; - goto exit; - } + if ((ad_getentryoff(ad, ADEID_FINDERI) != ADEDOFF_FINDERI_DOT_UND) + || (ad_getentrylen(ad, ADEID_FINDERI) < ADEDLEN_FINDERI) + || (ad_getentryoff(ad, ADEID_RFORK) < ADEDOFF_RFORK_DOT_UND)) { + DBG_ERR("invalid AppleDouble resource %s\n", path); + errno = EINVAL; + return -1; + } - p_ad = ad_get_entry(ad, ADEID_FINDERI); - if (p_ad == NULL) { - rc = -1; - goto exit; - } - p_meta_ad = ad_get_entry(meta_ad, ADEID_FINDERI); - if (p_meta_ad == NULL) { - rc = -1; - goto exit; - } + if (ad_getentrylen(ad, ADEID_FINDERI) == ADEDLEN_FINDERI) { + return len; + } - memcpy(p_meta_ad, p_ad, ADEDLEN_FINDERI); + /* + * Try to fixup AppleDouble files created by OS X with xattrs + * appended to the ADEID_FINDERI entry. We simply remove the + * xattrs blob, this means any fancy xattr that was stored + * there is lost. + */ - rc = ad_write(meta_ad, path); - if (rc != 0) { - rc = -1; - goto exit; - } - } + ret = ad_convert(ad, ad->ad_fd); + if (ret != 0) { + DBG_WARNING("Failed to convert [%s]\n", path); + return len; } - DEBUG(10, ("opened AppleDouble: %s\n", path)); + ok = ad_pack(ad); + if (!ok) { + DBG_WARNING("ad_pack [%s] failed\n", path); + return -1; + } -exit: - if (rc != 0) { - saved_errno = errno; - len = -1; + len = sys_pwrite(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0); + if (len != AD_DATASZ_DOT_UND) { + DBG_ERR("%s: bad size: %zd\n", path, len); + return -1; } - if (opened && fd != -1) { - close(fd); + + meta_ad = ad_init(talloc_tos(), ad->ad_handle, ADOUBLE_META); + if (meta_ad == NULL) { + return -1; } - TALLOC_FREE(adpath); + + p_ad = ad_get_entry(ad, ADEID_FINDERI); + if (p_ad == NULL) { + TALLOC_FREE(meta_ad); + return -1; + } + p_meta_ad = ad_get_entry(meta_ad, ADEID_FINDERI); + if (p_meta_ad == NULL) { + TALLOC_FREE(meta_ad); + return -1; + } + + memcpy(p_meta_ad, p_ad, ADEDLEN_FINDERI); + + ret = ad_set(meta_ad, path); TALLOC_FREE(meta_ad); - if (rc != 0) { - errno = saved_errno; + if (ret != 0) { + return -1; } + + return len; +} + +/** + * Read and parse resource fork, either ._ AppleDouble file or xattr + **/ +static ssize_t ad_read_rsrc(struct adouble *ad, + const char *path) +{ + struct fruit_config_data *config = NULL; + ssize_t len; + + SMB_VFS_HANDLE_GET_DATA(ad->ad_handle, config, + struct fruit_config_data, return -1); + + if (config->rsrc == FRUIT_RSRC_XATTR) { + len = ad_read_rsrc_xattr(ad, path); + } else { + len = ad_read_rsrc_adouble(ad, path); + } + return len; } @@ -1041,14 +1075,23 @@ static ssize_t ad_read(struct adouble *ad, const char *path) { switch (ad->ad_type) { case ADOUBLE_META: - return ad_header_read_meta(ad, path); + return ad_read_meta(ad, path); case ADOUBLE_RSRC: - return ad_header_read_rsrc(ad, path); + return ad_read_rsrc(ad, path); default: return -1; } } +static int adouble_destructor(struct adouble *ad) +{ + if ((ad->ad_fd != -1) && ad->ad_opened) { + close(ad->ad_fd); + ad->ad_fd = -1; + } + return 0; +} + /** * Allocate a struct adouble without initialiing it * @@ -1058,14 +1101,11 @@ static ssize_t ad_read(struct adouble *ad, const char *path) * @param[in] ctx talloc context * @param[in] handle vfs handle * @param[in] type type of AppleDouble, ADOUBLE_META or ADOUBLE_RSRC - - * @param[in] fsp if not NULL (for stream IO), the adouble handle is - * added as an fsp extension * * @return adouble handle **/ static struct adouble *ad_alloc(TALLOC_CTX *ctx, vfs_handle_struct *handle, - adouble_type_t type, files_struct *fsp) + adouble_type_t type) { int rc = 0; size_t adsize = 0; @@ -1088,39 +1128,27 @@ static struct adouble *ad_alloc(TALLOC_CTX *ctx, vfs_handle_struct *handle, return NULL; } - if (!fsp) { - ad = talloc_zero(ctx, struct adouble); - if (ad == NULL) { - rc = -1; - goto exit; - } - if (adsize) { - ad->ad_data = talloc_zero_array(ad, char, adsize); - } - } else { - ad = (struct adouble *)VFS_ADD_FSP_EXTENSION(handle, fsp, - struct adouble, - NULL); - if (ad == NULL) { + ad = talloc_zero(ctx, struct adouble); + if (ad == NULL) { + rc = -1; + goto exit; + } + + if (adsize) { + ad->ad_data = talloc_zero_array(ad, char, adsize); + if (ad->ad_data == NULL) { rc = -1; goto exit; } - if (adsize) { - ad->ad_data = talloc_zero_array( - VFS_MEMCTX_FSP_EXTENSION(handle, fsp), - char, adsize); - } - ad->ad_fsp = fsp; } - if (adsize && ad->ad_data == NULL) { - rc = -1; - goto exit; - } ad->ad_handle = handle; ad->ad_type = type; ad->ad_magic = AD_MAGIC; ad->ad_version = AD_VERSION; + ad->ad_fd = -1; + + talloc_set_destructor(ad, adouble_destructor); exit: if (rc != 0) { @@ -1135,12 +1163,11 @@ exit: * @param[in] ctx talloc context * @param[in] handle vfs handle * @param[in] type type of AppleDouble, ADOUBLE_META or ADOUBLE_RSRC - * @param[in] fsp file handle, may be NULL for a type of e_ad_meta * * @return adouble handle, initialized **/ static struct adouble *ad_init(TALLOC_CTX *ctx, vfs_handle_struct *handle, - adouble_type_t type, files_struct *fsp) + adouble_type_t type) { int rc = 0; const struct ad_entry_order *eid; @@ -1166,7 +1193,7 @@ static struct adouble *ad_init(TALLOC_CTX *ctx, vfs_handle_struct *handle, return NULL; } - ad = ad_alloc(ctx, handle, type, fsp); + ad = ad_alloc(ctx, handle, type); if (ad == NULL) { return NULL; } @@ -1205,16 +1232,42 @@ static struct adouble *ad_get(TALLOC_CTX *ctx, vfs_handle_struct *handle, int rc = 0; ssize_t len; struct adouble *ad = NULL; + int fd; + int mode; DEBUG(10, ("ad_get(%s) called for %s\n", type == ADOUBLE_META ? "meta" : "rsrc", path)); - ad = ad_alloc(ctx, handle, type, NULL); + ad = ad_alloc(ctx, handle, type); if (ad == NULL) { rc = -1; goto exit; } + /* + * Here's the deal: for ADOUBLE_META we can do without an fd + * as we can issue path based xattr calls. For ADOUBLE_RSRC + * however we need a full-fledged fd for file IO on the ._ + * file. + */ + if (type == ADOUBLE_RSRC) { + /* Try rw first so we can use the fd in ad_convert() */ + mode = O_RDWR; + + fd = ad_open(handle, ad, path, ADOUBLE_RSRC, mode, 0); + if (fd == -1 && ((errno == EROFS) || (errno == EACCES))) { + mode = O_RDONLY; + fd = ad_open(handle, ad, path, ADOUBLE_RSRC, mode, 0); + } + + if (fd == -1) { + DBG_DEBUG("ad_open [%s] error [%s]\n", + path, strerror(errno)); + rc = -1; + goto exit; + } + } + len = ad_read(ad, path); if (len == -1) { DEBUG(10, ("error reading AppleDouble for %s\n", path)); @@ -1233,21 +1286,144 @@ exit: } /** + * Return AppleDouble data for a file + * + * @param[in] ctx talloc context + * @param[in] handle vfs handle + * @param[in] fsp fsp to use for IO + * @param[in] type type of AppleDouble, ADOUBLE_META or ADOUBLE_RSRC + * + * @return talloced struct adouble or NULL on error + **/ +static struct adouble *ad_fget(TALLOC_CTX *ctx, vfs_handle_struct *handle, + files_struct *fsp, adouble_type_t type) +{ + int rc = 0; + ssize_t len; + struct adouble *ad = NULL; + char *path = fsp->base_fsp->fsp_name->base_name; + + DBG_DEBUG("ad_get(%s) path [%s]\n", + type == ADOUBLE_META ? "meta" : "rsrc", + fsp_str_dbg(fsp)); + + ad = ad_alloc(ctx, handle, type); + if (ad == NULL) { + rc = -1; + goto exit; + } + + if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) { + ad->ad_fd = fsp->fh->fd; + } else { + /* + * Here's the deal: for ADOUBLE_META we can do without an fd + * as we can issue path based xattr calls. For ADOUBLE_RSRC + * however we need a full-fledged fd for file IO on the ._ + * file. + */ + int fd; + int mode; + + if (type == ADOUBLE_RSRC) { + /* Try rw first so we can use the fd in ad_convert() */ + mode = O_RDWR; + + fd = ad_open(handle, ad, path, ADOUBLE_RSRC, mode, 0); + if (fd == -1 && + ((errno == EROFS) || (errno == EACCES))) + { + mode = O_RDONLY; + fd = ad_open(handle, ad, path, ADOUBLE_RSRC, + mode, 0); + } + + if (fd == -1) { + DBG_DEBUG("error opening AppleDouble for %s\n", path); + rc = -1; + goto exit; + } + } + } + + len = ad_read(ad, path); + if (len == -1) { + DBG_DEBUG("error reading AppleDouble for %s\n", path); + rc = -1; + goto exit; + } + +exit: + DBG_DEBUG("ad_get(%s) path [%s] rc [%d]\n", + type == ADOUBLE_META ? "meta" : "rsrc", + fsp_str_dbg(fsp), rc); + + if (rc != 0) { + TALLOC_FREE(ad); + } + return ad; +} + +/** * Set AppleDouble metadata on a file or directory * * @param[in] ad adouble handle + * + * @param[in] path pathname to file or directory + * + * @return status code, 0 means success + **/ +static int ad_set(struct adouble *ad, const char *path) +{ + bool ok; + int ret; + + DBG_DEBUG("Path [%s]\n", path); + + if (ad->ad_type != ADOUBLE_META) { + DBG_ERR("ad_set on [%s] used with ADOUBLE_RSRC\n", path); + return -1; + } + + ok = ad_pack(ad); + if (!ok) { + return -1; + } - * @param[in] path pathname to file or directory, may be NULL for a - * resource fork + ret = SMB_VFS_SETXATTR(ad->ad_handle->conn, + path, + AFPINFO_EA_NETATALK, + ad->ad_data, + AD_DATASZ_XATTR, 0); + + DBG_DEBUG("Path [%s] ret [%d]\n", path, ret); + + return ret; +} + +/** + * Set AppleDouble metadata on a file or directory + * + * @param[in] ad adouble handle + * @param[in] fsp file handle * * @return status code, 0 means success **/ -static int ad_write(struct adouble *ad, const char *path) +static int ad_fset(struct adouble *ad, files_struct *fsp) { - int rc = 0; + int rc = -1; ssize_t len; bool ok; + DBG_DEBUG("Path [%s]\n", fsp_str_dbg(fsp)); + + if ((fsp == NULL) + || (fsp->fh == NULL) + || (fsp->fh->fd == -1)) + { + smb_panic("bad fsp"); + } + ok = ad_pack(ad); if (!ok) { return -1; @@ -1255,31 +1431,32 @@ static int ad_write(struct adouble *ad, const char *path) switch (ad->ad_type) { case ADOUBLE_META: - rc = SMB_VFS_SETXATTR(ad->ad_handle->conn, path, - AFPINFO_EA_NETATALK, ad->ad_data, - AD_DATASZ_XATTR, 0); + rc = SMB_VFS_NEXT_FSETXATTR(ad->ad_handle, + fsp, + AFPINFO_EA_NETATALK, + ad->ad_data, + AD_DATASZ_XATTR, 0); break; + case ADOUBLE_RSRC: - if ((ad->ad_fsp == NULL) - || (ad->ad_fsp->fh == NULL) - || (ad->ad_fsp->fh->fd == -1)) { - rc = -1; - goto exit; - } - /* FIXME: direct sys_pwrite(), don't have an fsp */ - len = sys_pwrite(ad->ad_fsp->fh->fd, ad->ad_data, - talloc_get_size(ad->ad_data), 0); - if (len != talloc_get_size(ad->ad_data)) { - DEBUG(1, ("short write on %s: %zd", - fsp_str_dbg(ad->ad_fsp), len)); - rc = -1; - goto exit; + len = SMB_VFS_NEXT_PWRITE(ad->ad_handle, + fsp, + ad->ad_data, + talloc_get_size(ad->ad_data), + 0); + if (len != (ssize_t)talloc_get_size(ad->ad_data)) { + DBG_ERR("short write on %s: %zd", fsp_str_dbg(fsp), len); + return -1; } + rc = 0; break; + default: return -1; } -exit: + + DBG_DEBUG("Path [%s] rc [%d]\n", fsp_str_dbg(fsp), rc); + return rc; } @@ -1537,19 +1714,6 @@ static SMB_INO_T fruit_inode(const SMB_STRUCT_STAT *sbuf, const char *sname) return result; } -/** - * Ensure ad_fsp is still valid - **/ -static bool fruit_fsp_recheck(struct adouble *ad, files_struct *fsp) -{ - if (ad->ad_fsp == fsp) { - return true; - } - ad->ad_fsp = fsp; - - return true; -} - static bool add_fruit_stream(TALLOC_CTX *mem_ctx, unsigned int *num_streams, struct stream_struct **streams, const char *name, off_t size, @@ -2577,29 +2741,22 @@ static int fruit_open_meta_netatalk(vfs_handle_struct *handle, * The attribute does not exist or needs to be truncated, * create an AppleDouble EA */ - ad = ad_init(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), - handle, ADOUBLE_META, fsp); + ad = ad_init(fsp, handle, ADOUBLE_META); if (ad == NULL) { rc = -1; goto exit; } - rc = ad_write(ad, smb_fname->base_name); + fsp->fh->fd = hostfd; + + rc = ad_fset(ad, fsp); + fsp->fh->fd = -1; if (rc != 0) { rc = -1; goto exit; } - } else { - ad = ad_alloc(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), - handle, ADOUBLE_META, fsp); - if (ad == NULL) { - rc = -1; - goto exit; - } - if (ad_read(ad, smb_fname->base_name) == -1) { - rc = -1; - goto exit; - } + + TALLOC_FREE(ad); } exit: @@ -2714,28 +2871,21 @@ static int fruit_open_rsrc_adouble(vfs_handle_struct *handle, fsp->fh->fd = hostfd; if (flags & (O_CREAT | O_TRUNC)) { - ad = ad_init(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), - handle, ADOUBLE_RSRC, fsp); + ad = ad_init(fsp, handle, ADOUBLE_RSRC); if (ad == NULL) { rc = -1; goto exit; } - rc = ad_write(ad, smb_fname->base_name); + + fsp->fh->fd = hostfd; + + rc = ad_fset(ad, fsp); + fsp->fh->fd = -1; if (rc != 0) { rc = -1; goto exit; } - } else { - ad = ad_alloc(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), - handle, ADOUBLE_RSRC, fsp); - if (ad == NULL) { - rc = -1; - goto exit; - } - if (ad_read(ad, smb_fname->base_name) == -1) { - rc = -1; - goto exit; - } + TALLOC_FREE(ad); } exit: @@ -3399,11 +3549,6 @@ static ssize_t fruit_pread(vfs_handle_struct *handle, goto exit; } - if (!fruit_fsp_recheck(ad, fsp)) { - rc = -1; - goto exit; - } - if (ad->ad_type == ADOUBLE_META) { char afpinfo_buf[AFP_INFO_SIZE]; char *p = NULL; @@ -3539,11 +3684,6 @@ static ssize_t fruit_pwrite(vfs_handle_struct *handle, goto exit; } - if (!fruit_fsp_recheck(ad, fsp)) { - rc = -1; - goto exit; - } - if (ad->ad_type == ADOUBLE_META) { char *p = NULL; @@ -3556,7 +3696,7 @@ static ssize_t fruit_pwrite(vfs_handle_struct *handle, } memcpy(p, &ai->afpi_FinderInfo[0], ADEDLEN_FINDERI); - rc = ad_write(ad, fsp->base_fsp->fsp_name->base_name); + rc = ad_fset(ad, fsp); } else { len = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset + ad_getentryoff(ad, ADEID_RFORK)); @@ -3574,7 +3714,7 @@ static ssize_t fruit_pwrite(vfs_handle_struct *handle, if ((len + offset) > ad_getentrylen(ad, ADEID_RFORK)) { ad_setentrylen(ad, ADEID_RFORK, len + offset); - rc = ad_write(ad, fsp->base_fsp->fsp_name->base_name); + rc = ad_fset(ad, fsp); } } } @@ -3934,11 +4074,6 @@ static int fruit_fstat(vfs_handle_struct *handle, files_struct *fsp, goto exit; } - if (!fruit_fsp_recheck(ad, fsp)) { - rc = -1; - goto exit; - } - switch (ad->ad_type) { case ADOUBLE_META: rc = fruit_fstat_meta(handle, fsp, sbuf); @@ -4250,7 +4385,7 @@ static int fruit_ntimes(vfs_handle_struct *handle, ad_setdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, convert_time_t_to_uint32_t(ft->create_time.tv_sec)); - rc = ad_write(ad, smb_fname->base_name); + rc = ad_set(ad, smb_fname->base_name); exit: @@ -4275,10 +4410,6 @@ static int fruit_fallocate(struct vfs_handle_struct *handle, return SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len); } - if (!fruit_fsp_recheck(ad, fsp)) { - return -1; - } - /* Let the pwrite code path handle it. */ errno = ENOSYS; return -1; @@ -4303,14 +4434,16 @@ static int fruit_ftruncate_rsrc_adouble(struct vfs_handle_struct *handle, off_t offset) { int rc; - struct adouble *ad = - (struct adouble *)VFS_FETCH_FSP_EXTENSION(handle, fsp); - off_t ad_off = ad_getentryoff(ad, ADEID_RFORK); + struct adouble *ad = NULL; + off_t ad_off; - if (!fruit_fsp_recheck(ad, fsp)) { + ad = ad_fget(talloc_tos(), handle, fsp, ADOUBLE_RSRC); + if (ad == NULL) { return -1; } + ad_off = ad_getentryoff(ad, ADEID_RFORK); + rc = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset + ad_off); if (rc != 0) { return -1; @@ -4318,7 +4451,7 @@ static int fruit_ftruncate_rsrc_adouble(struct vfs_handle_struct *handle, ad_setentrylen(ad, ADEID_RFORK, offset); - rc = ad_write(ad, NULL); + rc = ad_fset(ad, fsp); if (rc != 0) { DBG_ERR("ad_write [%s] failed [%s]\n", fsp_str_dbg(fsp), strerror(errno)); |