Add support for retrieving the journal status via mountctl. Increase some
authorMatthew Dillon <dillon@dragonflybsd.org>
Sun, 9 Jan 2005 03:04:53 +0000 (03:04 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sun, 9 Jan 2005 03:04:53 +0000 (03:04 +0000)
of the buffer limits.

sys/kern/vfs_jops.c
sys/kern/vfs_journal.c
sys/kern/vfs_syscalls.c
sys/sys/mountctl.h

index 3ffca05..e2a1d93 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/vfs_jops.c,v 1.5 2004/12/31 23:48:08 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_jops.c,v 1.6 2005/01/09 03:04:51 dillon Exp $
  */
 /*
  * Each mount point may have zero or more independantly configured journals
@@ -104,6 +104,10 @@ static int journal_install_vfs_journal(struct mount *mp, struct file *fp,
 static int journal_remove_vfs_journal(struct mount *mp,
                            const struct mountctl_remove_journal *info);
 static int journal_resync_vfs_journal(struct mount *mp, const void *ctl);
+static int journal_status_vfs_journal(struct mount *mp,
+                      const struct mountctl_status_journal *info,
+                      struct mountctl_journal_ret_status *rstat,
+                      int buflen, int *res);
 static void journal_thread(void *info);
 
 static void *journal_reserve(struct journal *jo, 
@@ -197,7 +201,8 @@ journal_mountctl(struct vop_mountctl_args *ap)
            break;
        case MOUNTCTL_REMOVE_VFS_JOURNAL:
        case MOUNTCTL_RESYNC_VFS_JOURNAL:
-           error = EINVAL;
+       case MOUNTCTL_STATUS_VFS_JOURNAL:
+           error = ENOENT;
            break;
        default:
            error = EOPNOTSUPP;
@@ -226,6 +231,14 @@ journal_mountctl(struct vop_mountctl_args *ap)
                error = EINVAL;
            error = journal_resync_vfs_journal(mp, ap->a_ctl);
            break;
+       case MOUNTCTL_STATUS_VFS_JOURNAL:
+           if (ap->a_ctllen != sizeof(struct mountctl_status_journal))
+               error = EINVAL;
+           if (error == 0) {
+               error = journal_status_vfs_journal(mp, ap->a_ctl, 
+                                       ap->a_buf, ap->a_buflen, ap->a_res);
+           }
+           break;
        default:
            error = EOPNOTSUPP;
            break;
@@ -378,6 +391,50 @@ journal_resync_vfs_journal(struct mount *mp, const void *ctl)
     return(EINVAL);
 }
 
+static int
+journal_status_vfs_journal(struct mount *mp, 
+                      const struct mountctl_status_journal *info,
+                      struct mountctl_journal_ret_status *rstat,
+                      int buflen, int *res)
+{
+    struct journal *jo;
+    int error = 0;
+    int index;
+
+    index = 0;
+    *res = 0;
+    TAILQ_FOREACH(jo, &mp->mnt_jlist, jentry) {
+       if (info->index == MC_JOURNAL_INDEX_ID) {
+           if (bcmp(jo->id, info->id, sizeof(jo->id)) != 0)
+               continue;
+       } else if (info->index >= 0) {
+           if (info->index < index)
+               continue;
+       } else if (info->index != MC_JOURNAL_INDEX_ALL) {
+           continue;
+       }
+       if (buflen < sizeof(*rstat)) {
+           if (*res)
+               rstat[-1].flags |= MC_JOURNAL_STATUS_MORETOCOME;
+           else
+               error = EINVAL;
+           break;
+       }
+       bzero(rstat, sizeof(*rstat));
+       rstat->recsize = sizeof(*rstat);
+       bcopy(jo->id, rstat->id, sizeof(jo->id));
+       rstat->index = index;
+       rstat->membufsize = jo->fifo.size;
+       rstat->membufused = jo->fifo.xindex - jo->fifo.rindex;
+       rstat->membufiopend = jo->fifo.windex - jo->fifo.rindex;
+       rstat->bytessent = jo->total_acked;
+       ++rstat;
+       ++index;
+       *res += sizeof(*rstat);
+       buflen -= sizeof(*rstat);
+    }
+    return(error);
+}
 /*
  * The per-journal worker thread is responsible for writing out the
  * journal's FIFO to the target stream.
@@ -465,6 +522,7 @@ journal_thread(void *info)
         */
        jo->fifo.rindex += bytes;
        jo->fifo.xindex += bytes;
+       jo->total_acked += bytes;
        if (jo->flags & MC_JOURNAL_WWAIT) {
            jo->flags &= ~MC_JOURNAL_WWAIT;     /* XXX hysteresis */
            wakeup(&jo->fifo.windex);
index 68d8abc..2d54de5 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/vfs_journal.c,v 1.5 2004/12/31 23:48:08 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_journal.c,v 1.6 2005/01/09 03:04:51 dillon Exp $
  */
 /*
  * Each mount point may have zero or more independantly configured journals
@@ -104,6 +104,10 @@ static int journal_install_vfs_journal(struct mount *mp, struct file *fp,
 static int journal_remove_vfs_journal(struct mount *mp,
                            const struct mountctl_remove_journal *info);
 static int journal_resync_vfs_journal(struct mount *mp, const void *ctl);
+static int journal_status_vfs_journal(struct mount *mp,
+                      const struct mountctl_status_journal *info,
+                      struct mountctl_journal_ret_status *rstat,
+                      int buflen, int *res);
 static void journal_thread(void *info);
 
 static void *journal_reserve(struct journal *jo, 
@@ -197,7 +201,8 @@ journal_mountctl(struct vop_mountctl_args *ap)
            break;
        case MOUNTCTL_REMOVE_VFS_JOURNAL:
        case MOUNTCTL_RESYNC_VFS_JOURNAL:
-           error = EINVAL;
+       case MOUNTCTL_STATUS_VFS_JOURNAL:
+           error = ENOENT;
            break;
        default:
            error = EOPNOTSUPP;
@@ -226,6 +231,14 @@ journal_mountctl(struct vop_mountctl_args *ap)
                error = EINVAL;
            error = journal_resync_vfs_journal(mp, ap->a_ctl);
            break;
+       case MOUNTCTL_STATUS_VFS_JOURNAL:
+           if (ap->a_ctllen != sizeof(struct mountctl_status_journal))
+               error = EINVAL;
+           if (error == 0) {
+               error = journal_status_vfs_journal(mp, ap->a_ctl, 
+                                       ap->a_buf, ap->a_buflen, ap->a_res);
+           }
+           break;
        default:
            error = EOPNOTSUPP;
            break;
@@ -378,6 +391,50 @@ journal_resync_vfs_journal(struct mount *mp, const void *ctl)
     return(EINVAL);
 }
 
+static int
+journal_status_vfs_journal(struct mount *mp, 
+                      const struct mountctl_status_journal *info,
+                      struct mountctl_journal_ret_status *rstat,
+                      int buflen, int *res)
+{
+    struct journal *jo;
+    int error = 0;
+    int index;
+
+    index = 0;
+    *res = 0;
+    TAILQ_FOREACH(jo, &mp->mnt_jlist, jentry) {
+       if (info->index == MC_JOURNAL_INDEX_ID) {
+           if (bcmp(jo->id, info->id, sizeof(jo->id)) != 0)
+               continue;
+       } else if (info->index >= 0) {
+           if (info->index < index)
+               continue;
+       } else if (info->index != MC_JOURNAL_INDEX_ALL) {
+           continue;
+       }
+       if (buflen < sizeof(*rstat)) {
+           if (*res)
+               rstat[-1].flags |= MC_JOURNAL_STATUS_MORETOCOME;
+           else
+               error = EINVAL;
+           break;
+       }
+       bzero(rstat, sizeof(*rstat));
+       rstat->recsize = sizeof(*rstat);
+       bcopy(jo->id, rstat->id, sizeof(jo->id));
+       rstat->index = index;
+       rstat->membufsize = jo->fifo.size;
+       rstat->membufused = jo->fifo.xindex - jo->fifo.rindex;
+       rstat->membufiopend = jo->fifo.windex - jo->fifo.rindex;
+       rstat->bytessent = jo->total_acked;
+       ++rstat;
+       ++index;
+       *res += sizeof(*rstat);
+       buflen -= sizeof(*rstat);
+    }
+    return(error);
+}
 /*
  * The per-journal worker thread is responsible for writing out the
  * journal's FIFO to the target stream.
@@ -465,6 +522,7 @@ journal_thread(void *info)
         */
        jo->fifo.rindex += bytes;
        jo->fifo.xindex += bytes;
+       jo->total_acked += bytes;
        if (jo->flags & MC_JOURNAL_WWAIT) {
            jo->flags &= ~MC_JOURNAL_WWAIT;     /* XXX hysteresis */
            wakeup(&jo->fifo.windex);
index 5a0cf97..7a94742 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)vfs_syscalls.c      8.13 (Berkeley) 4/15/94
  * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.52 2004/12/29 02:40:02 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.53 2005/01/09 03:04:51 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -706,9 +706,9 @@ mountctl(struct mountctl_args *uap)
        /*
         * Argument length checks
         */
-       if (uap->ctllen < 0 || uap->ctllen > MAXPATHLEN)
+       if (uap->ctllen < 0 || uap->ctllen > 1024)
                return (EINVAL);
-       if (uap->buflen < 0 || uap->buflen > MAXPATHLEN)
+       if (uap->buflen < 0 || uap->buflen > 16 * 1024)
                return (EINVAL);
        if (uap->path == NULL)
                return (EINVAL);
index 7ec3d7c..b005e56 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/mountctl.h,v 1.4 2004/12/31 23:48:06 dillon Exp $
+ * $DragonFly: src/sys/sys/mountctl.h,v 1.5 2005/01/09 03:04:53 dillon Exp $
  */
 
 /*
 #define MOUNTCTL_INSTALL_VFS_JOURNAL   1
 #define MOUNTCTL_REMOVE_VFS_JOURNAL    2
 #define MOUNTCTL_RESYNC_VFS_JOURNAL    3
-#define MOUNTCTL_JOURNAL_VFS_STATUS    4
+#define MOUNTCTL_STATUS_VFS_JOURNAL    4
 
 #define MOUNTCTL_INSTALL_BLK_JOURNAL   8
 #define MOUNTCTL_REMOVE_BLK_JOURNAL    9
 #define MOUNTCTL_RESYNC_BLK_JOURNAL    10
-#define MOUNTCTL_JOURNAL_BLK_STATUS    11
+#define MOUNTCTL_STATUS_BLK_JOURNAL    11
 
 struct mountctl_install_journal {
        char    id[JIDMAX];
@@ -83,25 +83,35 @@ struct mountctl_remove_journal {
 #define MC_JOURNAL_REMOVE_TRASH                0x00000001      /* data -> trash */
 #define MC_JOURNAL_REMOVE_ASSYNC       0x00000002      /* asynchronous op */
 
-struct mountctl_journal_status {
+struct mountctl_status_journal {
        char    id[JIDMAX];
+       int     index;
+};
+
+#define MC_JOURNAL_INDEX_ALL           -2
+#define MC_JOURNAL_INDEX_ID            -1
+
+struct mountctl_journal_ret_status {
+       int     recsize;
+       char    id[JIDMAX];
+       int     index;
        int     flags;
        int64_t membufsize;
        int64_t membufused;
-       int64_t membufqueued;
+       int64_t membufiopend;
        int64_t swapbufsize;
        int64_t swapbufused;
-       int64_t swapbufqueued;
+       int64_t swapbufiopend;
        int64_t transidstart;
        int64_t transidcurrent;
-       int64_t transidqueued;
+       int64_t transidiopend;
        int64_t transidacked;
        int64_t bytessent;
        int64_t bytesacked;
        struct timeval lastack;
 };
 
-#define MC_JOURNAL_STATUS_NEXT         0x80000000      /* find next id */
+#define MC_JOURNAL_STATUS_MORETOCOME   0x00000001
 
 /*
  * Physical file format (binary)
@@ -354,6 +364,7 @@ struct journal {
        char            id[JIDMAX];
        int             flags;          /* journaling flags */
        int64_t         transid;
+       int64_t         total_acked;
        struct journal_memfifo fifo;
        struct thread   thread;
 };