[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