[PATCH] vfs_fruit: resource fork length
Ralph Böhme
rb at sernet.de
Tue Sep 16 02:34:05 MDT 2014
Hi
attached please find an update for the vfs_fruit torture test and
fixes for two issue:
* the resource fork size that gets written to ther AppleDouble header
is calculated wrong when the resource is extended with pwrite()
* the resource fork size is not updated upon ftruncate()
This patch series depends the other patch submitted recently.
Review and commit (if ok) appreciated.
Thanks!
-Ralph
--
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de,mailto:kontakt@sernet.de
-------------- next part --------------
>From 6b6ee545047c6bba6978db9c134c86ae9f1ea4ed Mon Sep 17 00:00:00 2001
From: Ralph Boehme <rb at sernet.de>
Date: Mon, 15 Sep 2014 16:38:09 +0200
Subject: [PATCH 1/4] s4:torture:vfs_fruit: add size checks for resource fork
IO
Signed-off-by: Ralph Boehme <rb at sernet.de>
---
source4/torture/vfs/fruit.c | 91 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 90 insertions(+), 1 deletion(-)
diff --git a/source4/torture/vfs/fruit.c b/source4/torture/vfs/fruit.c
index ad05b9f..39f41a2 100644
--- a/source4/torture/vfs/fruit.c
+++ b/source4/torture/vfs/fruit.c
@@ -579,11 +579,17 @@ static bool test_write_atalk_rfork_io(struct torture_context *tctx,
{
TALLOC_CTX *mem_ctx = talloc_new(tctx);
const char *fname = BASEDIR "\\torture_write_rfork_io";
+ const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM;
const char *rfork_content = "1234567890";
NTSTATUS status;
struct smb2_handle testdirh;
bool ret = true;
+ union smb_open io;
+ struct smb2_handle filehandle;
+ union smb_fileinfo finfo;
+ union smb_setfileinfo sinfo;
+
smb2_util_unlink(tree1, fname);
status = torture_smb2_testdir(tree1, BASEDIR, &testdirh);
@@ -606,9 +612,41 @@ static bool test_write_atalk_rfork_io(struct torture_context *tctx,
fname, AFPRESOURCE_STREAM,
0, 20, 10, 10, rfork_content);
- torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
+ /* Check size after write */
+
+ ZERO_STRUCT(io);
+ io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
+ io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
+ SEC_FILE_WRITE_ATTRIBUTE |
+ SEC_RIGHTS_FILE_ALL;
+ io.smb2.in.fname = rfork;
+ status = smb2_create(tree1, mem_ctx, &(io.smb2));
+ CHECK_STATUS(status, NT_STATUS_OK);
+ filehandle = io.smb2.out.file.handle;
+
+ torture_comment(tctx, "(%s) check resource fork size after write\n",
__location__);
+ ZERO_STRUCT(finfo);
+ finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
+ finfo.generic.in.file.handle = filehandle;
+ status = smb2_getinfo_file(tree1, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (finfo.all_info.out.size != 20) {
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s) Incorrect resource fork size\n",
+ __location__);
+ ret = false;
+ smb2_util_close(tree1, filehandle);
+ goto done;
+ }
+ smb2_util_close(tree1, filehandle);
+
+ /* Write at large offset */
+
+ torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
+ __location__);
+
ret &= write_stream(tree1, __location__, tctx, mem_ctx,
fname, AFPRESOURCE_STREAM,
(off_t)1<<32, 10, rfork_content);
@@ -617,6 +655,57 @@ static bool test_write_atalk_rfork_io(struct torture_context *tctx,
fname, AFPRESOURCE_STREAM,
(off_t)1<<32, 10, 0, 10, rfork_content);
+ /* Truncate back to size of 1 byte */
+
+ torture_comment(tctx, "(%s) truncate resource fork and check size\n",
+ __location__);
+
+ ZERO_STRUCT(io);
+ io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
+ io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
+ SEC_FILE_WRITE_ATTRIBUTE |
+ SEC_RIGHTS_FILE_ALL;
+ io.smb2.in.fname = rfork;
+ status = smb2_create(tree1, mem_ctx, &(io.smb2));
+ CHECK_STATUS(status, NT_STATUS_OK);
+ filehandle = io.smb2.out.file.handle;
+
+ ZERO_STRUCT(sinfo);
+ sinfo.end_of_file_info.level =
+ RAW_SFILEINFO_END_OF_FILE_INFORMATION;
+ sinfo.end_of_file_info.in.file.handle = filehandle;
+ sinfo.end_of_file_info.in.size = 1;
+ status = smb2_setinfo_file(tree1, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ smb2_util_close(tree1, filehandle);
+
+ /* Now check size */
+ ZERO_STRUCT(io);
+ io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
+ io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
+ SEC_FILE_WRITE_ATTRIBUTE |
+ SEC_RIGHTS_FILE_ALL;
+ io.smb2.in.fname = rfork;
+ status = smb2_create(tree1, mem_ctx, &(io.smb2));
+ CHECK_STATUS(status, NT_STATUS_OK);
+ filehandle = io.smb2.out.file.handle;
+
+ ZERO_STRUCT(finfo);
+ finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
+ finfo.generic.in.file.handle = filehandle;
+ status = smb2_getinfo_file(tree1, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (finfo.all_info.out.size != 1) {
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s) Incorrect resource fork size\n",
+ __location__);
+ ret = false;
+ smb2_util_close(tree1, filehandle);
+ goto done;
+ }
+ smb2_util_close(tree1, filehandle);
+
done:
smb2_deltree(tree1, BASEDIR);
talloc_free(mem_ctx);
--
1.9.3
>From 9a79a8b7aef8bae83565b3081099b2c855ac73e5 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <rb at sernet.de>
Date: Mon, 15 Sep 2014 13:51:41 +0200
Subject: [PATCH 2/4] vfs_fruit: fix resource fork length calculation
Don't add the AppleDouble header size to the resource fork size.
Signed-off-by: Ralph Boehme <rb at sernet.de>
---
source3/modules/vfs_fruit.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 1226dc0..89578fb 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -2309,7 +2309,7 @@ static ssize_t fruit_pwrite(vfs_handle_struct *handle,
handle, fsp);
struct fruit_config_data *config = NULL;
AfpInfo *ai = NULL;
- ssize_t len, new_rfork_size;
+ ssize_t len;
char *name = NULL;
char *tmp_base_name = NULL;
NTSTATUS status;
@@ -2375,16 +2375,12 @@ static ssize_t fruit_pwrite(vfs_handle_struct *handle,
if (config->rsrc == FRUIT_RSRC_ADFILE) {
rc = ad_read(ad, name);
if (rc == -1) {
- rc = -1;
goto exit;
}
rc = 0;
- new_rfork_size = len + offset
- + ad_getentryoff(ad, ADEID_RFORK);
- if (new_rfork_size > ad_getentrylen(ad, ADEID_RFORK)) {
- ad_setentrylen(ad, ADEID_RFORK,
- new_rfork_size);
+ if ((len + offset) > ad_getentrylen(ad, ADEID_RFORK)) {
+ ad_setentrylen(ad, ADEID_RFORK, len + offset);
rc = ad_write(ad, name);
}
}
--
1.9.3
>From 7df078a54d76acbac77c0c49da7153d3670d2744 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <rb at sernet.de>
Date: Mon, 15 Sep 2014 13:49:48 +0200
Subject: [PATCH 3/4] vfs_fruit: ad_write: path may be NULL for rfork
In preperation of the next commit where we want to call ad_write() on
a resource fork without having a name, just an fsp, which is fine for
resource forks.
Signed-off-by: Ralph Boehme <rb at sernet.de>
---
source3/modules/vfs_fruit.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 89578fb..9ccc66e 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -1112,7 +1112,9 @@ exit:
* Set AppleDouble metadata on a file or directory
*
* @param[in] ad adouble handle
- * @param[in] path pathname to file or directory
+
+ * @param[in] path pathname to file or directory, may be NULL for a
+ * resource fork
*
* @return status code, 0 means success
**/
@@ -1143,7 +1145,8 @@ static int ad_write(struct adouble *ad, const char *path)
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", path, len));
+ DEBUG(1, ("short write on %s: %zd",
+ fsp_str_dbg(ad->ad_fsp), len));
rc = -1;
goto exit;
}
--
1.9.3
>From c974be0ee649c700ccee853b64fc317c495ac9e5 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <rb at sernet.de>
Date: Mon, 15 Sep 2014 13:53:22 +0200
Subject: [PATCH 4/4] vfs_fruit: update rfork size in AppleDouble header
Update the AppleDouble entry with the new size when ftruncating a
resource fork.
Signed-off-by: Ralph Boehme <rb at sernet.de>
---
source3/modules/vfs_fruit.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 9ccc66e..3e131e7 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -2822,6 +2822,14 @@ static int fruit_ftruncate(struct vfs_handle_struct *handle,
rc = SMB_VFS_NEXT_FTRUNCATE(
handle, fsp,
offset + ad_getentryoff(ad, ADEID_RFORK));
+ if (rc != 0) {
+ return -1;
+ }
+ ad_setentrylen(ad, ADEID_RFORK, offset);
+ rc = ad_write(ad, NULL);
+ if (rc != 0) {
+ return -1;
+ }
}
break;
default:
--
1.9.3
More information about the samba-technical
mailing list