[Pkg-owncloud-commits] [owncloud-client] 133/484: csync_vio: reuse the information from readdir in stat

Sandro Knauß hefee-guest at moszumanska.debian.org
Wed Dec 16 00:37:29 UTC 2015


This is an automated email from the git hooks/post-receive script.

hefee-guest pushed a commit to branch master
in repository owncloud-client.

commit f18b40f7e7890a659d20f1d3bbd3125a3089b612
Author: Olivier Goffart <ogoffart at woboq.com>
Date:   Thu Oct 22 02:29:27 2015 +0200

    csync_vio: reuse the information from readdir in stat
    
    On unix we don't safe much (otherwise csync would have been
    designed differently).
    On windows however, the readdir already fetch all the info, so we
    can as well use it.
    
    We still have to query for the file id but we might optimize that later
---
 csync/src/csync.h                            |   3 +-
 csync/src/csync_update.c                     |  14 +--
 csync/src/vio/csync_vio_local_unix.c         |  10 --
 csync/src/vio/csync_vio_local_win.c          | 152 +++++++++++----------------
 csync/tests/csync_tests/check_csync_update.c |   1 -
 csync/tests/vio_tests/check_vio.c            |  43 --------
 6 files changed, 68 insertions(+), 155 deletions(-)

diff --git a/csync/src/csync.h b/csync/src/csync.h
index c2e1afa..626c3ee 100644
--- a/csync/src/csync.h
+++ b/csync/src/csync.h
@@ -173,7 +173,7 @@ enum csync_vio_file_stat_fields_e {
   CSYNC_VIO_FILE_STAT_FIELDS_TYPE = 1 << 0,
   CSYNC_VIO_FILE_STAT_FIELDS_MODE = 1 << 1, // local POSIX mode
   CSYNC_VIO_FILE_STAT_FIELDS_FLAGS = 1 << 2,
-  CSYNC_VIO_FILE_STAT_FIELDS_DEVICE = 1 << 3,
+//  CSYNC_VIO_FILE_STAT_FIELDS_DEVICE = 1 << 3,
   CSYNC_VIO_FILE_STAT_FIELDS_INODE = 1 << 4,
 //  CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT = 1 << 5,
   CSYNC_VIO_FILE_STAT_FIELDS_SIZE = 1 << 6,
@@ -212,7 +212,6 @@ struct csync_vio_file_stat_s {
 
   mode_t mode;
 
-  dev_t device;
   uint64_t inode;
 
   int fields; // actually enum csync_vio_file_stat_fields_e fields;
diff --git a/csync/src/csync_update.c b/csync/src/csync_update.c
index 4eb0457..779f83b 100644
--- a/csync/src/csync_update.c
+++ b/csync/src/csync_update.c
@@ -580,7 +580,6 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
   char *d_name = NULL;
   csync_vio_handle_t *dh = NULL;
   csync_vio_file_stat_t *dirent = NULL;
-  csync_vio_file_stat_t *fs = NULL;
   csync_file_stat_t *previous_fs = NULL;
   int read_from_db = 0;
   int rc = 0;
@@ -737,15 +736,13 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
 
     /* Only for the local replica we have to stat(), for the remote one we have all data already */
     if (ctx->replica == LOCAL_REPLICA) {
-        fs = csync_vio_file_stat_new();
-        res = csync_vio_stat(ctx, filename, fs);
+        res = csync_vio_stat(ctx, filename, dirent);
     } else {
-        fs = dirent;
         res = 0;
     }
 
     if( res == 0) {
-      switch (fs->type) {
+      switch (dirent->type) {
         case CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK:
           flag = CSYNC_FTW_FLAG_SLINK;
           break;
@@ -771,14 +768,9 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
     previous_fs = ctx->current_fs;
 
     /* Call walker function for each file */
-    rc = fn(ctx, filename, fs, flag);
+    rc = fn(ctx, filename, dirent, flag);
     /* this function may update ctx->current and ctx->read_from_db */
 
-    /* Only for the local replica we have to destroy stat(), for the remote one it is a pointer to dirent */
-    if (ctx->replica == LOCAL_REPLICA) {
-        csync_vio_file_stat_destroy(fs);
-    }
-
     if (rc < 0) {
       if (CSYNC_STATUS_IS_OK(ctx->status_code)) {
           ctx->status_code = CSYNC_STATUS_UPDATE_ERROR;
diff --git a/csync/src/vio/csync_vio_local_unix.c b/csync/src/vio/csync_vio_local_unix.c
index e72eb4f..667c72e 100644
--- a/csync/src/vio/csync_vio_local_unix.c
+++ b/csync/src/vio/csync_vio_local_unix.c
@@ -157,13 +157,6 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
     return -1;
   }
 
-  buf->name = c_basename(uri);
-
-  if (buf->name == NULL) {
-    csync_vio_file_stat_destroy(buf);
-    c_free_locale_string(wuri);
-    return -1;
-  }
   buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
 
   switch(sb.st_mode & S_IFMT) {
@@ -210,9 +203,6 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
 #endif
   buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
 
-  buf->device = sb.st_dev;
-  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DEVICE;
-
   buf->inode = sb.st_ino;
   buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
 
diff --git a/csync/src/vio/csync_vio_local_win.c b/csync/src/vio/csync_vio_local_win.c
index 9229827..80e1228 100644
--- a/csync/src/vio/csync_vio_local_win.c
+++ b/csync/src/vio/csync_vio_local_win.c
@@ -116,10 +116,31 @@ int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
   return rc;
 }
 
+
+static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder)
+{
+    long long int t = filetime->dwHighDateTime;
+    t <<= 32;
+    t += (UINT32)filetime->dwLowDateTime;
+    t -= 116444736000000000LL;
+    if (t < 0)
+    {
+        if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
+        return -1 - ((-t - 1) / 10000000);
+    }
+    else
+    {
+        if (remainder) *remainder = t % 10000000;
+        return t / 10000000;
+    }
+}
+
 csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
 
   dhandle_t *handle = NULL;
   csync_vio_file_stat_t *file_stat = NULL;
+  ULARGE_INTEGER FileIndex;
+  DWORD rem;
 
   handle = (dhandle_t *) dhandle;
 
@@ -148,13 +169,43 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
   file_stat->name = c_utf8_from_locale(handle->ffd.cFileName);
 
   file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
-  if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
-      file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
-  } else {
-      file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
-  }
+  if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT
+            && handle->ffd.dwReserved0 & IO_REPARSE_TAG_SYMLINK) {
+        file_stat->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK;
+        file_stat->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
+    } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
+                || handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
+                || handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
+        file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
+    } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
+    } else {
+        file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
+    }
+
+    file_stat->flags = CSYNC_VIO_FILE_FLAGS_NONE;
+    /* Check for the hidden flag */
+    if( handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) {
+        file_stat->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
+    }
+
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
 
-  return file_stat;
+    file_stat->size = (handle->ffd.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + handle->ffd.nFileSizeLow;
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
+
+    file_stat->atime = FileTimeToUnixTime(&handle->ffd.ftLastAccessTime, &rem);
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
+
+    file_stat->mtime = FileTimeToUnixTime(&handle->ffd.ftLastWriteTime, &rem);
+      /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
+
+    file_stat->ctime = FileTimeToUnixTime(&handle->ffd.ftCreationTime, &rem);
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
+
+    return file_stat;
 
 err:
   SAFE_FREE(file_stat);
@@ -162,29 +213,16 @@ err:
   return NULL;
 }
 
-static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder)
-{
-   long long int t = filetime->dwHighDateTime;
-   t <<= 32;
-   t += (UINT32)filetime->dwLowDateTime;
-   t -= 116444736000000000LL;
-   if (t < 0)
-   {
-    if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
-	return -1 - ((-t - 1) / 10000000);
-    }
-    else
-    {
-	if (remainder) *remainder = t % 10000000;
-	return t / 10000000;
-    }
-}
+
 
 int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
