All of lore.kernel.org
 help / color / mirror / Atom feed
* [NFS] [PATCH] Make UDF exportable
@ 2008-01-30 20:53 Rasmus Rohde
       [not found] ` <1201726404.2976.8.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
  2008-02-05 10:29 ` Christoph Hellwig
  0 siblings, 2 replies; 25+ messages in thread
From: Rasmus Rohde @ 2008-01-30 20:53 UTC (permalink / raw)
  To: nfs

I've cooked together a patch for making UDF exportable.

It is based on the code found in ISO fs. Since I am far from an expert
in this area bugs may be present.

--- fs/udf/namei.c.orig	2007-10-10 16:22:30.000000000 +0200
+++ fs/udf/namei.c	2008-01-30 21:39:00.000000000 +0100
@@ -31,6 +31,7 @@
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/sched.h>
+#include <linux/exportfs.h>
 
 static inline int udf_match(int len1, const char *name1, int len2,
 			    const char *name2)
@@ -315,9 +316,8 @@ static struct dentry *udf_lookup(struct 
 		}
 	}
 	unlock_kernel();
-	d_add(dentry, inode);
 
-	return NULL;
+	return d_splice_alias(inode, dentry);
 }
 
 static struct fileIdentDesc *udf_add_entry(struct inode *dir,
@@ -1231,6 +1231,151 @@ end_rename:
 	return retval;
 }
 
