Hi,

> Signed-off-by: Rasmus Rohde <[EMAIL PROTECTED]>
  Interesting character before Signed-off-by :).

> --- 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;
  Have you ever tried this? I think this could never work. UDF doesn't have
entry named .. in a directory. You have to search for an entry that has
in fileCharacteristics set bit FID_FILE_CHAR_PARENT. Maybe you could
hack-around udf_find_entry() to recognize .. dentry and do the search
accordingly.

> +     
> +     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];
>       };
>  };
  Otherwise the patch looks fine. But please rediff the patch against
Andrew's development tree (or -mm) because there are some cleanups there...
Thanks.

                                                                        Honza
-- 
Jan Kara <[EMAIL PROTECTED]>
SUSE Labs, CR
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to