[SCM] SAMBA-CTDB repository - branch v3-4-ctdb updated - 061dd90fc54daeaed758b47e3aa413a8362c9a08

Michael Adam obnox at samba.org
Tue Jun 23 13:59:16 GMT 2009


The branch, v3-4-ctdb has been updated
       via  061dd90fc54daeaed758b47e3aa413a8362c9a08 (commit)
      from  e780063d072342cc5c57a7adc6c8ea2cd8084775 (commit)

http://gitweb.samba.org/?p=obnox/samba-ctdb.git;a=shortlog;h=v3-4-ctdb


- Log -----------------------------------------------------------------
commit 061dd90fc54daeaed758b47e3aa413a8362c9a08
Author: Volker Lendecke <vl at samba.org>
Date:   Thu May 14 15:34:42 2009 +0200

    Introduce "struct stat_ex" as a replacement for SMB_STRUCT_STAT
    
    This patch introduces
    
    struct stat_ex {
            dev_t           st_ex_dev;
            ino_t           st_ex_ino;
            mode_t          st_ex_mode;
            nlink_t         st_ex_nlink;
            uid_t           st_ex_uid;
            gid_t           st_ex_gid;
            dev_t           st_ex_rdev;
            off_t           st_ex_size;
            struct timespec st_ex_atime;
            struct timespec st_ex_mtime;
            struct timespec st_ex_ctime;
            struct timespec st_ex_btime; /* birthtime */
            blksize_t       st_ex_blksize;
            blkcnt_t        st_ex_blocks;
    };
    typedef struct stat_ex SMB_STRUCT_STAT;
    
    It is really large because due to the friendly libc headers playing macro
    tricks with fields like st_ino, so I renamed them to st_ex_xxx.
    
    Why this change? To support birthtime, we already have quite a few #ifdef's at
    places where it does not really belong. With a stat struct that we control, we
    can consolidate the nanosecond timestamps and the birthtime deep in the VFS
    stat calls.
    
    At this moment it is triggered by a request to support the birthtime field for
    GPFS. GPFS does not extend the system level struct stat, but instead has a
    separate call that gets us the additional information beyond posix. Without
    being able to do that within the VFS stat calls, that support would have to be
    scattered around the main smbd code.
    
    It will very likely break all the onefs modules, but I think the changes will
    be reasonably easy to do.

-----------------------------------------------------------------------

Summary of changes:
 source3/client/client.c             |   42 ++++---
 source3/client/clitar.c             |    5 +-
 source3/include/includes.h          |   33 ++++-
 source3/include/proto.h             |   11 +--
 source3/include/smb_macros.h        |    6 +-
 source3/lib/debug.c                 |    2 +-
 source3/lib/system.c                |  225 ++++++++++++++++++++++++++++++--
 source3/lib/time.c                  |  245 -----------------------------------
 source3/lib/util.c                  |   10 +-
 source3/libsmb/clifile.c            |   32 +++---
 source3/libsmb/clirap.c             |    6 +-
 source3/libsmb/libsmb_stat.c        |   12 +-
 source3/modules/nfs4_acls.c         |   11 +-
 source3/modules/vfs_acl_tdb.c       |    4 +-
 source3/modules/vfs_acl_xattr.c     |    4 +-
 source3/modules/vfs_afsacl.c        |    6 +-
 source3/modules/vfs_commit.c        |    2 +-
 source3/modules/vfs_default.c       |   44 +++---
 source3/modules/vfs_fake_perms.c    |   20 ++--
 source3/modules/vfs_fileid.c        |    4 +-
 source3/modules/vfs_gpfs.c          |    4 +-
 source3/modules/vfs_hpuxacl.c       |    2 +-
 source3/modules/vfs_netatalk.c      |   12 +-
 source3/modules/vfs_recycle.c       |    8 +-
 source3/modules/vfs_shadow_copy2.c  |    2 +-
 source3/modules/vfs_streams_depot.c |   10 +-
 source3/modules/vfs_streams_xattr.c |   54 ++++----
 source3/modules/vfs_tsmsm.c         |   15 ++-
 source3/param/loadparm.c            |   64 +++++-----
 source3/passdb/pdb_smbpasswd.c      |    2 +-
 source3/printing/nt_printing.c      |    4 +-
 source3/printing/printfsp.c         |    2 +-
 source3/printing/printing.c         |    2 +-
 source3/registry/regfio.c           |    4 +-
 source3/smbd/close.c                |    2 +-
 source3/smbd/dir.c                  |   12 +-
 source3/smbd/dosmode.c              |   42 +++---
 source3/smbd/file_access.c          |   16 +-
 source3/smbd/fileio.c               |    2 +-
 source3/smbd/filename.c             |    2 +-
 source3/smbd/msdfs.c                |    2 +-
 source3/smbd/nttrans.c              |   28 ++--
 source3/smbd/open.c                 |   56 ++++----
 source3/smbd/posix_acls.c           |   52 ++++----
 source3/smbd/reply.c                |   70 ++++++-----
 source3/smbd/service.c              |    4 +-
 source3/smbd/trans2.c               |  104 ++++++++--------
 source3/smbd/vfs.c                  |   28 ++--
 source3/torture/cmd_vfs.c           |  180 ++++++++++++++------------
 source3/utils/net_conf.c            |    2 +-
 source3/utils/net_usershare.c       |   14 +-
 source3/utils/testparm.c            |    6 +-
 source3/web/cgi.c                   |    8 +-
 53 files changed, 771 insertions(+), 768 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/client/client.c b/source3/client/client.c
