All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rasmus Rohde <rohde-3mLe3WyXyAE@public.gmane.org>
To: nfs@lists.sourceforge.net
Subject: [NFS] [PATCH] Make UDF exportable
Date: Wed, 30 Jan 2008 21:53:24 +0100	[thread overview]
Message-ID: <1201726404.2976.8.camel@localhost.localdomain> (raw)

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


             reply	other threads:[~2008-01-30 20:54 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-30 20:53 Rasmus Rohde [this message]
     [not found] ` <1201726404.2976.8.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-02-05 10:29   ` [NFS] [PATCH] Make UDF exportable 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
     [not found]       ` <20080206180850.GD3475-pwKtmJkCtMINMLpHRKhSow@public.gmane.org>
2008-02-06 20:58         ` Rasmus Rohde
2008-02-06 20:58       ` Rasmus Rohde
2008-02-07  3:37         ` Christoph Hellwig
     [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: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
2008-04-29 14:33                   ` Christoph Hellwig
2008-04-30 15:41                     ` Jan Kara
2008-04-30 15:41                     ` Jan Kara
     [not found]                   ` <1202396577.18175.2.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-04-29 14:33                     ` Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1201726404.2976.8.camel@localhost.localdomain \
    --to=rohde-3mle3wyxyae@public.gmane.org \
    --cc=nfs@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.