aft: Update mtime and file size on afhi changes.
authorAndre Noll <maan@tuebingen.mpg.de>
Tue, 23 Dec 2014 12:52:03 +0000 (12:52 +0000)
committerAndre Noll <maan@tuebingen.mpg.de>
Mon, 30 Mar 2015 21:40:58 +0000 (21:40 +0000)
If the current audio file is re-added to the osl database, for example
because meta tags have changed, file size and modification time change.
However, the paraslash stat command still shows the old values because
currently the virtual streaming system calls fstat(2) only once when
the audio file is opened and keeps reporting the resulting mtime and
file size values until the file is closed.

This commit introduces make_inode_status_items() which is called
from make_status_items() on AFSI_CHANGE and AFHI_CHANGE events for
the current audio file. The new function calls stat(2) on the path
obtained from the current aft row. We can't use fstat(2) since (a)
we don't have an open file descriptor any more and (b) this would
not work anyway if the original file was overwritten.

Due to the new helper, mmd->mtime can be removed. We must keep
mmd->size though, since we need the original file size for the call
to munmap().

aft.c
command.c
server.h
vss.c

diff --git a/aft.c b/aft.c
index 0e86b12d6c13ea1992c0c751dae61df43f78b226..59be56eb68cd274debfe5077c5031687121fc7fa 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1043,6 +1043,28 @@ out:
 static struct ls_data status_item_ls_data;
 static struct osl_row *current_aft_row;
 
+static void make_inode_status_items(struct para_buffer *pb)
+{
+       struct stat statbuf = {.st_size = 0};
+       char *path, mtime_str[30] = "\0";
+       struct tm mtime_tm;
+       int ret;
+
+       ret = get_audio_file_path_of_row(current_aft_row, &path);
+       if (ret < 0)
+               goto out;
+       ret = stat(path, &statbuf);
+       if (ret < 0)
+               goto out;
+       localtime_r(&statbuf.st_mtime, &mtime_tm);
+       ret = strftime(mtime_str, 29, "%b %d %Y", &mtime_tm);
+       assert(ret > 0); /* number of bytes placed in mtime_str */
+out:
+       /* We don't care too much about errors here */
+       (void)WRITE_STATUS_ITEM(pb, SI_MTIME, "%s\n", mtime_str);
+       (void)WRITE_STATUS_ITEM(pb, SI_FILE_SIZE, "%ld\n", statbuf.st_size / 1024);
+}
+
 static int make_status_items(void)
 {
        struct ls_options opts = {
@@ -1057,6 +1079,7 @@ static int make_status_items(void)
        ret = print_list_item(&status_item_ls_data, &opts, &pb, current_time);
        if (ret < 0)
                return ret;
+       make_inode_status_items(&pb);
        free(status_items);
        status_items = pb.buf;
        memset(&pb, 0, sizeof(pb));
@@ -1068,6 +1091,7 @@ static int make_status_items(void)
                status_items = NULL;
                return ret;
        }
+       make_inode_status_items(&pb);
        free(parser_friendly_status_items);
        parser_friendly_status_items = pb.buf;
        return 1;
index 2ef9c5a87b54760ed38fc41e4f3b83391a4aa3f5..0baad5dcfca009ba0261c68e270073d72b277e06 100644 (file)
--- a/command.c
+++ b/command.c
@@ -112,21 +112,15 @@ static char *vss_get_status_flags(unsigned int flags)
 static unsigned get_status(struct misc_meta_data *nmmd, int parser_friendly,
                char **result)
 {
-       char mtime[30] = "";
        char *status, *flags; /* vss status info */
        /* nobody updates our version of "now" */
        long offset = (nmmd->offset + 500) / 1000;
        struct timeval current_time;
-       struct tm mtime_tm;
        struct para_buffer b = {.flags = parser_friendly? PBF_SIZE_PREFIX : 0};
 
        /* report real status */
        status = vss_status_tohuman(nmmd->vss_status_flags);
        flags = vss_get_status_flags(nmmd->vss_status_flags);
-       if (nmmd->size) { /* parent currently has an audio file open */
-               localtime_r(&nmmd->mtime, &mtime_tm);
-               strftime(mtime, 29, "%b %d %Y", &mtime_tm);
-       }
        clock_get_realtime(&current_time);
        /*
         * The calls to WRITE_STATUS_ITEM() below never fail because
@@ -134,8 +128,6 @@ static unsigned get_status(struct misc_meta_data *nmmd, int parser_friendly,
         * is not smart enough to prove this and complains nevertheless.
         * Casting the return value to void silences clang.
         */
-       (void)WRITE_STATUS_ITEM(&b, SI_FILE_SIZE, "%zu\n", nmmd->size / 1024);
-       (void)WRITE_STATUS_ITEM(&b, SI_MTIME, "%s\n", mtime);
        (void)WRITE_STATUS_ITEM(&b, SI_STATUS, "%s\n", status);
        (void)WRITE_STATUS_ITEM(&b, SI_STATUS_FLAGS, "%s\n", flags);
        (void)WRITE_STATUS_ITEM(&b, SI_OFFSET, "%li\n", offset);
index a89e005a10b3027be020dc3689b410131e71ff49..287614c8d884703fbfe30b1dd7edadde1f9e10bc 100644 (file)
--- a/server.h
+++ b/server.h
@@ -52,8 +52,6 @@ struct sender_command_data{
 struct misc_meta_data {
        /** The size of the current audio file in bytes. */
        size_t size;
-       /** The last modification time of the current audio file. */
-       time_t mtime;
        /** The "old" status flags -- commands may only read them. */
        unsigned int vss_status_flags;
        /** The new status flags -- commands may set them. */
diff --git a/vss.c b/vss.c
index fc42ba68662a00df0923ceb963c47e4ece5b1686..ea075df923a9e7b551ffc5cb220fb5bfe8a6e7c5 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -855,7 +855,6 @@ static void vss_eof(struct vss_task *vsst)
        mmd->afd.afhi.chunk_tv.tv_usec = 0;
        free(mmd->afd.afhi.chunk_table);
        mmd->afd.afhi.chunk_table = NULL;
-       mmd->mtime = 0;
        mmd->size = 0;
        mmd->events++;
 }
@@ -1011,7 +1010,6 @@ static void recv_afs_result(struct vss_task *vsst, fd_set *rfds)
                goto err;
        }
        mmd->size = statbuf.st_size;
-       mmd->mtime = statbuf.st_mtime;
        ret = para_mmap(mmd->size, PROT_READ, MAP_PRIVATE | MAP_POPULATE,
                passed_fd, 0, &vsst->map);
        if (ret < 0)