Skip to contentSkip to conversation

2.2.x Fixes for stackable filesystems

PATCH New William Taber 1 participant 1 message Oct 26, 2000

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 2.2.x Fixes for stackable filesystems

Linus, Alan,

I am proposing this patch for inclusion in the 2.2.x tree. (Whether it goes into 2.2.18 or 2.2.19 is your call.) We have run this successfully with 2.2.14 through 2.2.17.

Our kernel patches help stacking file systems work properly in two areas:

* dentry reference count fixes when files are opened by init_private_file()
* file reference count fixes for stacking filesystems mmap().

1. In some cases, stacking file systems which do no data translation may want to substitute another dentry/inode at the time of a file open. If they do that, the dentry reference counts will get mishandled by some callers of init_private_file(). Our changes make init_private_file() take a dentry reference itself, and free it only if an error occurs on the file open. This leaves the file open routine free to swap the dentry with another one. All callers of the file system open routine must dget() the dentry before putting it into the file structure prior to calling the open routine. Callers of init_private_file() must dput() the file's dentry when they are done with the file.

2. In the mmap case, stacking file systems which do no data translation probably want to substitute the underlying file system's file pointer, so that paging operations are handled directly by the underlying file system. The call into the file system's mmap() must be allowed to set the VM area's file pointer, so that it can effect this swap. Our change to the VM system is to set the VMA's file pointer only if the specific mmap() routine did not set it.

Thanks,

Will Taber

+---------------------------------------------------------------------+
| Will Taber                                                          |
| Software Engineer, CMBU                 E-mail  [email protected] |
| Rational Software Corporation           Phone:  781-676-2436        |
| 20 Maguire Road, Lexington, Mass. 02421                             |
+---------------------------------------------------------------------+
fs/exec.c +3 -2
diff -Naur linux.clean.2.2.14/fs/exec.c linux/fs/exec.c
@@ -136,7 +136,7 @@
 			goto out_fd;
 		f->f_flags = mode;
 		f->f_mode = (mode+1) & O_ACCMODE;
-		f->f_dentry = dentry;
+		f->f_dentry = dget(dentry);
 		f->f_pos = 0;
 		f->f_reada = 0;
 		f->f_op = inode->i_op->default_file_ops;
@@ -146,11 +146,11 @@
 				goto out_filp;
 		}
 		fd_install(fd, f);
-		dget(dentry);
 	}
 	return fd;
 
 out_filp:
+        dput(dentry);
 	if (error > 0)
 		error = -EIO;
 	put_filp(f);
@@ -371,6 +371,7 @@
 close_readexec:
 	if (file.f_op->release)
 		file.f_op->release(inode,&file);
+        dput(file.f_dentry);
 end_readexec:
 	return result;
 }
fs/file_table.c +8 -4
diff -Naur linux.clean.2.2.14/fs/file_table.c linux/fs/file_table.c
@@ -117,16 +117,20 @@
  */
 int init_private_file(struct file *filp, struct dentry *dentry, int mode)
 {
+	int err;
 	memset(filp, 0, sizeof(*filp));
 	filp->f_mode   = mode;
 	filp->f_count  = 1;
-	filp->f_dentry = dentry;
+	filp->f_dentry = dget(dentry);
 	filp->f_uid    = current->fsuid;
 	filp->f_gid    = current->fsgid;
 	filp->f_op     = dentry->d_inode->i_op->default_file_ops;
-	if (filp->f_op->open)
-		return filp->f_op->open(dentry->d_inode, filp);
-	else
+	if (filp->f_op->open) {
+		err = filp->f_op->open(dentry->d_inode, filp);
+                if (err)
+                    dput(dentry);
+		return err;
+        } else
 		return 0;
 }
 
fs/nfsd/nfsfh.c +1 -0
diff -Naur linux.clean.2.2.14/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
@@ -396,6 +396,7 @@
 out_close:
 	if (file.f_op->release)
 		file.f_op->release(dir, &file);
+        dput(file.f_dentry);
 out:
 	return error;
 }
mm/mmap.c +8 -2
diff -Naur linux.clean.2.2.14/mm/mmap.c linux/mm/mmap.c
@@ -321,8 +321,14 @@
 			file->f_dentry->d_inode->i_writecount++;
 		if (error)
 			goto unmap_and_free_vma;
-		vma->vm_file = file;
-		file->f_count++;
+                if (vma->vm_file == NULL) {
+                    /*
+                     * underlying FS may have attached it differently--only
+                     * attach it if they didn't.
+                     */
+                    vma->vm_file = file;
+                    file->f_count++;
+                }
 	}
 
 	/*

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/