-    HANDLE h, hFind;
-    FILETIME ftCreate, ftAccess, ftWrite;
+    /* Almost nothing to do since csync_vio_local_readdir already filled up most of the information
+       But we still need to fetch the file ID.
+       Possible optimisation: only fetch the file id when we need it (for new files)
+      */
+
+    HANDLE h;
     BY_HANDLE_FILE_INFORMATION fileInfo;
-    WIN32_FIND_DATAW FindFileData;
     ULARGE_INTEGER FileIndex;
     mbchar_t *wuri = c_utf8_path_to_locale( uri );
 
@@ -205,47 +243,6 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
         return -1;
     }
 
-    buf->flags = CSYNC_VIO_FILE_FLAGS_NONE;
-    do {
-        // Check first if it is a symlink (code from c_islink)
-        if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
-            hFind = FindFirstFileW(wuri, &FindFileData );
-            if (hFind !=  INVALID_HANDLE_VALUE) {
-                if( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
-                        (FindFileData.dwReserved0 & IO_REPARSE_TAG_SYMLINK) ) {
-                    buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK;
-                    buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
-                    break;
-                }
-            }
-            FindClose(hFind);
-        }
-        if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
-                || fileInfo.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
-                || fileInfo.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
-            buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
-            break;
-        }
-        if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
-            buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
-            break;
-        }
-        // fallthrough:
-        buf->type = CSYNC_VIO_FILE_TYPE_REGULAR;
-        break;
-    } while (0);
-
-    /* Check for the hidden flag */
-    if( fileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) {
-        buf->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
-    }
-
-    buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
-    buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
-
-    buf->device = fileInfo.dwVolumeSerialNumber;
-    buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DEVICE;
-
     /* Get the Windows file id as an inode replacement. */
     FileIndex.HighPart = fileInfo.nFileIndexHigh;
     FileIndex.LowPart = fileInfo.nFileIndexLow;
