hammer2 - Get data-usage aggregation working, add INODE_GET
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 19 May 2012 22:17:03 +0000 (15:17 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 19 May 2012 22:17:03 +0000 (15:17 -0700)
* Cleanup aggregation of data_count and inode_count in the inode.
  data_count should now work properly (though it requires a 'sync'
  if you want up-to-date information).

  This allow data and inode usage for an entire sub-tree to be
  retrieved from the parent directory inode.  No need to run 'du'
  over millions of inodes.

  The new 'hammer2 stat' command can be used to access the info.

* Add the HAMMER2IOC_INODE_GET/SET ioctls to access information that
  cannot be obtained from a normal stat().

sys/vfs/hammer2/hammer2_chain.c
sys/vfs/hammer2/hammer2_ioctl.c
sys/vfs/hammer2/hammer2_ioctl.h

index b04684b..808172c 100644 (file)
@@ -1546,7 +1546,8 @@ again:
         * Additional linkage for inodes.  Reuse the parent pointer to
         * find the parent directory.
         *
-        * Cumulative adjustments are inherited on [re]attach.
+        * Cumulative adjustments are inherited on [re]attach and will
+        * propagate up the tree on the next flush.
         */
        if (chain->bref.type == HAMMER2_BREF_TYPE_INODE) {
                hammer2_chain_t *scan = parent;
@@ -1558,8 +1559,8 @@ again:
                        ip->pip = scan->u.ip;
                        ip->pmp = scan->u.ip->pmp;
                        ip->depth = scan->u.ip->depth + 1;
-                       ip->delta_icount += ip->ip_data.inode_count;
-                       ip->delta_dcount += ip->ip_data.data_count;
+                       ip->pip->delta_icount += ip->ip_data.inode_count;
+                       ip->pip->delta_dcount += ip->ip_data.data_count;
                        ++ip->pip->delta_icount;
                }
        }
@@ -2057,16 +2058,20 @@ hammer2_chain_delete(hammer2_mount_t *hmp, hammer2_chain_t *parent,
 
        /*
         * Cumulative adjustments must be propagated to the parent inode
-        * when deleting and synchronized to ip.  A future reattachment
-        * (e.g. during a rename) expects only to use ip_data.*_count.
+        * when deleting and synchronized to ip.
+        *
+        * NOTE:  We do not propagate ip->delta_*count to the parent because
+        *        these represent adjustments that have not yet been
+        *        propagated upward, so we don't need to remove them from
+        *        the parent.
         *
         * Clear the pointer to the parent inode.
         */
        if (chain->bref.type == HAMMER2_BREF_TYPE_INODE) {
                ip = chain->u.ip;
                if (ip->pip) {
-                       ip->pip->delta_icount += ip->delta_icount;
-                       ip->pip->delta_dcount += ip->delta_dcount;
+                       ip->pip->delta_icount -= ip->ip_data.inode_count;
+                       ip->pip->delta_dcount -= ip->ip_data.data_count;
                        ip->ip_data.inode_count += ip->delta_icount;
                        ip->ip_data.data_count += ip->delta_dcount;
                        ip->delta_icount = 0;
index b1d7f06..e31ef5c 100644 (file)
@@ -52,6 +52,8 @@ static int hammer2_ioctl_socket_set(hammer2_inode_t *ip, void *data);
 static int hammer2_ioctl_pfs_get(hammer2_inode_t *ip, void *data);
 static int hammer2_ioctl_pfs_create(hammer2_inode_t *ip, void *data);
 static int hammer2_ioctl_pfs_delete(hammer2_inode_t *ip, void *data);
+static int hammer2_ioctl_inode_get(hammer2_inode_t *ip, void *data);
+static int hammer2_ioctl_inode_set(hammer2_inode_t *ip, void *data);
 
 int
 hammer2_ioctl(hammer2_inode_t *ip, u_long com, void *data, int fflag,
@@ -105,6 +107,13 @@ hammer2_ioctl(hammer2_inode_t *ip, u_long com, void *data, int fflag,
                if (error == 0)
                        error = hammer2_ioctl_pfs_delete(ip, data);
                break;
+       case HAMMER2IOC_INODE_GET:
+               error = hammer2_ioctl_inode_get(ip, data);
+               break;
+       case HAMMER2IOC_INODE_SET:
+               if (error == 0)
+                       error = hammer2_ioctl_inode_set(ip, data);
+               break;
        default:
                error = EOPNOTSUPP;
                break;
@@ -383,3 +392,34 @@ hammer2_ioctl_pfs_delete(hammer2_inode_t *ip, void *data)
                                    0, NULL);
        return (error);
 }
+
+/*
+ * Retrieve the raw inode structure
+ */
+static int
+hammer2_ioctl_inode_get(hammer2_inode_t *ip, void *data)
+{
+       hammer2_ioc_inode_t *ino = data;
+
+       hammer2_inode_lock_sh(ip);
+       ino->ip_data = ip->ip_data;
+       hammer2_inode_unlock_sh(ip);
+       return (0);
+}
+
+static int
+hammer2_ioctl_inode_set(hammer2_inode_t *ip, void *data)
+{
+       hammer2_ioc_inode_t *ino = data;
+       int error = EINVAL;
+
+       hammer2_inode_lock_ex(ip);
+       if (ino->flags & HAMMER2IOC_INODE_FLAG_IQUOTA) {
+       }
+       if (ino->flags & HAMMER2IOC_INODE_FLAG_DQUOTA) {
+       }
+       if (ino->flags & HAMMER2IOC_INODE_FLAG_COPIES) {
+       }
+       hammer2_inode_unlock_ex(ip);
+       return (error);
+}
index ffa49ad..175e211 100644 (file)
@@ -94,6 +94,24 @@ struct hammer2_ioc_pfs {
 
 typedef struct hammer2_ioc_pfs hammer2_ioc_pfs_t;
 
+/*
+ * Ioctls to manage inodes
+ */
+struct hammer2_ioc_inode {
+       uint32_t                flags;
+       hammer2_inode_data_t    ip_data;
+};
+
+typedef struct hammer2_ioc_inode hammer2_ioc_inode_t;
+
+#define HAMMER2IOC_INODE_FLAG_IQUOTA   0x00000001
+#define HAMMER2IOC_INODE_FLAG_DQUOTA   0x00000002
+#define HAMMER2IOC_INODE_FLAG_COPIES   0x00000004
+
+/*
+ * Ioctl list
+ */
+
 #define HAMMER2IOC_VERSION_GET _IOWR('h', 64, struct hammer2_ioc_version)
 
 #define HAMMER2IOC_REMOTE_GET  _IOWR('h', 68, struct hammer2_ioc_remote)
@@ -108,4 +126,7 @@ typedef struct hammer2_ioc_pfs hammer2_ioc_pfs_t;
 #define HAMMER2IOC_PFS_CREATE  _IOWR('h', 81, struct hammer2_ioc_pfs)
 #define HAMMER2IOC_PFS_DELETE  _IOWR('h', 82, struct hammer2_ioc_pfs)
 
+#define HAMMER2IOC_INODE_GET   _IOWR('h', 86, struct hammer2_ioc_inode)
+#define HAMMER2IOC_INODE_SET   _IOWR('h', 87, struct hammer2_ioc_inode)
+
 #endif