* is there a way to export a fat32 file system using nfs? @ 2001-06-13 1:52 John Covici 2001-06-13 3:00 ` Neil Brown 0 siblings, 1 reply; 5+ messages in thread From: John Covici @ 2001-06-13 1:52 UTC (permalink / raw) To: linux-kernel Hi. I seem to remember that at one time in the 2.2 series I was able to to export fat32 file systems using nfs, but now it doesn't work anymore. If I remember correctly, I get "get: operation not permitted" when trying to export the directory in question. I am using 2.4.5. Any assistance would be appreciated. -- John Covici covici@ccs.covici.com ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: is there a way to export a fat32 file system using nfs? 2001-06-13 1:52 is there a way to export a fat32 file system using nfs? John Covici @ 2001-06-13 3:00 ` Neil Brown 2001-06-13 3:09 ` Alexander Viro 0 siblings, 1 reply; 5+ messages in thread From: Neil Brown @ 2001-06-13 3:00 UTC (permalink / raw) To: John Covici; +Cc: linux-kernel On Tuesday June 12, covici@ccs.covici.com wrote: > Hi. I seem to remember that at one time in the 2.2 series I was able > to to export fat32 file systems using nfs, but now it doesn't work > anymore. No, it doesn't. It did in early 2.2 due to some fairly ugly hacks which just had to go. They worked in a lot of simple cases, but it wouldn't be too difficult to confuse such a server so that it would start losing files. It would be possible to add to 2.4.5, but not easy. The basic problem is that you cannot create a reliable NFS filehandle for a file in a FAT filesystem as there are no inode numbers or anything similar. What might work would be: In fat_fill_inode, set i_generation to the current time. When creating a filehandle, store: i_ino i_generation i_location i_logstart When when asked to lookup a filehandle: Call find_inode(i_ino). If this finds something check i_generation. If it matches, SUCCESS. Call fat_iget(i_location). If this finds something, check i_logstart. If it matches, assume SUCCESS. Then comes the tricky bit: read the directory entry indicated by i_location, check the i_logstart is right, if it is, try to get it into the inode cache properly. It is something that I would like to do, but I have lots of other things that I want to do at the moment. NeilBrown > > If I remember correctly, I get "get: operation not permitted" when > trying to export the directory in question. > > I am using 2.4.5. > > Any assistance would be appreciated. > > -- > John Covici > covici@ccs.covici.com > > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: is there a way to export a fat32 file system using nfs? 2001-06-13 3:00 ` Neil Brown @ 2001-06-13 3:09 ` Alexander Viro 2001-06-13 3:41 ` Neil Brown 0 siblings, 1 reply; 5+ messages in thread From: Alexander Viro @ 2001-06-13 3:09 UTC (permalink / raw) To: Neil Brown; +Cc: John Covici, linux-kernel On Wed, 13 Jun 2001, Neil Brown wrote: > Call fat_iget(i_location). > If this finds something, check i_logstart. > If it matches, assume SUCCESS. > > Then comes the tricky bit: read the directory entry > indicated by i_location, check the i_logstart is right, > if it is, try to get it into the inode cache properly. Uh-huh. Suppose that directory had been removed and space had been reused by a regular file. Which had been filled with the right contents. It's really not hard to do. Now, remove that file and you've got a nice data corruption waiting to happen. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: is there a way to export a fat32 file system using nfs? 2001-06-13 3:09 ` Alexander Viro @ 2001-06-13 3:41 ` Neil Brown 2001-06-15 1:43 ` is there a way to export a fat32 file system using nfs? - YES! Neil Brown 0 siblings, 1 reply; 5+ messages in thread From: Neil Brown @ 2001-06-13 3:41 UTC (permalink / raw) To: Alexander Viro; +Cc: John Covici, linux-kernel On Tuesday June 12, viro@math.psu.edu wrote: > > > On Wed, 13 Jun 2001, Neil Brown wrote: > > > Call fat_iget(i_location). > > If this finds something, check i_logstart. > > If it matches, assume SUCCESS. > > > > Then comes the tricky bit: read the directory entry > > indicated by i_location, check the i_logstart is right, > > if it is, try to get it into the inode cache properly. > > Uh-huh. Suppose that directory had been removed and space had been > reused by a regular file. Which had been filled with the right > contents. It's really not hard to do. Now, remove that file and > you've got a nice data corruption waiting to happen. Told you it was tricky!! Let's see now... We could also store the disc address of the start of the directory in the filehandle. Then we examine the FAT to see if the file starting at that block looks like a directory, and contains the target directory entry. If it does, we extract the ".." entry (do FAT directories have and analogue of ".." entries?) and keep going up the tree until we find the root, or we have tried too hard. Once we hit the root we will have collected a full path name for the file, so we just do lots of lookups to get it into the caches. Ugh. I might just do that first step (find_ino) and offer it as as an experimental patch to the growing number of people who have asked for nfs exporting of FAT filesystems, and see how reliable it is in practice. NeilBrown ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: is there a way to export a fat32 file system using nfs? - YES! 2001-06-13 3:41 ` Neil Brown @ 2001-06-15 1:43 ` Neil Brown 0 siblings, 0 replies; 5+ messages in thread From: Neil Brown @ 2001-06-15 1:43 UTC (permalink / raw) To: John Covici, Knuth Posern, Bob Sully, madhu Cc: Alexander Viro, linux-kernel, nfs On Wednesday June 13, neilb@cse.unsw.edu.au wrote: > > I might just do that first step (find_ino) and offer it as as an > experimental patch to the growing number of people who have asked for > nfs exporting of FAT filesystems, and see how reliable it is in > practice. Following is a patch against 2.4.6-pre3 which allows FAT (msdos or VFAT) filesystems to be exported via NFS in Linux. It should work reasonable well for simple accesses if the server doesn't suffer too much memory pressure. If the server reboots, if you hold a file open for extended periods without much activity, or if the server needs to flush inodes due to memory pressure, you will probably loose. I would be interested to hear of how well it goes for anyone who needs to use it. If I get enough favourable response, I might submit it to Linus. It is also available at: http://www.cse.unsw.edu.au/~neilb/patches/linux/2.4.6-pre3/patch-C-fatnfs NeilBrown --- ./fs/fat/inode.c 2001/06/13 23:07:25 1.1 +++ ./fs/fat/inode.c 2001/06/15 01:29:22 1.2 @@ -154,15 +154,19 @@ void fat_delete_inode(struct inode *inode) { - lock_kernel(); - inode->i_size = 0; - fat_truncate(inode); - unlock_kernel(); + if (!is_bad_inode(inode)) { + lock_kernel(); + inode->i_size = 0; + fat_truncate(inode); + unlock_kernel(); + } clear_inode(inode); } void fat_clear_inode(struct inode *inode) { + if (is_bad_inode(inode)) + return; lock_kernel(); spin_lock(&fat_inode_lock); fat_cache_inval_inode(inode); @@ -372,6 +376,7 @@ inode->i_uid = sbi->options.fs_uid; inode->i_gid = sbi->options.fs_gid; inode->i_version = ++event; + inode->i_generation = 0; inode->i_mode = (S_IRWXUGO & ~sbi->options.fs_umask) | S_IFDIR; inode->i_op = sbi->dir_ops; inode->i_fop = &fat_dir_operations; @@ -403,12 +408,123 @@ inode->i_nlink = fat_subdirs(inode)+2; } +/* + * a FAT file handle with fhtype 3 is + * 0/ i_ino - for fast, reliable lookup if still in the cache + * 1/ i_generation - to see if i_ino is still valid + * bit 0 == 0 iff directory + * 2/ i_location - if ino has changed, but still in cache + * 3/ i_logstart - to semi-verify inode found at i_location + * 4/ parent->i_logstart - maybe used to hunt for the file on disc + * + */ +struct dentry *fat_fh_to_dentry(struct super_block *sb, __u32 *fh, + int len, int fhtype, int parent) +{ + struct inode *inode = NULL; + struct list_head *lp; + struct dentry *result; + + if (fhtype != 3) + return NULL; + if (len < 5) + return NULL; + if (parent) + return NULL; /* We cannot find the parent, + It better just *be* there */ + + inode = iget(sb, fh[0]); + if (!inode || is_bad_inode(inode) || + inode->i_generation != fh[1]) { + if (inode) iput(inode); + inode = NULL; + } + if (!inode) { + /* try 2 - see if i_location is in F-d-c + * require i_logstart to be the same + * Will fail if you truncate and then re-write + */ + + inode = fat_iget(sb, fh[2]); + if (inode && MSDOS_I(inode)->i_logstart != fh[3]) { + iput(inode); + inode = NULL; + } + } + if (!inode) { + /* For now, do nothing + * What we could do is: + * follow the file starting at fh[4], and record + * the ".." entry, and the name of the fh[2] entry. + * The follow the ".." file finding the next step up. + * This way we build a path to the root of + * the tree. If this works, we lookup the path and so + * get this inode into the cache. + * Finally try the fat_iget lookup again + * If that fails, then weare totally out of luck + * But all that is for another day + */ + } + if (!inode) + return ERR_PTR(-ESTALE); + + + /* now to find a dentry. + * If possible, get a well-connected one + * + * Given the way that we found the inode, it *MUST* be + * well-connected, but it is easiest to just copy the + * code. + */ + spin_lock(&dcache_lock); + for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) { + result = list_entry(lp,struct dentry, d_alias); + if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) { + dget_locked(result); + result->d_vfs_flags |= DCACHE_REFERENCED; + spin_unlock(&dcache_lock); + iput(inode); + return result; + } + } + spin_unlock(&dcache_lock); + result = d_alloc_root(inode); + if (result == NULL) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + result->d_flags |= DCACHE_NFSD_DISCONNECTED; + return result; + + +} + +int fat_dentry_to_fh(struct dentry *de, __u32 *fh, int *lenp, int needparent) +{ + int len = *lenp; + struct inode *inode = de->d_inode; + + if (len < 5) + return 255; /* no room */ + *lenp = 5; + fh[0] = inode->i_ino; + fh[1] = inode->i_generation; + fh[2] = MSDOS_I(inode)->i_location; + fh[3] = MSDOS_I(inode)->i_logstart; + fh[4] = MSDOS_I(de->d_parent->d_inode)->i_logstart; + return 3; +} + static struct super_operations fat_sops = { write_inode: fat_write_inode, delete_inode: fat_delete_inode, put_super: fat_put_super, statfs: fat_statfs, clear_inode: fat_clear_inode, + + read_inode: make_bad_inode, + fh_to_dentry: fat_fh_to_dentry, + dentry_to_fh: fat_dentry_to_fh, }; /* @@ -771,7 +887,10 @@ inode->i_uid = sbi->options.fs_uid; inode->i_gid = sbi->options.fs_gid; inode->i_version = ++event; + inode->i_generation = CURRENT_TIME; + if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) { + inode->i_generation &= ~1; inode->i_mode = MSDOS_MKMODE(de->attr,S_IRWXUGO & ~sbi->options.fs_umask) | S_IFDIR; inode->i_op = sbi->dir_ops; @@ -802,6 +921,7 @@ } MSDOS_I(inode)->mmu_private = inode->i_size; } else { /* not a directory */ + inode->i_generation |= 1; inode->i_mode = MSDOS_MKMODE(de->attr, ((IS_NOEXEC(inode) || (sbi->options.showexec && ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2001-06-15 1:44 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2001-06-13 1:52 is there a way to export a fat32 file system using nfs? John Covici 2001-06-13 3:00 ` Neil Brown 2001-06-13 3:09 ` Alexander Viro 2001-06-13 3:41 ` Neil Brown 2001-06-15 1:43 ` is there a way to export a fat32 file system using nfs? - YES! Neil Brown
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).