Al, Linus, Ion and I ported our stacking templates to all versions up to 2.3.99-pre9. We've cut a new release, fistgen-0.0.3, available in http://www.cs.columbia.edu/~ezk/research/fist/. The following kernel patches are passive and are functionally identical to the patches we've submitted for -pre6. They are intended to make the Linux kernel more "stacking-friendly" so that my stacking templates can call VFS code directly rather than reproducing it. Here's what the patch below does: - dentry_open cannot be called as is from stackable templates because it computes the 'mode' variable internally. So we changed dentry_open such that it accepts a specific mode variable, separate from "flags". Then we assign the mode which was passed to dentry_open to f->f_mode. - we changed all 3 invocations of dentry_open to pass the correct mode information: o fs/exec.c:open_exec(), we pass FMODE_READ to the dentry_open call. o fs/open.c:filp_open(), we compute and pass the correct mode to pass to dentry_open based on the flags passed to filp_open. This makes the code in filp_open more clear, rather than distributing mode computations inside and outside various functions. o ipc/shm.c:sys_shmat(), we pass "prot" which is already computed in this function, further showing that computing the mode flags inside dentry_open isn't correct; it should be done by the caller of dentry_open(). - we clarified filp_open() by adding a new variable called open_flags, which is computed from the flags passed to filp_open. This is passed to the dentry_open call as the "mode" argument. - we moved the static inline function sync_page from filemap.c to mm.h so that it can be called from stackable file systems. In many ways this sync_page function is a "VFS" callable function that could be called by other file systems. Comments are welcome. Let me know if you have any concerns about this patch, and we can work on it some more. Thanks, Erez. ############################################################################## diff -ruN linux-2.3.99-pre9-vanilla/fs/exec.c linux-2.3.99-pre9-fist/fs/exec.c --- linux-2.3.99-pre9-vanilla/fs/exec.c Sun May 21 14:38:47 2000 +++ linux-2.3.99-pre9-fist/fs/exec.c Tue May 23 19:30:47 2000 @@ -334,7 +334,7 @@ file = ERR_PTR(err); if (!err) { lock_kernel(); - file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); + file = dentry_open(nd.dentry, nd.mnt, FMODE_READ, +O_RDONLY); unlock_kernel(); out: return file; diff -ruN linux-2.3.99-pre9-vanilla/fs/open.c linux-2.3.99-pre9-fist/fs/open.c --- linux-2.3.99-pre9-vanilla/fs/open.c Mon May 8 16:31:40 2000 +++ linux-2.3.99-pre9-fist/fs/open.c Tue May 23 19:30:47 2000 @@ -599,12 +599,12 @@ } /* - * Note that while the flag value (low two bits) for sys_open means: + * Note that while the flags value (low two bits) for sys_open means: * 00 - read-only * 01 - write-only * 10 - read-write * 11 - special - * it is changed into + * when it is copied into open_flags, it is changed into * 00 - no permissions needed * 01 - read-permission * 10 - write-permission @@ -614,23 +614,24 @@ */ struct file *filp_open(const char * filename, int flags, int mode) { - int namei_flags, error; + int namei_flags, open_flags, error; struct nameidata nd; namei_flags = flags; - if ((namei_flags+1) & O_ACCMODE) + open_flags = ((flags + 1) & O_ACCMODE); + if (open_flags) namei_flags++; if (namei_flags & O_TRUNC) namei_flags |= 2; error = open_namei(filename, namei_flags, mode, &nd); if (!error) - return dentry_open(nd.dentry, nd.mnt, flags); + return dentry_open(nd.dentry, nd.mnt, open_flags, flags); return ERR_PTR(error); } -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int mode, int +flags) { struct file * f; struct inode *inode; @@ -641,7 +642,7 @@ if (!f) goto cleanup_dentry; f->f_flags = flags; - f->f_mode = (flags+1) & O_ACCMODE; + f->f_mode = mode; inode = dentry->d_inode; if (f->f_mode & FMODE_WRITE) { error = get_write_access(inode); diff -ruN linux-2.3.99-pre9-vanilla/include/linux/fs.h linux-2.3.99-pre9-fist/include/linux/fs.h --- linux-2.3.99-pre9-vanilla/include/linux/fs.h Tue May 23 17:18:48 2000 +++ linux-2.3.99-pre9-fist/include/linux/fs.h Tue May 23 19:48:52 2000 @@ -858,7 +858,7 @@ extern void put_unused_fd(unsigned int); /* locked inside */ extern struct file *filp_open(const char *, int, int); -extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); +extern struct file * dentry_open(struct dentry *, struct vfsmount *, int, int); extern int filp_close(struct file *, fl_owner_t id); extern char * getname(const char *); #define __getname() ((char *) __get_free_page(GFP_KERNEL)) diff -ruN linux-2.3.99-pre9-vanilla/include/linux/mm.h linux-2.3.99-pre9-fist/include/linux/mm.h --- linux-2.3.99-pre9-vanilla/include/linux/mm.h Tue May 23 17:18:49 2000 +++ linux-2.3.99-pre9-fist/include/linux/mm.h Tue May 23 19:48:54 2000 @@ -546,6 +546,21 @@ #define vmlist_modify_lock(mm) vmlist_access_lock(mm) #define vmlist_modify_unlock(mm) vmlist_access_unlock(mm) +/* + * Common MM functions for inclusion in the VFS + * or in other stackable file systems. Some of these + * functions were in linux/mm/ C files. + * + */ +static inline int sync_page(struct page *page) +{ + struct address_space *mapping = page->mapping; + + if (mapping && mapping->a_ops && mapping->a_ops->sync_page) + return mapping->a_ops->sync_page(page); + return 0; +} + #endif /* __KERNEL__ */ #endif diff -ruN linux-2.3.99-pre9-vanilla/ipc/shm.c linux-2.3.99-pre9-fist/ipc/shm.c --- linux-2.3.99-pre9-vanilla/ipc/shm.c Sat May 20 13:55:30 2000 +++ linux-2.3.99-pre9-fist/ipc/shm.c Tue May 23 19:30:47 2000 @@ -1191,7 +1191,7 @@ err = permission(dentry->d_inode, acc_mode); if (err) goto bad_file1; - file = dentry_open(dentry, shm_fs_type.kern_mnt, o_flags); + file = dentry_open(dentry, shm_fs_type.kern_mnt, prot, o_flags); err = PTR_ERR(file); if (IS_ERR (file)) goto bad_file1; diff -ruN linux-2.3.99-pre9-vanilla/mm/filemap.c linux-2.3.99-pre9-fist/mm/filemap.c --- linux-2.3.99-pre9-vanilla/mm/filemap.c Mon May 22 12:50:55 2000 +++ linux-2.3.99-pre9-fist/mm/filemap.c Tue May 23 19:30:47 2000 @@ -78,15 +78,6 @@ atomic_dec(&page_cache_size); } -static inline int sync_page(struct page *page) -{ - struct address_space *mapping = page->mapping; - - if (mapping && mapping->a_ops && mapping->a_ops->sync_page) - return mapping->a_ops->sync_page(page); - return 0; -} - /* * Remove a page from the page cache and free it. Caller has to make * sure the page is locked and that nobody else uses it - or that usage