On Tue 29-04-08 10:33:31, Christoph Hellwig wrote:
quoted text > On Thu, Feb 07, 2008 at 04:02:57PM +0100, Rasmus Rohde wrote:
> >
> > > > Before posting the last and hopefully final patch I'd like to know what
> > > > Jan says about open coding the lookup for ..
> > > > It will mean a lot of code duplication and I think it makes good sense
> > > > for udf_find_entry to be able to handle ..
> > > Yes, I think opencoding it would really lead to larger code duplication
> > > than I'd like so please keep the change in udf_find_entry(). Thanks.
> > Great - then I think we are hopefully at a patch that can be accepted.
>
> Jan, any reason this patch didn't go in with the last merge? I'd really
> like to see it in .26.
Thanks for catching this. It seems I missed the patch when merging all
the UDF patches I had in my mailbox. I have it merged in my git tree and
will push it to Linus with other patches.
Honza
quoted text >
> >
> > Signed-off-by: Rasmus Rohde <rohde@duff.dk>
> >
> > diff -uprN -X linux-2.6.24-mm1-vanilla/Documentation/dontdiff linux-2.6.24-mm1-vanilla/fs/udf/namei.c linux-2.6.24-mm1/fs/udf/namei.c
> > --- linux-2.6.24-mm1-vanilla/fs/udf/namei.c 2008-02-06 21:23:36.000000000 +0100
> > +++ linux-2.6.24-mm1/fs/udf/namei.c 2008-02-07 07:13:04.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)
> > @@ -159,6 +160,8 @@ static struct fileIdentDesc *udf_find_en
> > sector_t offset;
> > struct extent_position epos = {};
> > struct udf_inode_info *dinfo = UDF_I(dir);
> > + int isdotdot = dentry->d_name.len == 2 &&
> > + dentry->d_name.name[0] == '.' && dentry->d_name.name[1] == '.';
> >
> > size = udf_ext0_offset(dir) + dir->i_size;
> > f_pos = udf_ext0_offset(dir);
> > @@ -232,6 +235,12 @@ static struct fileIdentDesc *udf_find_en
> > continue;
> > }
> >
> > + if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) &&
> > + isdotdot) {
> > + brelse(epos.bh);
> > + return fi;
> > + }
> > +
> > if (!lfi)
> > continue;
> >
> > @@ -324,9 +333,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,
> > @@ -1298,6 +1306,134 @@ 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_WITH_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(inode)->i_location;
> > + 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(inode)->i_location;
> > + 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;
> > +}
> > +
> > +const 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,
> > diff -uprN -X linux-2.6.24-mm1-vanilla/Documentation/dontdiff linux-2.6.24-mm1-vanilla/fs/udf/super.c linux-2.6.24-mm1/fs/udf/super.c
> > --- linux-2.6.24-mm1-vanilla/fs/udf/super.c 2008-02-06 21:23:36.000000000 +0100
> > +++ linux-2.6.24-mm1/fs/udf/super.c 2008-02-07 07:06:30.000000000 +0100
> > @@ -1801,6 +1801,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;
> > diff -uprN -X linux-2.6.24-mm1-vanilla/Documentation/dontdiff linux-2.6.24-mm1-vanilla/fs/udf/udfdecl.h linux-2.6.24-mm1/fs/udf/udfdecl.h
> > --- linux-2.6.24-mm1-vanilla/fs/udf/udfdecl.h 2008-02-06 21:23:36.000000000 +0100
> > +++ linux-2.6.24-mm1/fs/udf/udfdecl.h 2008-02-07 07:11:24.000000000 +0100
> > @@ -45,6 +45,7 @@ struct task_struct;
> > struct buffer_head;
> > struct super_block;
> >
> > +extern const struct export_operations udf_export_ops;
> > extern const struct inode_operations udf_dir_inode_operations;
> > extern const struct file_operations udf_dir_operations;
> > extern const struct inode_operations udf_file_inode_operations;
> > diff -uprN -X linux-2.6.24-mm1-vanilla/Documentation/dontdiff linux-2.6.24-mm1-vanilla/include/linux/exportfs.h linux-2.6.24-mm1/include/linux/exportfs.h
> > --- linux-2.6.24-mm1-vanilla/include/linux/exportfs.h 2008-02-06 21:23:46.000000000 +0100
> > +++ linux-2.6.24-mm1/include/linux/exportfs.h 2008-02-06 21:25:06.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];
> > };
> > };
> >
> >
> ---end quoted text---
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
--
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