Hi!

This patch modifies coda_release(), so that when all files belonging
to the same inode are closed, the container inode is released. This is
done with a reference counter in coda_inode_info, which is increased
in coda_open() and decreased in coda_release().

This change is important for userspace filesystems using the coda
kernel module, which -- unlinke Venus -- want to delete the container
file after use. With the current setup coda holds onto the container
inode, so the occupied disk space (which can be quite large) isn't
freed until coda flushes its cache.

Patch is against 2.4.0-test5.

Miklos

----------------------------------------------------------------------

diff -ru linux-2.4.0-test5.tar.gz@/linux/fs/coda/dir.c /spare/src/linux/fs/coda/dir.c
--- linux-2.4.0-test5.tar.gz@/linux/fs/coda/dir.c       Thu Jul 13 06:58:43 2000
+++ /spare/src/linux/fs/coda/dir.c      Wed Aug  2 09:50:47 2000
@@ -578,6 +578,7 @@
         unsigned short flags = f->f_flags & (~O_EXCL);
        unsigned short coda_flags = coda_flags_to_cflags(flags);
        struct coda_cred *cred;
+       struct coda_inode_info *cii;
 
        lock_kernel();
         ENTRY;
@@ -617,6 +618,9 @@
        }
        i->i_mapping = cont_inode->i_mapping;
 
+       cii = ITOC(i);
+       atomic_inc(&cii->c_contcount);
+
        CDEBUG(D_FILE, "result %d, coda i->i_count is %d for ino %ld\n", 
               error, atomic_read(&i->i_count), i->i_ino);
        CDEBUG(D_FILE, "cache ino: %ld, count %d, ops %p\n", 
@@ -634,6 +638,7 @@
         unsigned short flags = (f->f_flags) & (~O_EXCL);
        unsigned short cflags = coda_flags_to_cflags(flags);
        struct coda_cred *cred;
+       struct coda_inode_info *cii;
 
        lock_kernel();
         ENTRY;
@@ -644,10 +649,18 @@
        if (i->i_mapping != &i->i_data)
                container = (struct inode *)i->i_mapping->host;
 
-        CDEBUG(D_FILE, "RELEASE coda (ino %ld, ct %d) cache (ino %ld, ct %d)\n",
+       cii = ITOC(i);
+        CDEBUG(D_FILE, "RELEASE contcount: %i, coda (ino %ld, ct %d) cache (ino %ld, 
+ct %d)\n",
+              atomic_read(&cii->c_contcount),
                i->i_ino, atomic_read(&i->i_count),
                 (container ? container->i_ino : 0),
                (container ? atomic_read(&container->i_count) : -99));
+
+
+       if(atomic_dec_and_test(&cii->c_contcount)) {
+               i->i_mapping = &i->i_data;
+               iput(container);
+       }
 
        error = venus_release(i->i_sb, coda_i2f(i), cflags, cred);
 
diff -ru linux-2.4.0-test5.tar.gz@/linux/include/linux/coda_fs_i.h 
/spare/src/linux/include/linux/coda_fs_i.h
--- linux-2.4.0-test5.tar.gz@/linux/include/linux/coda_fs_i.h   Thu Jul 13 07:01:32 
2000
+++ /spare/src/linux/include/linux/coda_fs_i.h  Wed Aug  2 09:43:34 2000
@@ -23,6 +23,7 @@
         struct list_head   c_cnhead;    /* head of cache entries */
        struct list_head   c_volrootlist; /* list of volroot cnoddes */
         struct inode      *c_vnode;     /*  inode associated with cnode */
+       atomic_t           c_contcount; /* refcount for container inode */
         int                c_magic;     /* to verify the data structure */
 };
 

Reply via email to