From: Rasmus Rohde <rohde@duff.dk>
To: Christoph Hellwig <hch@infradead.org>
Cc: nfs@lists.sourceforge.net, jack@suse.cz, linux-fsdevel@vger.kernel.org
Subject: Re: [NFS] [PATCH] Make UDF exportable
Date: Tue, 05 Feb 2008 18:44:24 +0100 [thread overview]
Message-ID: <1202233464.12188.43.camel@localhost.localdomain> (raw)
In-Reply-To: <20080205102955.GA28347@infradead.org>
> > +static struct dentry *udf_export_get_parent(struct dentry *child)
> Any reason this is not called udf_get_parent to follow the scheme
> in most filesystems?
Well - in isofs it was named isofs_export_get_parent, so I tried to stay consistent with that.
> > + 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();
>
> This if/else block looks little odd, and following the locking is a bit
> hard. What about doing it like the following:
Most of the code is copied from udf_lookup(..)
To me the locking is simple. Before the two returns you have an unlock.
It's pretty clear that all control-paths are covered. However changing
to your scheme is fine with me if you find it more readable.
> > +static struct dentry *
> > +udf_export_iget(struct super_block *sb, u32 block,
> > + u16 offset, __u32 generation)
> to follow other filesystems this should be called
> udf_nfs_get_inode. Also please decide if you want to put the static
> and return type on the same line or on a separate one. Having it on
> the same one is documented in Documentation/Codingstyle but separate
> ones are acceptable aswell. Just make sure to stick to either one :)
Again - this was just copied from isofs.
> > +{
> > + 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))
> > + {
> it would be better to introduce a version of udf_iget that can check
> the generation and return an error instead of having to check this
> later. If you don't think you're up to modifying code we could do
> this later on, though. In this case please note this in the patch
> description and fix up the above formatting to read something like:
>
> if (is_bad_inode(inode) ||
> (generation && inode->i_generation != generation)) {
is_bad_inode(..) is actually already checked so I'll just remove that.
> > +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;
>
> It would be useful if you could add symbolic constants for the
> two fh types you add and chose values not yet used by other filesystems,
> e.g. 0x51 and 0x52. This will help people sniffing the nfs on the
> wire protocol to understand what file handle they're dealing with.
Hehe - need I say isofs? :)
> Also you migh want to make the fh_len check more explicit and check
> that it's either 3 or 5 which is the only fhs you actually generate.
Sounds reasonable including the other length-checks you mention.
> Also it would be nice if you could add your fid type to the union in
> include/linux/exportfs.h and use the union member. The symbolic names
> for the FH types should go into enum fid_type with a short comment
> describing them.
Ok.
Attached is a new attempt at a patch.
Signed-off-by: Rasmus Rohde <rohde@duff.dk>
--- fs/udf/namei.c.orig 2007-10-10 16:22:30.000000000 +0200
+++ fs/udf/namei.c 2008-02-05 18:28:13.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,135 @@ end_rename:
return retval;
}
+static struct dentry *udf_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))
+ goto out_unlock;
+
+ 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)
+ goto out_unlock;
+ unlock_kernel();
+
+ parent = d_alloc_anon(inode);
+ if (!parent) {
+ iput(inode);
+ parent = ERR_PTR(-ENOMEM);
+ }
+
+ return parent;
+out_unlock:
+ unlock_kernel();
+ return ERR_PTR(-EACCES);
+}
+
+
+static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
+ u16 partref, __u32 generation)
+{
+ struct inode *inode;
+ struct dentry *result;
+ kernel_lb_addr loc;
+
+ if (block == 0)
+ return ERR_PTR(-ESTALE);
+
+ loc.logicalBlockNum = block;
+ loc.partitionReferenceNum = partref;
+ inode = udf_iget(sb, loc);
+
+ if (inode == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ if (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;
+}
+
+static struct dentry *udf_fh_to_dentry(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type)
+{
+ if ((fh_len != 3 && fh_len != 5) ||
+ (fh_type != FILEID_UDF_WITH_PARENT &&
+ fh_type != FILEID_UDF_WITHOUT_PARENT))
+ return NULL;
+
+ return udf_nfs_get_inode(sb, fid->udf.block, fid->udf.partref,
+ fid->udf.generation);
+}
+
+static struct dentry *udf_fh_to_parent(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type)
+{
+ if (fh_len != 5 || fh_type != FILEID_UDF_WITHOUT_PARENT)
+ return NULL;
+
+ return udf_nfs_get_inode(sb, fid->udf.parent_block,
+ fid->udf.parent_partref,
+ fid->udf.parent_generation);
+}
+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 fid *fid = (struct fid *)fh;
+ int type = FILEID_UDF_WITHOUT_PARENT;
+
+ if (len < 3 || (connectable && len < 5))
+ return 255;
+
+ *lenp = 3;
+ fid->udf.block = location.logicalBlockNum;
+ fid->udf.partref = location.partitionReferenceNum;
+ fid->udf.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);
+ fid->udf.parent_block = location.logicalBlockNum;
+ fid->udf.parent_partref = location.partitionReferenceNum;
+ fid->udf.parent_generation = inode->i_generation;
+ spin_unlock(&de->d_lock);
+ *lenp = 5;
+ type = FILEID_UDF_WITH_PARENT;
+ }
+
+ 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_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;
--- include/linux/exportfs.h.orig 2008-02-05 18:28:44.000000000 +0100
+++ include/linux/exportfs.h 2008-02-05 18:28:51.000000000 +0100
@@ -33,6 +33,19 @@ enum fid_type {
* 32 bit parent directory inode number.
*/
FILEID_INO32_GEN_PARENT = 2,
+
+ /*
+ * 32 bit block number, 16 bit partition reference,
+ * 16 bit unused, 32 bit generation number.
+ */
+ FILEID_UDF_WITHOUT_PARENT = 0x51,
+
+ /*
+ * 32 bit block number, 16 bit partition reference,
+ * 16 bit unused, 32 bit generation number,
+ * 32 bit parent block number, 32 bit parent generation number
+ */
+ FILEID_UDF_WITH_PARENT = 0x52,
};
struct fid {
@@ -43,6 +56,14 @@ struct fid {
u32 parent_ino;
u32 parent_gen;
} i32;
+ struct {
+ u32 block;
+ u16 partref;
+ u16 parent_partref;
+ u32 generation;
+ u32 parent_block;
+ u32 parent_generation;
+ } udf;
__u32 raw[6];
};
};
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2008-02-05 18:23 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
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
[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
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=1202233464.12188.43.camel@localhost.localdomain \
--to=rohde@duff.dk \
--cc=hch@infradead.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.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.