Try to update attributes for volume roots when they become available,
[openafs.git] / src / afs / LINUX / osi_vfsops.c
index 3e9faa1..fd20062 100644 (file)
  *
  * super_block operations should return negated errno to Linux.
  */
+#include <afsconfig.h>
 #include "../afs/param.h"
+
+RCSID("$Header$");
+
 #include "../afs/sysincludes.h"
 #include "../afs/afsincludes.h"
 #include "../afs/afs_stats.h"
@@ -74,6 +78,7 @@ struct super_block *afs_read_super(struct super_block *sb, void *data,
     AFS_GLOCK();
     if (afs_was_mounted) {
        printf("You must reload the AFS kernel extensions before remounting AFS.\n");
+       AFS_GUNLOCK();
        return NULL;
     }
     afs_was_mounted = 1;
@@ -89,6 +94,9 @@ struct super_block *afs_read_super(struct super_block *sb, void *data,
     sb->s_blocksize_bits = 10;
     sb->s_magic = AFS_VFSMAGIC;
     sb->s_op = &afs_sops;      /* Super block (vfs) ops */
+#if defined(MAX_NON_LFS)
+    sb->s_maxbytes = MAX_NON_LFS;
+#endif
     code = afs_root(sb);
     if (code)
        MOD_DEC_USE_COUNT;
@@ -126,17 +134,17 @@ static int afs_root(struct super_block *afsp)
 #endif
                
                /* "/afs" is a directory, reset inode ops accordingly. */
-               tvp->v.v_op = &afs_dir_iops;
+               AFSTOV(tvp)->v_op = &afs_dir_iops;
 #if defined(AFS_LINUX24_ENV)
-               tvp->v.v_fop = &afs_dir_fops;
+               AFSTOV(tvp)->v_fop = &afs_dir_fops;
 #endif
 
                /* setup super_block and mount point inode. */
                afs_globalVp = tvp;
 #if defined(AFS_LINUX24_ENV)
-               afsp->s_root = d_alloc_root((struct inode*)tvp);
+               afsp->s_root = d_alloc_root(AFSTOI(tvp));
 #else
-               afsp->s_root = d_alloc_root((struct inode*)tvp, NULL);
+               afsp->s_root = d_alloc_root(AFSTOI(tvp), NULL);
 #endif
                afsp->s_root->d_op = &afs_dentry_operations;
            } else
@@ -180,8 +188,8 @@ int afs_notify_change(struct dentry *dp, struct iattr* iattrp)
     VATTR_NULL(&vattr);
     iattr2vattr(&vattr, iattrp); /* Convert for AFS vnodeops call. */
     update_inode_cache(ip, &vattr);
-    code = afs_setattr((struct vcache*)ip, &vattr, credp);
-    afs_CopyOutAttrs((struct vcache*)ip, &vattr);
+    code = afs_setattr(ITOAFS(ip), &vattr, credp);
+    afs_CopyOutAttrs(ITOAFS(ip), &vattr);
     /* Note that the inode may still not have all the correct info. But at
      * least we've got the newest version of what was supposed to be set.
      */
@@ -210,7 +218,11 @@ static LIST_HEAD(dummy_inode_list);
  * pages to disk. So it needs an inode syncing function to update metadata when it
  * has synced some pages of a file to disk.
  */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+void afs_write_inode(struct inode *ip, int unused) 
+#else
 void afs_write_inode(struct inode *ip) 
+#endif
 {
     /* and put it back on our dummy list. */
     list_del(&ip->i_list);
@@ -227,37 +239,17 @@ void afs_write_inode(struct inode *ip)
  * If we use the common inode pool, we'll need to set i_nlink to 0 here.
  * That will trigger the call to delete routine.
  */
+
 void afs_delete_inode(struct inode *ip)
 {
-    cred_t *credp = crref();
-    struct vcache *vc = (struct vcache*)ip;
+    struct vcache *vc = ITOAFS(ip);
 
     AFS_GLOCK();
-#if defined(AFS_LINUX24_ENV)
-    lock_kernel();
-    if (atomic_read(&ip->i_count) > 1)
-#else
-    if (ip->i_count > 1)
-#endif
-       printf("afs_put_inode: ino %d (0x%x) has count %d\n", ip->i_ino, ip);
-
-    ObtainWriteLock(&vc->lock, 504);
-    afs_InactiveVCache(vc, credp);
-#if defined(AFS_LINUX24_ENV)
-    atomic_set(&ip->i_count, 0);
-#else
-    ip->i_count = 0;
-#endif
-    ip->i_nlink = 0; /* iput checks this after calling this routine. */
-    ReleaseWriteLock(&vc->lock);
-
-#ifdef AFS_LINUX24_ENV
-    unlock_kernel();
-#endif
+    osi_clear_inode(ip);
     AFS_GUNLOCK();
-    crfree(credp);
 }
 
+
 /* afs_put_super
  * Called from unmount to release super_block. */
 void afs_put_super(struct super_block *sbp)
@@ -269,8 +261,10 @@ void afs_put_super(struct super_block *sbp)
     AFS_GLOCK();
     AFS_STATCNT(afs_unmount);
 
-    if (!suser())
+    if (!suser()) {
+       AFS_GUNLOCK();
        return;
+    }
 
     afs_globalVFS = 0;
     afs_globalVp = 0;
@@ -339,6 +333,14 @@ int afs_statfs(struct super_block *sbp, struct statfs *statp, int size)
 }
 
 
+void 
+afs_umount_begin(struct super_block *sbp)
+{
+    afs_put_super(sbp);      
+    afs_shuttingdown=1;
+    afs_was_mounted=0;
+}
+
 #if defined(AFS_LINUX24_ENV)
 struct super_operations afs_sops = {
     read_inode:        afs_read_inode,
@@ -346,6 +348,7 @@ struct super_operations afs_sops = {
     delete_inode:      afs_delete_inode,
     put_super:         afs_put_super,
     statfs:            afs_statfs,
+    umount_begin:      NULL /* afs_umount_begin */
 };
 #else
 struct super_operations afs_sops = {
@@ -359,7 +362,7 @@ struct super_operations afs_sops = {
     afs_statfs,
     NULL,              /* afs_remount_fs - see doc above */
     NULL,              /* afs_clear_inode */
-    NULL,              /* afs_umount_begin */
+    NULL                /* afs_umount_begin */
 };
 #endif
 
@@ -460,3 +463,13 @@ void vcache2inode(struct vcache *avc)
     VATTR_NULL(&vattr);
     afs_CopyOutAttrs(avc, &vattr); /* calls vattr2inode */
 }
+
+/* Yet another one for fakestat'ed mountpoints */
+void vcache2fakeinode(struct vcache *rootvp, struct vcache *mpvp)
+{
+    struct vattr vattr;
+
+    VATTR_NULL(&vattr);
+    afs_CopyOutAttrs(rootvp, &vattr);
+    vattr2inode(AFSTOV(mpvp), &vattr);
+}