+static struct dentry *udf_export_get_parent(struct dentry *child)
+{
+	struct dentry *parent;
+	struct inode *inode = NULL;
+	struct dentry dotdot;
+	struct fileIdentDesc cfi;
+	struct udf_fileident_bh fibh;
+
+	dotdot.d_name.name = "..";
+	dotdot.d_name.len = 2;
+
+	lock_kernel();
+	if (udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) {
+		if (fibh.sbh != fibh.ebh)
+			brelse(fibh.ebh);
+		brelse(fibh.sbh);
+		
+		inode = udf_iget(child->d_inode->i_sb,
+				 lelb_to_cpu(cfi.icb.extLocation));
+		if (!inode) {
+			unlock_kernel();
+			return ERR_PTR(-EACCES);
+		}
+	} else {
+		unlock_kernel();
+		return ERR_PTR(-EACCES);
+	}
+	unlock_kernel();
+
+	parent = d_alloc_anon(inode);
+	if (!parent) {
+		iput(inode);
+		parent = ERR_PTR(-ENOMEM);
+	}
+
+	return parent;
+}
+
+
+static struct dentry *
+udf_export_iget(struct super_block *sb, u32 block,
+		u16 offset, __u32 generation)
+{
+	struct inode *inode;
+	struct dentry *result;
+	kernel_lb_addr loc;
+
+	if (block == 0)
+		return ERR_PTR(-ESTALE);
+
+	loc.logicalBlockNum = block;
+	loc.partitionReferenceNum = offset;
+	inode = udf_iget(sb, loc);
+
+	if (inode == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	if (is_bad_inode(inode)
+	    || (generation && inode->i_generation != generation))
+	{
+		iput(inode);
+		return ERR_PTR(-ESTALE);
+	}
+	result = d_alloc_anon(inode);
+	if (!result) {
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	}
+	return result;
+}
+
+
+struct udf_fid {
+	u32 block;
+	u16 partref;
+	u16 parent_partref;
+	u32 generation;
+	u32 parent_block;
+	u32 parent_generation;
+};
+
+static struct dentry *udf_fh_to_dentry(struct super_block *sb,
+	struct fid *fid, int fh_len, int fh_type)
+{
+	struct udf_fid *ufid = (struct udf_fid *)fid;
+
+	if (fh_len < 3 || fh_type > 2)
+		return NULL;
+
+	return udf_export_iget(sb, ufid->block, ufid->partref,
+			ufid->generation);
+}
+
+static struct dentry *udf_fh_to_parent(struct super_block *sb,
+		struct fid *fid, int fh_len, int fh_type)
+{
+	struct udf_fid *ufid = (struct udf_fid *)fid;
+
+	if (fh_type != 2)
+		return NULL;
+
+	return udf_export_iget(sb,
+			fh_len > 2 ? ufid->parent_block : 0,
+			ufid->parent_partref,
+			fh_len > 4 ? ufid->parent_generation : 0);
+}
+static int
+udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
+{
+	int len = *lenp;
+	struct inode *inode =  de->d_inode;
+	kernel_lb_addr location = UDF_I_LOCATION(inode);
+	struct udf_fid *ufid = (struct udf_fid *)fh;
+	int type = 1;
+
+	if (len < 3 || (connectable && len < 5))
+		return 255;
+
+	*lenp = 3;
+	ufid->block = location.logicalBlockNum;
+	ufid->partref = location.partitionReferenceNum;
+	ufid->generation = inode->i_generation;
+
+	if (connectable && !S_ISDIR(inode->i_mode)) {
+		spin_lock(&de->d_lock);
+		inode = de->d_parent->d_inode;
+		location = UDF_I_LOCATION(inode);
+		ufid->parent_block = location.logicalBlockNum;
+		ufid->parent_partref = location.partitionReferenceNum;	
+		ufid->parent_generation = inode->i_generation;
+		spin_unlock(&de->d_lock);
+		*lenp = 5;
+		type = 2;
+	}
+
+	return type;
+}
+
+struct export_operations udf_export_ops = {
+	.encode_fh	= udf_encode_fh,
+	.fh_to_dentry   = udf_fh_to_dentry,
+	.fh_to_parent   = udf_fh_to_parent,
+	.get_parent     = udf_export_get_parent,
+};
+
 const struct inode_operations udf_dir_inode_operations = {
 	.lookup				= udf_lookup,
 	.create				= udf_create,

--- fs/udf/super.c.orig	2008-01-30 17:57:23.000000000 +0100
+++ fs/udf/super.c	2008-01-30 21:38:10.000000000 +0100
@@ -71,7 +71,7 @@
 #define VDS_POS_LENGTH			7
 
 static char error_buf[1024];
-
+extern struct export_operations udf_export_ops;
 /* These are the "meat" - everything else is stuffing */
 static int udf_fill_super(struct super_block *, void *, int);
 static void udf_put_super(struct super_block *);
@@ -1490,6 +1490,7 @@ static int udf_fill_super(struct super_b
 
 	/* Fill in the rest of the superblock */
 	sb->s_op = &udf_sb_ops;
+	sb->s_export_op = &udf_export_ops;
 	sb->dq_op = NULL;
 	sb->s_dirt = 0;
 	sb->s_magic = UDF_SUPER_MAGIC;



-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
_______________________________________________
Please note that nfs@lists.sourceforge.net is being discontinued.
Please subscribe to linux-nfs@vger.kernel.org instead.
    http://vger.kernel.org/vger-lists.html#linux-nfs


^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2008-04-30 15:42 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-30 20:53 [NFS] [PATCH] Make UDF exportable Rasmus Rohde
     [not found] ` <1201726404.2976.8.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-02-05 10:29   ` Christoph Hellwig
2008-02-05 10:29 ` Christoph Hellwig
2008-02-05 17:44   ` Rasmus Rohde
2008-02-05 19:26     ` Rasmus Rohde
     [not found]     ` <1202233464.12188.43.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-02-05 19:26       ` Rasmus Rohde
2008-02-06 18:08     ` Jan Kara
2008-02-06 20:58       ` Rasmus Rohde
     [not found]         ` <1202331482.2727.8.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-02-07  3:37           ` Christoph Hellwig
2008-02-07  5:45           ` Christoph Hellwig
2008-02-07  3:37         ` Christoph Hellwig
2008-02-07  3:44         ` Neil Brown
2008-02-07  3:44         ` Neil Brown
2008-02-07  5:45         ` Christoph Hellwig
2008-02-07  7:06           ` Rasmus Rohde
2008-02-07  7:06           ` Rasmus Rohde
2008-02-07 14:48             ` Jan Kara
     [not found]               ` <20080207144859.GJ6140-pwKtmJkCtMINMLpHRKhSow@public.gmane.org>
2008-02-07 15:02                 ` Rasmus Rohde
2008-02-07 15:02                   ` Rasmus Rohde
2008-02-07 15:13                   ` Jan Kara
     [not found]                   ` <1202396577.18175.2.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-04-29 14:33                     ` Christoph Hellwig
2008-04-29 14:33                   ` Christoph Hellwig
2008-04-30 15:41                     ` Jan Kara
2008-04-30 15:41                     ` Jan Kara
     [not found]       ` <20080206180850.GD3475-pwKtmJkCtMINMLpHRKhSow@public.gmane.org>
2008-02-06 20:58         ` Rasmus Rohde

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.