]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/afs/super.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
[linux-2.6-omap-h63xx.git] / fs / afs / super.c
index 7030d76155fcdf42398ccc71e8a6c8af17237d9a..2e8496ba1205386ed2e5bc959947460688714496 100644 (file)
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/parser.h>
+#include <linux/statfs.h>
+#include <linux/sched.h>
 #include "internal.h"
 
 #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
 
 static void afs_i_init_once(void *foo, struct kmem_cache *cachep,
                            unsigned long flags);
-
 static int afs_get_sb(struct file_system_type *fs_type,
                      int flags, const char *dev_name,
                      void *data, struct vfsmount *mnt);
-
 static struct inode *afs_alloc_inode(struct super_block *sb);
-
 static void afs_put_super(struct super_block *sb);
-
 static void afs_destroy_inode(struct inode *inode);
+static int afs_statfs(struct dentry *dentry, struct kstatfs *buf);
 
 struct file_system_type afs_fs_type = {
        .owner          = THIS_MODULE,
@@ -47,9 +46,9 @@ struct file_system_type afs_fs_type = {
 };
 
 static const struct super_operations afs_super_ops = {
-       .statfs         = simple_statfs,
+       .statfs         = afs_statfs,
        .alloc_inode    = afs_alloc_inode,
-       .drop_inode     = generic_delete_inode,
+       .write_inode    = afs_write_inode,
        .destroy_inode  = afs_destroy_inode,
        .clear_inode    = afs_clear_inode,
        .umount_begin   = afs_umount_begin,
@@ -66,7 +65,7 @@ enum {
        afs_opt_vol,
 };
 
-static const match_table_t afs_options_list = {
+static match_table_t afs_options_list = {
        { afs_opt_cell,         "cell=%s"       },
        { afs_opt_rwpath,       "rwpath"        },
        { afs_opt_vol,          "vol=%s"        },
@@ -453,15 +452,15 @@ static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep,
 {
        struct afs_vnode *vnode = _vnode;
 
-       if (flags & SLAB_CTOR_CONSTRUCTOR) {
-               memset(vnode, 0, sizeof(*vnode));
-               inode_init_once(&vnode->vfs_inode);
-               init_waitqueue_head(&vnode->update_waitq);
-               mutex_init(&vnode->permits_lock);
-               mutex_init(&vnode->validate_lock);
-               spin_lock_init(&vnode->lock);
-               INIT_WORK(&vnode->cb_broken_work, afs_broken_callback_work);
-       }
+       memset(vnode, 0, sizeof(*vnode));
+       inode_init_once(&vnode->vfs_inode);
+       init_waitqueue_head(&vnode->update_waitq);
+       mutex_init(&vnode->permits_lock);
+       mutex_init(&vnode->validate_lock);
+       spin_lock_init(&vnode->writeback_lock);
+       spin_lock_init(&vnode->lock);
+       INIT_LIST_HEAD(&vnode->writebacks);
+       INIT_WORK(&vnode->cb_broken_work, afs_broken_callback_work);
 }
 
 /*
@@ -485,6 +484,7 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
        vnode->flags            = 1 << AFS_VNODE_UNSET;
        vnode->cb_promised      = false;
 
+       _leave(" = %p", &vnode->vfs_inode);
        return &vnode->vfs_inode;
 }
 
@@ -495,7 +495,7 @@ static void afs_destroy_inode(struct inode *inode)
 {
        struct afs_vnode *vnode = AFS_FS_I(inode);
 
-       _enter("{%lu}", inode->i_ino);
+       _enter("%p{%x:%u}", inode, vnode->fid.vid, vnode->fid.vnode);
 
        _debug("DESTROY INODE %p", inode);
 
@@ -504,3 +504,36 @@ static void afs_destroy_inode(struct inode *inode)
        kmem_cache_free(afs_inode_cachep, vnode);
        atomic_dec(&afs_count_active_inodes);
 }
+
+/*
+ * return information about an AFS volume
+ */
+static int afs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+       struct afs_volume_status vs;
+       struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode);
+       struct key *key;
+       int ret;
+
+       key = afs_request_key(vnode->volume->cell);
+       if (IS_ERR(key))
+               return PTR_ERR(key);
+
+       ret = afs_vnode_get_volume_status(vnode, key, &vs);
+       key_put(key);
+       if (ret < 0) {
+               _leave(" = %d", ret);
+               return ret;
+       }
+
+       buf->f_type     = dentry->d_sb->s_magic;
+       buf->f_bsize    = AFS_BLOCK_SIZE;
+       buf->f_namelen  = AFSNAMEMAX - 1;
+
+       if (vs.max_quota == 0)
+               buf->f_blocks = vs.part_max_blocks;
+       else
+               buf->f_blocks = vs.max_quota;
+       buf->f_bavail = buf->f_bfree = buf->f_blocks - vs.blocks_in_use;
+       return 0;
+}