linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* 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).