index b706591..71c3f44 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -3024,7 +3024,7 @@ static int cmd_getfacl(void)
 	}
 
 	d_printf("# file: %s\n", src);
-	d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_uid, (unsigned int)sbuf.st_gid);
+	d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_ex_uid, (unsigned int)sbuf.st_ex_gid);
 
 	if (num_file_acls == 0 && num_dir_acls == 0) {
 		d_printf("No acls found.\n");
@@ -3122,6 +3122,7 @@ static int cmd_stat(void)
 	fstring mode_str;
 	SMB_STRUCT_STAT sbuf;
 	struct tm *lt;
+	time_t tmp_time;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) {
 		d_printf("stat file\n");
@@ -3154,30 +3155,31 @@ static int cmd_stat(void)
 	/* Print out the stat values. */
 	d_printf("File: %s\n", src);
 	d_printf("Size: %-12.0f\tBlocks: %u\t%s\n",
-		(double)sbuf.st_size,
-		(unsigned int)sbuf.st_blocks,
-		filetype_to_str(sbuf.st_mode));
+		(double)sbuf.st_ex_size,
+		(unsigned int)sbuf.st_ex_blocks,
+		filetype_to_str(sbuf.st_ex_mode));
 
 #if defined(S_ISCHR) && defined(S_ISBLK)
-	if (S_ISCHR(sbuf.st_mode) || S_ISBLK(sbuf.st_mode)) {
+	if (S_ISCHR(sbuf.st_ex_mode) || S_ISBLK(sbuf.st_ex_mode)) {
 		d_printf("Inode: %.0f\tLinks: %u\tDevice type: %u,%u\n",
-			(double)sbuf.st_ino,
-			(unsigned int)sbuf.st_nlink,
-			unix_dev_major(sbuf.st_rdev),
-			unix_dev_minor(sbuf.st_rdev));
+			(double)sbuf.st_ex_ino,
+			(unsigned int)sbuf.st_ex_nlink,
+			unix_dev_major(sbuf.st_ex_rdev),
+			unix_dev_minor(sbuf.st_ex_rdev));
 	} else
 #endif
 		d_printf("Inode: %.0f\tLinks: %u\n",
-			(double)sbuf.st_ino,
-			(unsigned int)sbuf.st_nlink);
+			(double)sbuf.st_ex_ino,
+			(unsigned int)sbuf.st_ex_nlink);
 
 	d_printf("Access: (0%03o/%s)\tUid: %u\tGid: %u\n",
-		((int)sbuf.st_mode & 0777),
-		unix_mode_to_str(mode_str, sbuf.st_mode),
-		(unsigned int)sbuf.st_uid,
-		(unsigned int)sbuf.st_gid);
+		((int)sbuf.st_ex_mode & 0777),
+		unix_mode_to_str(mode_str, sbuf.st_ex_mode),
+		(unsigned int)sbuf.st_ex_uid,
+		(unsigned int)sbuf.st_ex_gid);
 
-	lt = localtime(&sbuf.st_atime);
+	tmp_time = convert_timespec_to_time_t(sbuf.st_ex_atime);
+	lt = localtime(&tmp_time);
 	if (lt) {
 		strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
 	} else {
@@ -3185,7 +3187,8 @@ static int cmd_stat(void)
 	}
 	d_printf("Access: %s\n", mode_str);
 
-	lt = localtime(&sbuf.st_mtime);
+	tmp_time = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+	lt = localtime(&tmp_time);
 	if (lt) {
 		strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
 	} else {
@@ -3193,7 +3196,8 @@ static int cmd_stat(void)
 	}
 	d_printf("Modify: %s\n", mode_str);
 
