Whamcloud - gitweb
9cc7294724089f7fff4eec241b8035f32149ae59
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-export-64bit-name-hash.patch
1 Index: linux-stage/fs/ext3/dir.c
2 ===================================================================
3 --- linux-stage.orig/fs/ext3/dir.c      2011-04-19 01:39:47.000000000 +0800
4 +++ linux-stage/fs/ext3/dir.c   2011-04-19 01:44:19.000000000 +0800
5 @@ -237,22 +237,50 @@
6  }
7
8  #ifdef CONFIG_EXT3_INDEX
9 +static inline int is_32bit_api(void)
10 +{
11 +#ifdef HAVE_IS_COMPAT_TASK
12 +        return is_compat_task();
13 +#else
14 +        return (BITS_PER_LONG == 32);
15 +#endif
16 +}
17 +
18  /*
19   * These functions convert from the major/minor hash to an f_pos
20   * value.
21 - * 
22 - * Currently we only use major hash numer.  This is unfortunate, but
23 - * on 32-bit machines, the same VFS interface is used for lseek and
24 - * llseek, so if we use the 64 bit offset, then the 32-bit versions of
25 - * lseek/telldir/seekdir will blow out spectacularly, and from within
26 - * the ext2 low-level routine, we don't know if we're being called by
27 - * a 64-bit version of the system call or the 32-bit version of the
28 - * system call.  Worse yet, NFSv2 only allows for a 32-bit readdir
29 - * cookie.  Sigh.
30 + *
31 + * Up layer (OSD) should specify O_32BITHASH or O_64BITHASH explicitly.
32 + * On the other hand, we allow ldiskfs to be mounted directly on both 32-bit
33 + * and 64-bit nodes, under such case, neither O_32BITHASH nor O_64BITHASH is
34 + * specified.
35   */
36 -#define hash2pos(major, minor) (major >> 1)
37 -#define pos2maj_hash(pos)      ((pos << 1) & 0xffffffff)
38 -#define pos2min_hash(pos)      (0)
39 +static inline loff_t hash2pos(struct file *filp, __u32 major, __u32 minor)
40 +{
41 +       if ((filp->f_flags & O_32BITHASH) ||
42 +           (!(filp->f_flags & O_64BITHASH) && is_32bit_api()))
43 +               return (major >> 1);
44 +       else
45 +               return (((__u64)(major >> 1) << 32) | (__u64)minor);
46 +}
47 +
48 +static inline __u32 pos2maj_hash(struct file *filp, loff_t pos)
49 +{
50 +       if ((filp->f_flags & O_32BITHASH) ||
51 +           (!(filp->f_flags & O_64BITHASH) && is_32bit_api()))
52 +               return ((pos << 1) & 0xffffffff);
53 +       else
54 +               return (((pos >> 32) << 1) & 0xffffffff);
55 +}
56 +
57 +static inline __u32 pos2min_hash(struct file *filp, loff_t pos)
58 +{
59 +       if ((filp->f_flags & O_32BITHASH) ||
60 +           (!(filp->f_flags & O_64BITHASH) && is_32bit_api()))
61 +               return (0);
62 +       else
63 +               return (pos & 0xffffffff);
64 +}
65  
66  /*
67   * This structure holds the nodes of the red-black tree used to store
68 @@ -314,7 +342,7 @@
69  }
70  
71  
72 -static struct dir_private_info *create_dir_info(loff_t pos)
73 +static struct dir_private_info *create_dir_info(struct file* filp, loff_t pos)
74  {
75         struct dir_private_info *p;
76  
77 @@ -325,8 +353,8 @@
78         p->curr_node = NULL;
79         p->extra_fname = NULL;
80         p->last_pos = 0;
81 -       p->curr_hash = pos2maj_hash(pos);
82 -       p->curr_minor_hash = pos2min_hash(pos);
83 +       p->curr_hash = pos2maj_hash(filp, pos);
84 +       p->curr_minor_hash = pos2min_hash(filp, pos);
85         p->next_hash = 0;
86         return p;
87  }
88 @@ -422,7 +450,7 @@
89                 printk("call_filldir: called with null fname?!?\n");
90                 return 0;
91         }
92 -       curr_pos = hash2pos(fname->hash, fname->minor_hash);
93 +       curr_pos = hash2pos(filp, fname->hash, fname->minor_hash);
94         while (fname) {
95                 error = filldir(dirent, fname->name,
96                                 fname->name_len, curr_pos, 
97 @@ -447,7 +475,7 @@
98         int     ret;
99  
100         if (!info) {
101 -               info = create_dir_info(filp->f_pos);
102 +               info = create_dir_info(filp, filp->f_pos);
103                 if (!info)
104                         return -ENOMEM;
105                 filp->private_data = info;
106 @@ -461,8 +489,8 @@
107                 free_rb_tree_fname(&info->root);
108                 info->curr_node = NULL;
109                 info->extra_fname = NULL;
110 -               info->curr_hash = pos2maj_hash(filp->f_pos);
111 -               info->curr_minor_hash = pos2min_hash(filp->f_pos);
112 +               info->curr_hash = pos2maj_hash(filp, filp->f_pos);
113 +               info->curr_minor_hash = pos2min_hash(filp, filp->f_pos);
114         }
115  
116         /*
117 Index: linux-stage/include/linux/ext3_fs.h
118 ===================================================================
119 --- linux-stage.orig/include/linux/ext3_fs.h    2011-04-19 01:39:47.000000000 +0800
120 +++ linux-stage/include/linux/ext3_fs.h 2011-04-19 01:45:21.000000000 +0800
121 @@ -54,6 +54,14 @@
122  #define ext3_debug(f, a...)    do {} while (0)
123  #endif
124  
125 +#ifndef O_32BITHASH
126 +# define O_32BITHASH    0x10000000
127 +#endif
128 +
129 +#ifndef O_64BITHASH
130 +# define O_64BITHASH    0x20000000
131 +#endif
132 +
133  #define EXT3_MULTIBLOCK_ALLOCATOR      1
134
135  #define EXT3_MB_HINT_MERGE             1       /* prefer goal again. length */