eCryptfs: don't encrypt file key with filename key
[safe/jmp/linux-2.6] / fs / gfs2 / ops_super.c
index 29f8a5c..320323d 100644 (file)
@@ -182,7 +182,6 @@ static void gfs2_put_super(struct super_block *sb)
 
        /*  At this point, we're through participating in the lockspace  */
        gfs2_sys_fs_del(sdp);
-       kfree(sdp);
 }
 
 /**
@@ -212,18 +211,18 @@ static int gfs2_sync_fs(struct super_block *sb, int wait)
 }
 
 /**
- * gfs2_write_super_lockfs - prevent further writes to the filesystem
+ * gfs2_freeze - prevent further writes to the filesystem
  * @sb: the VFS structure for the filesystem
  *
  */
 
-static void gfs2_write_super_lockfs(struct super_block *sb)
+static int gfs2_freeze(struct super_block *sb)
 {
        struct gfs2_sbd *sdp = sb->s_fs_info;
        int error;
 
        if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
-               return;
+               return -EINVAL;
 
        for (;;) {
                error = gfs2_freeze_fs(sdp);
@@ -243,17 +242,150 @@ static void gfs2_write_super_lockfs(struct super_block *sb)
                fs_err(sdp, "retrying...\n");
                msleep(1000);
        }
+       return 0;
 }
 
 /**
- * gfs2_unlockfs - reallow writes to the filesystem
+ * gfs2_unfreeze - reallow writes to the filesystem
  * @sb: the VFS structure for the filesystem
  *
  */
 
-static void gfs2_unlockfs(struct super_block *sb)
+static int gfs2_unfreeze(struct super_block *sb)
 {
        gfs2_unfreeze_fs(sb->s_fs_info);
+       return 0;
+}
+
+/**
+ * statfs_fill - fill in the sg for a given RG
+ * @rgd: the RG
+ * @sc: the sc structure
+ *
+ * Returns: 0 on success, -ESTALE if the LVB is invalid
+ */
+
+static int statfs_slow_fill(struct gfs2_rgrpd *rgd,
+                           struct gfs2_statfs_change_host *sc)
+{
+       gfs2_rgrp_verify(rgd);
+       sc->sc_total += rgd->rd_data;
+       sc->sc_free += rgd->rd_free;
+       sc->sc_dinodes += rgd->rd_dinodes;
+       return 0;
+}
+
+/**
+ * gfs2_statfs_slow - Stat a filesystem using asynchronous locking
+ * @sdp: the filesystem
+ * @sc: the sc info that will be returned
+ *
+ * Any error (other than a signal) will cause this routine to fall back
+ * to the synchronous version.
+ *
+ * FIXME: This really shouldn't busy wait like this.
+ *
+ * Returns: errno
+ */
+
+static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc)
+{
+       struct gfs2_holder ri_gh;
+       struct gfs2_rgrpd *rgd_next;
+       struct gfs2_holder *gha, *gh;
+       unsigned int slots = 64;
+       unsigned int x;
+       int done;
+       int error = 0, err;
+
+       memset(sc, 0, sizeof(struct gfs2_statfs_change_host));
+       gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL);
+       if (!gha)
+               return -ENOMEM;
+
+       error = gfs2_rindex_hold(sdp, &ri_gh);
+       if (error)
+               goto out;
+
+       rgd_next = gfs2_rgrpd_get_first(sdp);
+
+       for (;;) {
+               done = 1;
+
+               for (x = 0; x < slots; x++) {
+                       gh = gha + x;
+
+                       if (gh->gh_gl && gfs2_glock_poll(gh)) {
+                               err = gfs2_glock_wait(gh);
+                               if (err) {
+                                       gfs2_holder_uninit(gh);
+                                       error = err;
+                               } else {
+                                       if (!error)
+                                               error = statfs_slow_fill(
+                                                       gh->gh_gl->gl_object, sc);
+                                       gfs2_glock_dq_uninit(gh);
+                               }
+                       }
+
+                       if (gh->gh_gl)
+                               done = 0;
+                       else if (rgd_next && !error) {
+                               error = gfs2_glock_nq_init(rgd_next->rd_gl,
+                                                          LM_ST_SHARED,
+                                                          GL_ASYNC,
+                                                          gh);
+                               rgd_next = gfs2_rgrpd_get_next(rgd_next);
+                               done = 0;
+                       }
+
+                       if (signal_pending(current))
+                               error = -ERESTARTSYS;
+               }
+
+               if (done)
+                       break;
+
+               yield();
+       }
+
+       gfs2_glock_dq_uninit(&ri_gh);
+
+out:
+       kfree(gha);
+       return error;
+}
+
+/**
+ * gfs2_statfs_i - Do a statfs
+ * @sdp: the filesystem
+ * @sg: the sg structure
+ *
+ * Returns: errno
+ */
+
+static int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc)
+{
+       struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
+       struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
+
+       spin_lock(&sdp->sd_statfs_spin);
+
+       *sc = *m_sc;
+       sc->sc_total += l_sc->sc_total;
+       sc->sc_free += l_sc->sc_free;
+       sc->sc_dinodes += l_sc->sc_dinodes;
+
+       spin_unlock(&sdp->sd_statfs_spin);
+
+       if (sc->sc_free < 0)
+               sc->sc_free = 0;
+       if (sc->sc_free > sc->sc_total)
+               sc->sc_free = sc->sc_total;
+       if (sc->sc_dinodes < 0)
+               sc->sc_dinodes = 0;
+
+       return 0;
 }
 
 /**
@@ -558,8 +690,8 @@ const struct super_operations gfs2_super_ops = {
        .put_super              = gfs2_put_super,
        .write_super            = gfs2_write_super,
        .sync_fs                = gfs2_sync_fs,
-       .write_super_lockfs     = gfs2_write_super_lockfs,
-       .unlockfs               = gfs2_unlockfs,
+       .freeze_fs              = gfs2_freeze,
+       .unfreeze_fs            = gfs2_unfreeze,
        .statfs                 = gfs2_statfs,
        .remount_fs             = gfs2_remount_fs,
        .clear_inode            = gfs2_clear_inode,