-	lt = localtime(&sbuf.st_ctime);
+	tmp_time = convert_timespec_to_time_t(sbuf.st_ex_ctime);
+	lt = localtime(&tmp_time);
 	if (lt) {
 		strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
 	} else {
@@ -3402,7 +3406,7 @@ static int cmd_newer(void)
 
 	ok = next_token_talloc(ctx, &cmd_ptr,&buf,NULL);
 	if (ok && (sys_stat(buf,&sbuf) == 0)) {
-		newer_than = sbuf.st_mtime;
+		newer_than = convert_timespec_to_time_t(sbuf.st_ex_mtime);
 		DEBUG(1,("Getting files newer than %s",
 			 time_to_asc(newer_than)));
 	} else {
diff --git a/source3/client/clitar.c b/source3/client/clitar.c
index c9f3e87..0ab0f26 100644
--- a/source3/client/clitar.c
+++ b/source3/client/clitar.c
@@ -412,7 +412,7 @@ static void dotareof(int f)
 	/* Could be a pipe, in which case S_ISREG should fail,
 		* and we should write out at full size */
 	if (tp > 0) {
-		size_t towrite = S_ISREG(stbuf.st_mode) ? tp : tbufsiz;
+		size_t towrite = S_ISREG(stbuf.st_ex_mode) ? tp : tbufsiz;
 		if (sys_write(f, tarbuf, towrite) != towrite) {
 			DEBUG(0,("dotareof: sys_write fail\n"));
 		}
@@ -1791,7 +1791,8 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
 					SMB_STRUCT_STAT stbuf;
 
 					if (sys_stat(argv[Optind], &stbuf) == 0) {
-						newer_than = stbuf.st_mtime;
+						newer_than = convert_timespec_to_time_t(
+							stbuf.st_ex_mtime);
 						DEBUG(1,("Getting files newer than %s",
 							time_to_asc(newer_than)));
 						newOptind++;
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 248c326..e05a408 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -435,13 +435,32 @@ typedef uint64_t br_off;
  * Type for stat structure.
  */
 
-#ifndef SMB_STRUCT_STAT
-#  if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STAT64) && defined(HAVE_OFF64_T)
-#    define SMB_STRUCT_STAT struct stat64
-#  else
-#    define SMB_STRUCT_STAT struct stat
-#  endif
-#endif
+struct stat_ex {
+	dev_t		st_ex_dev;
+	ino_t		st_ex_ino;
+	mode_t		st_ex_mode;
+	nlink_t		st_ex_nlink;
+	uid_t		st_ex_uid;
+	gid_t		st_ex_gid;
+	dev_t		st_ex_rdev;
+	off_t		st_ex_size;
+	struct timespec st_ex_atime;
+	struct timespec st_ex_mtime;
+	struct timespec st_ex_ctime;
+	struct timespec st_ex_btime; /* birthtime */
+	blksize_t	st_ex_blksize;
+	blkcnt_t	st_ex_blocks;
+
+	/*
+	 * Add space for VFS internal extensions. The initial user of this
+	 * would be the onefs modules, passing the snapid from the stat calls
+	 * to the file_id_create call. Maybe we'll have to expand this later,
+	 * but the core of Samba should never look at this field.
+	 */
+	uint64_t vfs_private;
+};
+
+typedef struct stat_ex SMB_STRUCT_STAT;
 
 /*
  * Type for dirent structure.
diff --git a/source3/include/proto.h b/source3/include/proto.h
index e807c42..0a37832 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1019,13 +1019,6 @@ void srv_put_dos_date2(char *buf,int offset, time_t unixdate);
 void srv_put_dos_date3(char *buf,int offset,time_t unixdate);
 void put_long_date_timespec(char *p, struct timespec ts);
 void put_long_date(char *p, time_t t);
-struct timespec get_create_timespec(const SMB_STRUCT_STAT *st,bool fake_dirs);
-struct timespec get_atimespec(const SMB_STRUCT_STAT *pst);
-void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts);
-struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst);
-void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts);
-struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst);
-void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts);
 void dos_filetime_timespec(struct timespec *tsp);
 time_t srv_make_unix_date(const void *date_ptr);
 time_t srv_make_unix_date2(const void *date_ptr);
@@ -4182,7 +4175,7 @@ bool lp_recursive_veto_delete(int );
 bool lp_dos_filemode(int );
 bool lp_dos_filetimes(int );
 bool lp_dos_filetime_resolution(int );
-bool lp_fake_dir_create_times(int );
+bool lp_fake_dir_create_times(void);
 bool lp_blocking_locks(int );
 bool lp_inherit_perms(int );
 bool lp_inherit_acls(int );
@@ -6248,7 +6241,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
 		char **pp_fname_out,
 		SMB_OFF_T *size,
 		uint32 *mode,
-		time_t *date,
+		struct timespec *date,
 		bool check_descend,
 		bool ask_sharemode);
 bool is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, bool use_veto);
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 22cfaaf..7528883 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -88,9 +88,9 @@
  * stat structure is valid.
  */
 
-#define VALID_STAT(st) ((st).st_nlink != 0)  
-#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_mode))
-#define SET_STAT_INVALID(st) ((st).st_nlink = 0)
+#define VALID_STAT(st) ((st).st_ex_nlink != 0)
+#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_ex_mode))
+#define SET_STAT_INVALID(st) ((st).st_ex_nlink = 0)
 
 /* Macros to get at offsets within smb_lkrng and smb_unlkrng
    structures. We cannot define these as actual structures
diff --git a/source3/lib/debug.c b/source3/lib/debug.c
index 14aca3a..419af61 100644
--- a/source3/lib/debug.c
+++ b/source3/lib/debug.c
@@ -739,7 +739,7 @@ void check_log_size( void )
 
 	maxlog = lp_max_log_size() * 1024;
 
-	if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) {
+	if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_ex_size > maxlog ) {
 		(void)reopen_logs();
 		if( dbf && get_file_size( debugf ) > maxlog ) {
 			char *name = NULL;
diff --git a/source3/lib/system.c b/source3/lib/system.c
index e815766..7ebfa4f 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -290,6 +290,195 @@ int sys_fcntl_long(int fd, int cmd, long arg)
 	return ret;
 }
 
+/****************************************************************************
+ Return the best approximation to a 'create time' under UNIX from a stat
+ structure.
+****************************************************************************/
+
+static time_t calc_create_time(const struct stat *st)
+{
+	time_t ret, ret1;
+
+	ret = MIN(st->st_ctime, st->st_mtime);
+	ret1 = MIN(ret, st->st_atime);
+
+	if(ret1 != (time_t)0) {
+		return ret1;
+	}
+
+	/*
+	 * One of ctime, mtime or atime was zero (probably atime).
+	 * Just return MIN(ctime, mtime).
+	 */
+	return ret;
+}
+
+/****************************************************************************
+ Return the 'create time' from a stat struct if it exists (birthtime) or else
+ use the best approximation.
+****************************************************************************/
+
+static struct timespec get_create_timespec(const struct stat *pst)
+{
+	struct timespec ret;
+
+	if (S_ISDIR(pst->st_mode) && lp_fake_dir_create_times()) {
+		ret.tv_sec = 315493200L;          /* 1/1/1980 */
+		ret.tv_nsec = 0;
+		return ret;
+	}
+
+#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
+	ret = pst->st_birthtimespec;
+#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
+	ret.tv_sec = pst->st_birthtime;
+	ret.tv_nsec = pst->st_birthtimenspec;
+#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
+	ret.tv_sec = pst->st_birthtime;
+	ret.tv_nsec = 0;
+#else
+	ret.tv_sec = calc_create_time(pst);
+	ret.tv_nsec = 0;
+#endif
+
+	/* Deal with systems that don't initialize birthtime correctly.
+	 * Pointed out by SATOH Fumiyasu <fumiyas at osstech.jp>.
+	 */
+	if (null_timespec(ret)) {
+		ret.tv_sec = calc_create_time(pst);
+		ret.tv_nsec = 0;
+	}
+	return ret;
+}
+
+/****************************************************************************
+ Get/Set all the possible time fields from a stat struct as a timespec.
+****************************************************************************/
+
+static struct timespec get_atimespec(const struct stat *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+	struct timespec ret;
+
+	/* Old system - no ns timestamp. */
+	ret.tv_sec = pst->st_atime;
+	ret.tv_nsec = 0;
+	return ret;
+#else
+#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+	return pst->st_atim;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
+	struct timespec ret;
+	ret.tv_sec = pst->st_atime;
+	ret.tv_nsec = pst->st_atimensec;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
+	struct timespec ret;
+	ret.tv_sec = pst->st_atime;
+	ret.tv_nsec = pst->st_atime_n;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
+	struct timespec ret;
+	ret.tv_sec = pst->st_atime;
+	ret.tv_nsec = pst->st_uatime * 1000;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+	return pst->st_atimespec;
+#else
+#error	CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
+#endif
+#endif
+}
+
+static struct timespec get_mtimespec(const struct stat *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+	struct timespec ret;
+
+	/* Old system - no ns timestamp. */
+	ret.tv_sec = pst->st_mtime;
+	ret.tv_nsec = 0;
+	return ret;
+#else
+#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+	return pst->st_mtim;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
+	struct timespec ret;
+	ret.tv_sec = pst->st_mtime;
+	ret.tv_nsec = pst->st_mtimensec;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
+	struct timespec ret;
+	ret.tv_sec = pst->st_mtime;
+	ret.tv_nsec = pst->st_mtime_n;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
+	struct timespec ret;
+	ret.tv_sec = pst->st_mtime;
+	ret.tv_nsec = pst->st_umtime * 1000;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+	return pst->st_mtimespec;
+#else
+#error	CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
+#endif
+#endif
+}
+
+static struct timespec get_ctimespec(const struct stat *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+	struct timespec ret;
+
+	/* Old system - no ns timestamp. */
+	ret.tv_sec = pst->st_ctime;
+	ret.tv_nsec = 0;
+	return ret;
+#else
+#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+	return pst->st_ctim;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
+	struct timespec ret;
+	ret.tv_sec = pst->st_ctime;
+	ret.tv_nsec = pst->st_ctimensec;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
+	struct timespec ret;
+	ret.tv_sec = pst->st_ctime;
+	ret.tv_nsec = pst->st_ctime_n;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
+	struct timespec ret;
+	ret.tv_sec = pst->st_ctime;
+	ret.tv_nsec = pst->st_uctime * 1000;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+	return pst->st_ctimespec;
+#else
+#error	CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
+#endif
+#endif
+}
+
+static void init_stat_ex_from_stat (struct stat_ex *dst,
+				    const struct stat *src)
+{
+	dst->st_ex_dev = src->st_dev;
+	dst->st_ex_ino = src->st_ino;
+	dst->st_ex_mode = src->st_mode;
+	dst->st_ex_nlink = src->st_nlink;
+	dst->st_ex_uid = src->st_uid;
+	dst->st_ex_gid = src->st_gid;
+	dst->st_ex_rdev = src->st_rdev;
+	dst->st_ex_size = src->st_size;
+	dst->st_ex_atime = get_atimespec(src);
+	dst->st_ex_mtime = get_mtimespec(src);
+	dst->st_ex_ctime = get_ctimespec(src);
+	dst->st_ex_btime = get_create_timespec(src);
+	dst->st_ex_blksize = src->st_blksize;
+	dst->st_ex_blocks = src->st_blocks;
+}
+
 /*******************************************************************
 A stat() wrapper that will deal with 64 bit filesizes.
 ********************************************************************/
@@ -300,10 +489,16 @@ int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
 	ret = stat64(fname, sbuf);
 #else
-	ret = stat(fname, sbuf);
+	struct stat statbuf;
+	ret = stat(fname, &statbuf);
 #endif
-	/* we always want directories to appear zero size */
-	if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+	if (ret == 0) {
+		/* we always want directories to appear zero size */
+		if (S_ISDIR(statbuf.st_mode)) {
+			statbuf.st_size = 0;
+		}
+		init_stat_ex_from_stat(sbuf, &statbuf);
+	}
 	return ret;
 }
 
@@ -317,10 +512,16 @@ int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
 	ret = fstat64(fd, sbuf);
 #else
-	ret = fstat(fd, sbuf);
+	struct stat statbuf;
+	ret = fstat(fd, &statbuf);
 #endif
-	/* we always want directories to appear zero size */
-	if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+	if (ret == 0) {
+		/* we always want directories to appear zero size */
+		if (S_ISDIR(statbuf.st_mode)) {
+			statbuf.st_size = 0;
+		}
+		init_stat_ex_from_stat(sbuf, &statbuf);
+	}
 	return ret;
 }
 
@@ -334,10 +535,16 @@ int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
 	ret = lstat64(fname, sbuf);
 #else
-	ret = lstat(fname, sbuf);
+	struct stat statbuf;
+	ret = lstat(fname, &statbuf);
 #endif
-	/* we always want directories to appear zero size */
-	if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+	if (ret == 0) {
+		/* we always want directories to appear zero size */
+		if (S_ISDIR(statbuf.st_mode)) {
+			statbuf.st_size = 0;
+		}
+		init_stat_ex_from_stat(sbuf, &statbuf);
+	}
 	return ret;
 }
 
diff --git a/source3/lib/time.c b/source3/lib/time.c
index 865456b..1d4bd88 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -322,251 +322,6 @@ void put_long_date(char *p, time_t t)
 	put_long_date_timespec(p, ts);
 }
 
-/****************************************************************************
- Return the best approximation to a 'create time' under UNIX from a stat


-- 
SAMBA-CTDB repository


More information about the samba-cvs mailing list