@@ -253,28 +250,7 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
     /* printf("Index: %I64i\n", FileIndex.QuadPart); */
     buf->inode = FileIndex.QuadPart;
 
-    buf->size = (fileInfo.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + fileInfo.nFileSizeLow;
-    buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
-
-    /* Get the file time with a win32 call rather than through stat. See
-      * http://www.codeproject.com/Articles/1144/Beating-the-Daylight-Savings-Time-bug-and-getting
-      * for deeper explanation.
-      */
-    if( GetFileTime(h, &ftCreate, &ftAccess, &ftWrite) ) {
-        DWORD rem;
-        buf->atime = FileTimeToUnixTime(&ftAccess, &rem);
-        buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
-
-        buf->mtime = FileTimeToUnixTime(&ftWrite, &rem);
-        /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
-        buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
-
-        buf->ctime = FileTimeToUnixTime(&ftCreate, &rem);
-        buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
-    }
-
     c_free_locale_string(wuri);
     CloseHandle(h);
-
     return 0;
 }
diff --git a/csync/tests/csync_tests/check_csync_update.c b/csync/tests/csync_tests/check_csync_update.c
index 0213440..ced053e 100644
--- a/csync/tests/csync_tests/check_csync_update.c
+++ b/csync/tests/csync_tests/check_csync_update.c
@@ -201,7 +201,6 @@ static csync_vio_file_stat_t* create_fstat(const char *name,
     }
     fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
 
-    fs->device = 0;
 
     fs->size = 157459;
     fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
diff --git a/csync/tests/vio_tests/check_vio.c b/csync/tests/vio_tests/check_vio.c
index bf5e599..c8bc641 100644
--- a/csync/tests/vio_tests/check_vio.c
+++ b/csync/tests/vio_tests/check_vio.c
@@ -164,46 +164,6 @@ static void check_csync_vio_readdir(void **state)
 }
 
 
-/*
- * Test for general functions (stat, chmod, chown, ...)
- */
-
-static void check_csync_vio_stat_dir(void **state)
-{
-    CSYNC *csync = *state;
-    csync_vio_file_stat_t *fs;
-    int rc;
-
-    fs = csync_vio_file_stat_new();
-    assert_non_null(fs);
-
-    rc = csync_vio_stat(csync, CSYNC_TEST_DIR, fs);
-    assert_int_equal(rc, 0);
-
-    assert_string_equal(fs->name, "csync_test");
-    assert_int_equal(fs->type, CSYNC_VIO_FILE_TYPE_DIRECTORY);
-
-    csync_vio_file_stat_destroy(fs);
-}
-
-static void check_csync_vio_stat_file(void **state)
-{
-    CSYNC *csync = *state;
-    csync_vio_file_stat_t *fs;
-    int rc;
-
-    fs = csync_vio_file_stat_new();
-    assert_non_null(fs);
-
-    rc = csync_vio_stat(csync, CSYNC_TEST_FILE, fs);
-    assert_int_equal(rc, 0);
-
-    assert_string_equal(fs->name, "file.txt");
-    assert_int_equal(fs->type, CSYNC_VIO_FILE_TYPE_REGULAR);
-
-    csync_vio_file_stat_destroy(fs);
-}
-
 int torture_run_tests(void)
 {
     const UnitTest tests[] = {
@@ -211,9 +171,6 @@ int torture_run_tests(void)
         unit_test_setup_teardown(check_csync_vio_opendir_perm, setup, teardown),
         unit_test(check_csync_vio_closedir_null),
         unit_test_setup_teardown(check_csync_vio_readdir, setup_dir, teardown),
-
-        unit_test_setup_teardown(check_csync_vio_stat_dir, setup_dir, teardown),
-        unit_test_setup_teardown(check_csync_vio_stat_file, setup_file, teardown),
     };
 
     return run_tests(tests);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git



More information about the Pkg-owncloud-commits mailing list