lkml.org 
[lkml]   [2009]   [Dec]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: [fuse-devel] utimensat fails to update ctime
    From
    Date
    On Tue, 22 Dec 2009, Jean-Pierre André wrote:
    > With ntfs-3g this is not directly possible, because
    > the interface does not provide flags telling which
    > timestamps should be updated. The only way would
    > be fuse feeding both values (even though unchanged)
    > before calling ntfs-3g. This is true for all versions of
    > ntfs-3g.

    Here's a patch for the high level lib. If the flag_utime_omit_ok flag
    is set then the ->utimes() method will be supplied with arguments that
    correspond to utimensat (i.e. it can have UTIME_NOW and UTIME_OMIT
    values).

    Thanks,
    Miklos

    Index: fuse/configure.in
    ===================================================================
    --- fuse.orig/configure.in 2009-12-22 12:46:44.000000000 +0100
    +++ fuse/configure.in 2009-12-22 13:16:07.000000000 +0100
    @@ -53,7 +53,7 @@ fi
    if test "$enable_mtab" = "no"; then
    AC_DEFINE(IGNORE_MTAB, 1, [Don't update /etc/mtab])
    fi
    -AC_CHECK_FUNCS([fork setxattr fdatasync])
    +AC_CHECK_FUNCS([fork setxattr fdatasync utimensat])
    AC_CHECK_MEMBERS([struct stat.st_atim])
    AC_CHECK_MEMBERS([struct stat.st_atimespec])

    Index: fuse/include/fuse.h
    ===================================================================
    --- fuse.orig/include/fuse.h 2009-12-22 12:46:44.000000000 +0100
    +++ fuse/include/fuse.h 2009-12-22 13:16:07.000000000 +0100
    @@ -458,9 +458,15 @@ struct fuse_operations {
    unsigned int flag_nullpath_ok : 1;

    /**
    + * Flag indicating that the filesystem accepts special
    + * UTIME_NOW and UTIME_OMIT values in its utimens operation.
    + */
    + unsigned int flag_utime_omit_ok : 1;
    +
    + /**
    * Reserved flags, don't set
    */
    - unsigned int flag_reserved : 31;
    + unsigned int flag_reserved : 30;

    /**
    * Ioctl
    Index: fuse/lib/fuse.c
    ===================================================================
    --- fuse.orig/lib/fuse.c 2009-12-22 12:46:44.000000000 +0100
    +++ fuse/lib/fuse.c 2009-12-22 13:16:07.000000000 +0100
    @@ -97,6 +97,7 @@ struct fuse {
    int intr_installed;
    struct fuse_fs *fs;
    int nullpath_ok;
    + int utime_omit_ok;
    int curr_ticket;
    struct lock_queue_element *lockq;
    };
    @@ -2119,6 +2120,29 @@ static void fuse_lib_setattr(fuse_req_t
    err = fuse_fs_truncate(f->fs, path,
    attr->st_size);
    }
    +#ifdef HAVE_UTIMENSAT
    + if (!err && f->utime_omit_ok &&
    + (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
    + struct timespec tv[2];
    +
    + tv[0].tv_sec = 0;
    + tv[1].tv_sec = 0;
    + tv[0].tv_nsec = UTIME_OMIT;
    + tv[1].tv_nsec = UTIME_OMIT;
    +
    + if (valid & FUSE_SET_ATTR_ATIME_NOW)
    + tv[0].tv_nsec = UTIME_NOW;
    + else if (valid & FUSE_SET_ATTR_ATIME)
    + tv[0] = attr->st_atim;
    +
    + if (valid & FUSE_SET_ATTR_MTIME_NOW)
    + tv[1].tv_nsec = UTIME_NOW;
    + else if (valid & FUSE_SET_ATTR_MTIME)
    + tv[1] = attr->st_mtim;
    +
    + err = fuse_fs_utimens(f->fs, path, tv);
    + } else
    +#endif
    if (!err &&
    (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
    (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
    @@ -3637,6 +3661,7 @@ static int fuse_push_module(struct fuse
    newfs->m = m;
    f->fs = newfs;
    f->nullpath_ok = newfs->op.flag_nullpath_ok && f->nullpath_ok;
    + f->utime_omit_ok = newfs->op.flag_utime_omit_ok && f->utime_omit_ok;
    return 0;
    }

    @@ -3687,6 +3712,7 @@ struct fuse *fuse_new_common(struct fuse
    fs->compat = compat;
    f->fs = fs;
    f->nullpath_ok = fs->op.flag_nullpath_ok;
    + f->utime_omit_ok = fs->op.flag_utime_omit_ok;

    /* Oh f**k, this is ugly! */
    if (!fs->op.lock) {
    @@ -3743,8 +3769,10 @@ struct fuse *fuse_new_common(struct fuse

    fuse_session_add_chan(f->se, ch);

    - if (f->conf.debug)
    + if (f->conf.debug) {
    fprintf(stderr, "nullpath_ok: %i\n", f->nullpath_ok);
    + fprintf(stderr, "utime_omit_ok: %i\n", f->utime_omit_ok);
    + }

    /* Trace topmost layer by default */
    f->fs->debug = f->conf.debug;
    Index: fuse/example/fusexmp_fh.c
    ===================================================================
    --- fuse.orig/example/fusexmp_fh.c 2009-06-19 12:24:25.000000000 +0200
    +++ fuse/example/fusexmp_fh.c 2009-12-22 13:55:04.000000000 +0100
    @@ -283,6 +283,9 @@ static int xmp_ftruncate(const char *pat
    static int xmp_utimens(const char *path, const struct timespec ts[2])
    {
    int res;
    +#ifdef HAVE_UTIMENSAT
    + res = utimensat(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW);
    +#else
    struct timeval tv[2];

    tv[0].tv_sec = ts[0].tv_sec;
    @@ -291,6 +294,7 @@ static int xmp_utimens(const char *path,
    tv[1].tv_usec = ts[1].tv_nsec / 1000;

    res = utimes(path, tv);
    +#endif
    if (res == -1)
    return -errno;

    @@ -486,6 +490,9 @@ static struct fuse_operations xmp_oper =
    .lock = xmp_lock,

    .flag_nullpath_ok = 1,
    +#if HAVE_UTIMENSAT
    + .flag_utime_omit_ok = 1,
    +#endif
    };

    int main(int argc, char *argv[])
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2009-12-22 14:05    [W:7.944 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site