* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
@ 2004-03-10 22:49 Rusty Lynch
2004-03-11 15:53 ` Rusty Lynch
0 siblings, 1 reply; 13+ messages in thread
From: Rusty Lynch @ 2004-03-10 22:49 UTC (permalink / raw)
To: ocfs2-devel
The following patch is safe for the 2.4 kernel, but still incomplete
for the 2.6 kernel. I am sending this just incase there is any feedback
on what I am doing (and to give Sonic and Xiaofeng a chance to figure this
out while I'm asleep.)
So... struct inode changed in 2.6 such that the union on the end of the
struct now only contains "void *generic_ip", and therefore only adds
on sizeof(void *) to the end of the structure. Our 2.6 code is still
attempting to read/write private data at the end of the inode struct,
and therefore writing past the end of the object.
The suggested new way of storing private data is to define a new
struct that contains your private data and has an inode imbedded inside.
Then the private data can be reached from an inode by doing a simple
container_of on the inode. This is possible by hooking into inode
allocation/deallocation via the alloc_inode/destroy_inode function
pointers in the super operations.
(See linux/Documentation/filesystems/port)
The following patch does this and also takes the liberty to convert the
macros for getting/setting private data into inline functions (mainly
because stared at OCFS_GENERIC_IP and friends for way to long before
I realized what they were actually doing, and why that was freezing my
2.6 build.)
All this sounds good except... now d_alloc_root() oops's when it attempts
to initialize which attempts to d_initialize() which eventually dereferences
a new pointer while initializing a list_head. I'm sure I missed a step
some place, but I'm spent for the night.
--rusty
Index: src/super.c
===================================================================
--- src/super.c (revision 769)
+++ src/super.c (working copy)
@@ -135,6 +135,8 @@
static void ocfs_free_mem_lists (void);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+static struct inode *ocfs_alloc_inode(struct super_block *sb);
+static void ocfs_destroy_inode(struct inode *inode);
static int ocfs_statfs (struct super_block *sb, struct kstatfs *buf);
#else
static int ocfs_statfs (struct super_block *sb, struct statfs *buf);
@@ -146,7 +148,10 @@
.clear_inode = ocfs_clear_inode,
//put_inode = force_delete,
//delete_inode = ocfs_delete_inode,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ .alloc_inode = ocfs_alloc_inode,
+ .destroy_inode = ocfs_destroy_inode,
+#else
.read_inode = ocfs_read_inode,
.read_inode2 = ocfs_read_inode2,
#endif
@@ -154,9 +159,24 @@
};
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+static struct inode *ocfs_alloc_inode(struct super_block *sb)
+{
+ struct ocfs_inode_info *i = (struct ocfs_inode_info *)kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
+ if (!i) {
+ LOG_ERROR_STR("unable to allocate inode");
+ return NULL;
+ }
+
+ return &(i->vfs_inode);
+}
+
+static void ocfs_destroy_inode(struct inode *inode)
+{
+ kmem_cache_free(OcfsGlobalCtxt.inode_cache, OCFS_I(inode));
+}
+
static int ocfs_fill_super (struct super_block *sb, void *data, int silent)
{
struct dentry *root_dentry;
@@ -788,6 +808,11 @@
*/
static int ocfs_initialize_mem_lists (void)
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ OcfsGlobalCtxt.inode_cache = kmem_cache_create ("ocfs2_inode",
+ sizeof (struct ocfs_inode_info) + OCFS_POINTER_SIZE, 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
+ NULL, NULL);
+#endif
OcfsGlobalCtxt.oin_cache = kmem_cache_create ("ocfs2_oin",
sizeof (ocfs_inode) + OCFS_POINTER_SIZE, 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
NULL, NULL);
@@ -826,6 +851,9 @@
*/
static void ocfs_free_mem_lists (void)
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ kmem_cache_destroy (OcfsGlobalCtxt.inode_cache);
+#endif
kmem_cache_destroy (OcfsGlobalCtxt.oin_cache);
kmem_cache_destroy (OcfsGlobalCtxt.ofile_cache);
kmem_cache_destroy (OcfsGlobalCtxt.fe_cache);
Index: src/inc/ocfs.h
===================================================================
--- src/inc/ocfs.h (revision 769)
+++ src/inc/ocfs.h (working copy)
@@ -227,8 +227,85 @@
#define ocfs_getpid() getpid()
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+struct ocfs_inode_info {
+ /* fs-private stuff */
+ void * generic_ip;
+ __u64 voteoff;
+ __u64 feoff;
+ atomic_t i_clean_buffer_seq;
+ __u8 deleted; /* this can be a generic flags field later */
+ struct inode vfs_inode;
+};
+static inline struct ocfs_inode_info *OCFS_I(struct inode *inode)
+{
+ return list_entry(inode, struct ocfs_inode_info, vfs_inode);
+}
+
+static inline atomic_t *GET_INODE_CLEAN_SEQ(struct inode *inode)
+{
+ return &(OCFS_I(inode)->i_clean_buffer_seq);
+}
+
+static inline int inode_data_is_oin(struct inode *inode)
+{
+ return (OCFS_I(inode)->generic_ip != NULL);
+}
+
+static inline __u8 INODE_DELETED(struct inode *inode)
+{
+ return OCFS_I(inode)->deleted;
+}
+
+static inline void SET_INODE_DELETED(struct inode *inode)
+{
+ OCFS_I(inode)->deleted = 1;
+}
+
+static inline void CLEAR_INODE_DELETED(struct inode *inode)
+{
+ OCFS_I(inode)->deleted = 0;
+}
+
+static inline void SET_INODE_VOTEOFF(struct inode *inode, __u64 voteoff)
+{
+ OCFS_I(inode)->voteoff = voteoff;
+}
+
+static inline __u64 GET_INODE_VOTEOFF(struct inode *inode)
+{
+ return OCFS_I(inode)->voteoff;
+}
+
+static inline void SET_INODE_FEOFF(struct inode *inode, __u64 feoff)
+{
+ OCFS_I(inode)->feoff = feoff;
+}
+
+static inline __u64 GET_INODE_FEOFF(struct inode *inode)
+{
+ return OCFS_I(inode)->feoff;
+}
+
+static inline void CLEAR_INODE_OIN(struct inode *inode)
+{
+ OCFS_I(inode)->generic_ip = (void *)NULL;
+}
+
+static inline void SET_INODE_OIN(struct inode *inode, void *oin)
+{
+ OCFS_I(inode)->generic_ip = oin;
+}
+
+static inline void *GET_INODE_OIN(struct inode *inode)
+{
+ return OCFS_I(inode)->generic_ip;
+}
+
+#else
+
typedef struct _ocfs_inode_private
{
void * generic_ip;
@@ -277,6 +354,8 @@
#define GET_INODE_OIN(i) ((ocfs_inode *)(OCFS_GENERIC_IP(i)->generic_ip))
+#endif /* 2.4.x kernel */
+
#define FIRST_FILE_ENTRY(dir) ((char *) ((char *)dir)+OCFS_SECTOR_SIZE)
#define FILEENT(dir,idx) (ocfs_file_entry *) ( ((char *)dir) + \
((dir->index[idx]+1) * OCFS_SECTOR_SIZE))
@@ -2059,6 +2138,7 @@
ocfs_obj_id obj_id;
ocfs_sem res;
struct list_head osb_next; /* List of all volumes */
+ kmem_cache_t *inode_cache;
kmem_cache_t *oin_cache;
kmem_cache_t *ofile_cache;
kmem_cache_t *fe_cache;
Index: src/namei.c
===================================================================
--- src/namei.c (revision 769)
+++ src/namei.c (working copy)
@@ -935,7 +935,7 @@
/* new parent dir offset */
if (inode_data_is_oin (new_dir))
- newDirOff = (GET_INODE_OIN(new_dir))->dir_disk_off;
+ newDirOff = ((ocfs_inode *)GET_INODE_OIN(new_dir))->dir_disk_off;
else
newDirOff = GET_INODE_VOTEOFF (new_dir);
^ permalink raw reply [flat|nested] 13+ messages in thread* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-10 22:49 [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data Rusty Lynch
@ 2004-03-11 15:53 ` Rusty Lynch
2004-03-12 14:47 ` Mark Fasheh
0 siblings, 1 reply; 13+ messages in thread
From: Rusty Lynch @ 2004-03-11 15:53 UTC (permalink / raw)
To: ocfs2-devel
On Wed, Mar 10, 2004 at 08:49:38PM -0800, Rusty Lynch wrote:
> The following patch is safe for the 2.4 kernel, but still incomplete
> for the 2.6 kernel. I am sending this just incase there is any feedback
> on what I am doing (and to give Sonic and Xiaofeng a chance to figure this
> out while I'm asleep.)
>
> So... struct inode changed in 2.6 such that the union on the end of the
> struct now only contains "void *generic_ip", and therefore only adds
> on sizeof(void *) to the end of the structure. Our 2.6 code is still
> attempting to read/write private data at the end of the inode struct,
> and therefore writing past the end of the object.
>
> The suggested new way of storing private data is to define a new
> struct that contains your private data and has an inode imbedded inside.
> Then the private data can be reached from an inode by doing a simple
> container_of on the inode. This is possible by hooking into inode
> allocation/deallocation via the alloc_inode/destroy_inode function
> pointers in the super operations.
>
> (See linux/Documentation/filesystems/port)
>
> The following patch does this and also takes the liberty to convert the
> macros for getting/setting private data into inline functions (mainly
> because stared at OCFS_GENERIC_IP and friends for way to long before
> I realized what they were actually doing, and why that was freezing my
> 2.6 build.)
>
> All this sounds good except... now d_alloc_root() oops's when it attempts
> to initialize which attempts to d_initialize() which eventually dereferences
> a new pointer while initializing a list_head. I'm sure I missed a step
> some place, but I'm spent for the night.
>
What I was missing was the initialization of the newly allocated inode via
the kmem_cache_create constructor function pointer. The following patch
applies cleanly against v770 of svn (latest greatest as of this email.)
I think this path is ready for the tree.
--rusty
Index: src/super.c
===================================================================
--- src/super.c (revision 770)
+++ src/super.c (working copy)
@@ -135,6 +135,8 @@
static void ocfs_free_mem_lists (void);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+static struct inode *ocfs_alloc_inode(struct super_block *sb);
+static void ocfs_destroy_inode(struct inode *inode);
static int ocfs_statfs (struct super_block *sb, struct kstatfs *buf);
#else
static int ocfs_statfs (struct super_block *sb, struct statfs *buf);
@@ -146,7 +148,10 @@
.clear_inode = ocfs_clear_inode,
//put_inode = force_delete,
//delete_inode = ocfs_delete_inode,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ .alloc_inode = ocfs_alloc_inode,
+ .destroy_inode = ocfs_destroy_inode,
+#else
.read_inode = ocfs_read_inode,
.read_inode2 = ocfs_read_inode2,
#endif
@@ -154,9 +159,24 @@
};
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+static struct inode *ocfs_alloc_inode(struct super_block *sb)
+{
+ struct ocfs_inode_info *i = (struct ocfs_inode_info *)kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
+ if (!i) {
+ LOG_ERROR_STR("unable to allocate inode");
+ return NULL;
+ }
+
+ return &(i->vfs_inode);
+}
+
+static void ocfs_destroy_inode(struct inode *inode)
+{
+ kmem_cache_free(OcfsGlobalCtxt.inode_cache, OCFS_I(inode));
+}
+
static int ocfs_fill_super (struct super_block *sb, void *data, int silent)
{
struct dentry *root_dentry;
@@ -782,12 +802,34 @@
}
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
+{
+ struct ocfs_inode_info *i = (struct ocfs_inode_info *) foo;
+
+ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+ SLAB_CTOR_CONSTRUCTOR) {
+ i->generic_ip = NULL;
+ i->voteoff = 0;
+ i->feoff = 0;
+ atomic_set(&i->i_clean_buffer_seq, 0);
+ inode_init_once(&i->vfs_inode);
+ }
+}
+#endif
+
/*
* ocfs_initialize_mem_lists()
*
*/
static int ocfs_initialize_mem_lists (void)
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ OcfsGlobalCtxt.inode_cache = kmem_cache_create ("ocfs2_inode",
+ sizeof (struct ocfs_inode_info), 0,
+ SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT,
+ init_once, NULL);
+#endif
OcfsGlobalCtxt.oin_cache = kmem_cache_create ("ocfs2_oin",
sizeof (ocfs_inode) + OCFS_POINTER_SIZE, 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
NULL, NULL);
@@ -826,6 +868,9 @@
*/
static void ocfs_free_mem_lists (void)
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ kmem_cache_destroy (OcfsGlobalCtxt.inode_cache);
+#endif
kmem_cache_destroy (OcfsGlobalCtxt.oin_cache);
kmem_cache_destroy (OcfsGlobalCtxt.ofile_cache);
kmem_cache_destroy (OcfsGlobalCtxt.fe_cache);
Index: src/inc/ocfs.h
===================================================================
--- src/inc/ocfs.h (revision 770)
+++ src/inc/ocfs.h (working copy)
@@ -227,8 +227,85 @@
#define ocfs_getpid() getpid()
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+struct ocfs_inode_info {
+ /* fs-private stuff */
+ void * generic_ip;
+ __u64 voteoff;
+ __u64 feoff;
+ atomic_t i_clean_buffer_seq;
+ __u8 deleted; /* this can be a generic flags field later */
+ struct inode vfs_inode;
+};
+static inline struct ocfs_inode_info *OCFS_I(struct inode *inode)
+{
+ return list_entry(inode, struct ocfs_inode_info, vfs_inode);
+}
+
+static inline atomic_t *GET_INODE_CLEAN_SEQ(struct inode *inode)
+{
+ return &(OCFS_I(inode)->i_clean_buffer_seq);
+}
+
+static inline int inode_data_is_oin(struct inode *inode)
+{
+ return (OCFS_I(inode)->generic_ip != NULL);
+}
+
+static inline __u8 INODE_DELETED(struct inode *inode)
+{
+ return OCFS_I(inode)->deleted;
+}
+
+static inline void SET_INODE_DELETED(struct inode *inode)
+{
+ OCFS_I(inode)->deleted = 1;
+}
+
+static inline void CLEAR_INODE_DELETED(struct inode *inode)
+{
+ OCFS_I(inode)->deleted = 0;
+}
+
+static inline void SET_INODE_VOTEOFF(struct inode *inode, __u64 voteoff)
+{
+ OCFS_I(inode)->voteoff = voteoff;
+}
+
+static inline __u64 GET_INODE_VOTEOFF(struct inode *inode)
+{
+ return OCFS_I(inode)->voteoff;
+}
+
+static inline void SET_INODE_FEOFF(struct inode *inode, __u64 feoff)
+{
+ OCFS_I(inode)->feoff = feoff;
+}
+
+static inline __u64 GET_INODE_FEOFF(struct inode *inode)
+{
+ return OCFS_I(inode)->feoff;
+}
+
+static inline void CLEAR_INODE_OIN(struct inode *inode)
+{
+ OCFS_I(inode)->generic_ip = (void *)NULL;
+}
+
+static inline void SET_INODE_OIN(struct inode *inode, void *oin)
+{
+ OCFS_I(inode)->generic_ip = oin;
+}
+
+static inline void *GET_INODE_OIN(struct inode *inode)
+{
+ return OCFS_I(inode)->generic_ip;
+}
+
+#else
+
typedef struct _ocfs_inode_private
{
void * generic_ip;
@@ -277,6 +354,8 @@
#define GET_INODE_OIN(i) ((ocfs_inode *)(OCFS_GENERIC_IP(i)->generic_ip))
+#endif /* 2.4.x kernel */
+
#define FIRST_FILE_ENTRY(dir) ((char *) ((char *)dir)+OCFS_SECTOR_SIZE)
#define FILEENT(dir,idx) (ocfs_file_entry *) ( ((char *)dir) + \
((dir->index[idx]+1) * OCFS_SECTOR_SIZE))
@@ -2077,6 +2156,7 @@
ocfs_obj_id obj_id;
ocfs_sem res;
struct list_head osb_next; /* List of all volumes */
+ kmem_cache_t *inode_cache;
kmem_cache_t *oin_cache;
kmem_cache_t *ofile_cache;
kmem_cache_t *fe_cache;
Index: src/namei.c
===================================================================
--- src/namei.c (revision 770)
+++ src/namei.c (working copy)
@@ -935,7 +935,7 @@
/* new parent dir offset */
if (inode_data_is_oin (new_dir))
- newDirOff = (GET_INODE_OIN(new_dir))->dir_disk_off;
+ newDirOff = ((ocfs_inode *)GET_INODE_OIN(new_dir))->dir_disk_off;
else
newDirOff = GET_INODE_VOTEOFF (new_dir);
^ permalink raw reply [flat|nested] 13+ messages in thread* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-11 15:53 ` Rusty Lynch
@ 2004-03-12 14:47 ` Mark Fasheh
2004-03-12 15:07 ` Rusty Lynch
0 siblings, 1 reply; 13+ messages in thread
From: Mark Fasheh @ 2004-03-12 14:47 UTC (permalink / raw)
To: ocfs2-devel
Ok, I finally got a chance to sit down and check this one out. So far so
good, but a couple comments below:
On Thu, Mar 11, 2004 at 01:53:00PM -0800, Rusty Lynch wrote:
<snip>
> > So... struct inode changed in 2.6 such that the union on the end of the
> > struct now only contains "void *generic_ip", and therefore only adds
> > on sizeof(void *) to the end of the structure. Our 2.6 code is still
> > attempting to read/write private data at the end of the inode struct,
> > and therefore writing past the end of the object.
> >
> > The suggested new way of storing private data is to define a new
> > struct that contains your private data and has an inode imbedded inside.
> > Then the private data can be reached from an inode by doing a simple
> > container_of on the inode. This is possible by hooking into inode
> > allocation/deallocation via the alloc_inode/destroy_inode function
> > pointers in the super operations.
> >
> > (See linux/Documentation/filesystems/port)
Can we please somehow try to do the similar thing with our 2.4 code?
Obviously it's slightly different, but allocating the inode private data
and in 2.4, putting it in inode->u->generic_ip is The Right Thing (TM).
You can use a kmem_cache for both.
Also, please feel free to change our own "void * generic_ip" to an
"ocfs_inode *oin" as that's the only type of structure that ever gets put
there.
If you're so setup for 2.6 that testing on a 2.4 kernel is difficult, I'd be
happy to help out by testing on my 2.4 setup :)
> >
> > The following patch does this and also takes the liberty to convert the
> > macros for getting/setting private data into inline functions (mainly
> > because stared at OCFS_GENERIC_IP and friends for way to long before
> > I realized what they were actually doing, and why that was freezing my
> > 2.6 build.)
I know earlier that I said we wanted to get rid of our macros, but most of
these are one liners. Could you please just keep them in macro form? Also,
if we make things inline, I think we'd want to drop the all-caps as that
should be reserved for macros. Obviously, we break this rule ourselves in
many places, but much of that is old cruft which we are slowly changing :)
Speaking of which, i noticed that inode_data_is_oin should be upper case as
a macro, so feel free to change that too.
--Mark
--
Mark Fasheh
Software Developer, Oracle Corp
mark.fasheh@oracle.com
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-12 14:47 ` Mark Fasheh
@ 2004-03-12 15:07 ` Rusty Lynch
2004-03-12 18:09 ` Mark Fasheh
0 siblings, 1 reply; 13+ messages in thread
From: Rusty Lynch @ 2004-03-12 15:07 UTC (permalink / raw)
To: ocfs2-devel
On Fri, Mar 12, 2004 at 12:47:47PM -0800, Mark Fasheh wrote:
> Ok, I finally got a chance to sit down and check this one out. So far so
> good, but a couple comments below:
>
> On Thu, Mar 11, 2004 at 01:53:00PM -0800, Rusty Lynch wrote:
> <snip>
> > > So... struct inode changed in 2.6 such that the union on the end of the
> > > struct now only contains "void *generic_ip", and therefore only adds
> > > on sizeof(void *) to the end of the structure. Our 2.6 code is still
> > > attempting to read/write private data at the end of the inode struct,
> > > and therefore writing past the end of the object.
> > >
> > > The suggested new way of storing private data is to define a new
> > > struct that contains your private data and has an inode imbedded inside.
> > > Then the private data can be reached from an inode by doing a simple
> > > container_of on the inode. This is possible by hooking into inode
> > > allocation/deallocation via the alloc_inode/destroy_inode function
> > > pointers in the super operations.
> > >
> > > (See linux/Documentation/filesystems/port)
> Can we please somehow try to do the similar thing with our 2.4 code?
> Obviously it's slightly different, but allocating the inode private data
> and in 2.4, putting it in inode->u->generic_ip is The Right Thing (TM).
> You can use a kmem_cache for both.
>
> Also, please feel free to change our own "void * generic_ip" to an
> "ocfs_inode *oin" as that's the only type of structure that ever gets put
> there.
>
> If you're so setup for 2.6 that testing on a 2.4 kernel is difficult, I'd be
> happy to help out by testing on my 2.4 setup :)
This is what I wanted to do, but I was attempting to leave no trail on the
2.4 code. I am also running my changes on a 2.4 kernel, but not doing much
testing other then mounting a volume, unpackaging a bunch stuff, moving it
around, ... and what ever else strikes me as significant.
I'll make another pass that makes the 2.4 and 2.6 code store the inode private
data in the way suggested in 2.6.
>
> > >
> > > The following patch does this and also takes the liberty to convert the
> > > macros for getting/setting private data into inline functions (mainly
> > > because stared at OCFS_GENERIC_IP and friends for way to long before
> > > I realized what they were actually doing, and why that was freezing my
> > > 2.6 build.)
> I know earlier that I said we wanted to get rid of our macros, but most of
> these are one liners. Could you please just keep them in macro form? Also,
> if we make things inline, I think we'd want to drop the all-caps as that
> should be reserved for macros. Obviously, we break this rule ourselves in
> many places, but much of that is old cruft which we are slowly changing :)
> Speaking of which, i noticed that inode_data_is_oin should be upper case as
> a macro, so feel free to change that too.
> --Mark
As to the use of upper case for MACROS... I agree. I was just trying to sneak
in some macro genocide without having to touch all the code that calls the
macros.
So just curious, when do you feel a macro is better then an inline function?
Either way I'll generate a patch that just does the minimal about to move the
inode private data, and seperate the macro question to another patch (or series
of patches.)
--rusty
^ permalink raw reply [flat|nested] 13+ messages in thread* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-12 15:07 ` Rusty Lynch
@ 2004-03-12 18:09 ` Mark Fasheh
2004-03-13 12:40 ` Rusty Lynch
2004-03-14 16:34 ` Rusty Lynch
0 siblings, 2 replies; 13+ messages in thread
From: Mark Fasheh @ 2004-03-12 18:09 UTC (permalink / raw)
To: ocfs2-devel
On Fri, Mar 12, 2004 at 01:07:01PM -0800, Rusty Lynch wrote:
> This is what I wanted to do, but I was attempting to leave no trail on the
> 2.4 code. I am also running my changes on a 2.4 kernel, but not doing much
> testing other then mounting a volume, unpackaging a bunch stuff, moving it
> around, ... and what ever else strikes me as significant.
That should work for a basic test, I'll put it through the rest of it's
paces :)
> I'll make another pass that makes the 2.4 and 2.6 code store the inode private
> data in the way suggested in 2.6.
Is it even possible to handle this in the way suggested in 2.6? It's a
slightly different mechanism for 2.4, right? For 2.4, what I was thinking
was along the lines of:
<near the top of ocfs_populate_inode, prolly after the fe sanity check>
if (!inode->u.generic_ip)
inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache,
GFP_NOFS);
Of course, with proper error checking and whatnot.
Then in ocfs_clear_inode, we could just do:
ocfs_destroy_inode(inode);
inode->u.generic_ip = NULL;
Again, cleaned up and bugchecked and whatnot.
What do you think?
> As to the use of upper case for MACROS... I agree. I was just trying to sneak
> in some macro genocide without having to touch all the code that calls the
> macros.
Well, it's a good cause :)
> So just curious, when do you feel a macro is better then an inline function?
Umm, I have no strong opinions really. I think mostly my rule is if it's
only a line or two that doesn't necessarily require any typechecking, then a
macro is fine. Otherwise, an inline's the better choice.
> Either way I'll generate a patch that just does the minimal about to move the
> inode private data, and seperate the macro question to another patch (or series
> of patches.)
That'd be nice actually, rather than having more than one change in a patch
-- it's easier to review them that way.
--Mark
--
Mark Fasheh
Software Developer, Oracle Corp
mark.fasheh@oracle.com
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-12 18:09 ` Mark Fasheh
@ 2004-03-13 12:40 ` Rusty Lynch
2004-03-13 12:44 ` Wim Coekaerts
2004-03-14 16:34 ` Rusty Lynch
1 sibling, 1 reply; 13+ messages in thread
From: Rusty Lynch @ 2004-03-13 12:40 UTC (permalink / raw)
To: ocfs2-devel
On Fri, Mar 12, 2004 at 04:09:13PM -0800, Mark Fasheh wrote:
> On Fri, Mar 12, 2004 at 01:07:01PM -0800, Rusty Lynch wrote:
> > This is what I wanted to do, but I was attempting to leave no trail on the
> > 2.4 code. I am also running my changes on a 2.4 kernel, but not doing much
> > testing other then mounting a volume, unpackaging a bunch stuff, moving it
> > around, ... and what ever else strikes me as significant.
> That should work for a basic test, I'll put it through the rest of it's
> paces :)
>
> > I'll make another pass that makes the 2.4 and 2.6 code store the inode private
> > data in the way suggested in 2.6.
> Is it even possible to handle this in the way suggested in 2.6? It's a
> slightly different mechanism for 2.4, right? For 2.4, what I was thinking
> was along the lines of:
>
Ah... I had only looked at the source for one of the newer 2.4 kernels
and noticed the addition of the allocation/destroy hooks in the
super_operations. After seeing your response I dug a little deeper and
found that this is a fairly new addition to 2.4, so it would not be possible
to do since ocfs is required to support some older distribution releases
that probobly do not have the new hooks.
(BTW, is there a quick reference handy for each of the kernel versions that
ocfs2 needs to work on? The oldest is probobly all that would be needed.)
> <near the top of ocfs_populate_inode, prolly after the fe sanity check>
>
> if (!inode->u.generic_ip)
> inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache,
> GFP_NOFS);
easy enough
>
> Of course, with proper error checking and whatnot.
> Then in ocfs_clear_inode, we could just do:
>
> ocfs_destroy_inode(inode);
> inode->u.generic_ip = NULL;
>
> Again, cleaned up and bugchecked and whatnot.
> What do you think?
>
there is no ocfs_destroy_inode()... but I get the picture.
hmm... looking at all the places where we ocfs_release_oin(),
I need to look a little deeper at exactly how we do cleanup.
I'm stuck at home all weekend sick as a dog and kicking myself
for choosing the most sunny weekend of the year to get sick! :-<
I'm also bored out of my mind so I think I'll be hacking between
hacking. (ok, I can see where that wouldn't be all that funny
if you were not flying high on cough medication, but it was funny
to me :->)
> > As to the use of upper case for MACROS... I agree. I was just trying to sneak
> > in some macro genocide without having to touch all the code that calls the
> > macros.
> Well, it's a good cause :)
>
> > So just curious, when do you feel a macro is better then an inline function?
> Umm, I have no strong opinions really. I think mostly my rule is if it's
> only a line or two that doesn't necessarily require any typechecking, then a
> macro is fine. Otherwise, an inline's the better choice.
>
> > Either way I'll generate a patch that just does the minimal about to move the
> > inode private data, and seperate the macro question to another patch (or series
> > of patches.)
> That'd be nice actually, rather than having more than one change in a patch
> -- it's easier to review them that way.
> --Mark
>
> --
> Mark Fasheh
> Software Developer, Oracle Corp
> mark.fasheh@oracle.com
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-13 12:40 ` Rusty Lynch
@ 2004-03-13 12:44 ` Wim Coekaerts
0 siblings, 0 replies; 13+ messages in thread
From: Wim Coekaerts @ 2004-03-13 12:44 UTC (permalink / raw)
To: ocfs2-devel
just the main distributions
rhel3 rhas21 suse sp3
and forward rhel4 sles9
nothing else planned really.
hope you get better soon !
On Sat, Mar 13, 2004 at 10:39:59AM -0800, Rusty Lynch wrote:
> On Fri, Mar 12, 2004 at 04:09:13PM -0800, Mark Fasheh wrote:
> > On Fri, Mar 12, 2004 at 01:07:01PM -0800, Rusty Lynch wrote:
> > > This is what I wanted to do, but I was attempting to leave no trail on the
> > > 2.4 code. I am also running my changes on a 2.4 kernel, but not doing much
> > > testing other then mounting a volume, unpackaging a bunch stuff, moving it
> > > around, ... and what ever else strikes me as significant.
> > That should work for a basic test, I'll put it through the rest of it's
> > paces :)
> >
> > > I'll make another pass that makes the 2.4 and 2.6 code store the inode private
> > > data in the way suggested in 2.6.
> > Is it even possible to handle this in the way suggested in 2.6? It's a
> > slightly different mechanism for 2.4, right? For 2.4, what I was thinking
> > was along the lines of:
> >
>
> Ah... I had only looked at the source for one of the newer 2.4 kernels
> and noticed the addition of the allocation/destroy hooks in the
> super_operations. After seeing your response I dug a little deeper and
> found that this is a fairly new addition to 2.4, so it would not be possible
> to do since ocfs is required to support some older distribution releases
> that probobly do not have the new hooks.
>
> (BTW, is there a quick reference handy for each of the kernel versions that
> ocfs2 needs to work on? The oldest is probobly all that would be needed.)
>
> > <near the top of ocfs_populate_inode, prolly after the fe sanity check>
> >
> > if (!inode->u.generic_ip)
> > inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache,
> > GFP_NOFS);
>
> easy enough
>
> >
> > Of course, with proper error checking and whatnot.
> > Then in ocfs_clear_inode, we could just do:
> >
> > ocfs_destroy_inode(inode);
> > inode->u.generic_ip = NULL;
> >
> > Again, cleaned up and bugchecked and whatnot.
> > What do you think?
> >
>
> there is no ocfs_destroy_inode()... but I get the picture.
> hmm... looking at all the places where we ocfs_release_oin(),
> I need to look a little deeper at exactly how we do cleanup.
>
> I'm stuck at home all weekend sick as a dog and kicking myself
> for choosing the most sunny weekend of the year to get sick! :-<
>
> I'm also bored out of my mind so I think I'll be hacking between
> hacking. (ok, I can see where that wouldn't be all that funny
> if you were not flying high on cough medication, but it was funny
> to me :->)
>
>
> > > As to the use of upper case for MACROS... I agree. I was just trying to sneak
> > > in some macro genocide without having to touch all the code that calls the
> > > macros.
> > Well, it's a good cause :)
> >
> > > So just curious, when do you feel a macro is better then an inline function?
> > Umm, I have no strong opinions really. I think mostly my rule is if it's
> > only a line or two that doesn't necessarily require any typechecking, then a
> > macro is fine. Otherwise, an inline's the better choice.
> >
> > > Either way I'll generate a patch that just does the minimal about to move the
> > > inode private data, and seperate the macro question to another patch (or series
> > > of patches.)
> > That'd be nice actually, rather than having more than one change in a patch
> > -- it's easier to review them that way.
> > --Mark
> >
> > --
> > Mark Fasheh
> > Software Developer, Oracle Corp
> > mark.fasheh@oracle.com
> _______________________________________________
> Ocfs2-devel mailing list
> Ocfs2-devel@oss.oracle.com
> http://oss.oracle.com/mailman/listinfo/ocfs2-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-12 18:09 ` Mark Fasheh
2004-03-13 12:40 ` Rusty Lynch
@ 2004-03-14 16:34 ` Rusty Lynch
2004-03-15 16:16 ` Mark Fasheh
1 sibling, 1 reply; 13+ messages in thread
From: Rusty Lynch @ 2004-03-14 16:34 UTC (permalink / raw)
To: ocfs2-devel
On Fri, Mar 12, 2004 at 04:09:13PM -0800, Mark Fasheh wrote:
> On Fri, Mar 12, 2004 at 01:07:01PM -0800, Rusty Lynch wrote:
> > This is what I wanted to do, but I was attempting to leave no trail on the
> > 2.4 code. I am also running my changes on a 2.4 kernel, but not doing much
> > testing other then mounting a volume, unpackaging a bunch stuff, moving it
> > around, ... and what ever else strikes me as significant.
> That should work for a basic test, I'll put it through the rest of it's
> paces :)
>
> > I'll make another pass that makes the 2.4 and 2.6 code store the inode private
> > data in the way suggested in 2.6.
> Is it even possible to handle this in the way suggested in 2.6? It's a
> slightly different mechanism for 2.4, right? For 2.4, what I was thinking
> was along the lines of:
>
> <near the top of ocfs_populate_inode, prolly after the fe sanity check>
>
> if (!inode->u.generic_ip)
> inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache,
> GFP_NOFS);
>
> Of course, with proper error checking and whatnot.
> Then in ocfs_clear_inode, we could just do:
>
> ocfs_destroy_inode(inode);
> inode->u.generic_ip = NULL;
>
> Again, cleaned up and bugchecked and whatnot.
> What do you think?
>
> > As to the use of upper case for MACROS... I agree. I was just trying to sneak
> > in some macro genocide without having to touch all the code that calls the
> > macros.
> Well, it's a good cause :)
>
> > So just curious, when do you feel a macro is better then an inline function?
> Umm, I have no strong opinions really. I think mostly my rule is if it's
> only a line or two that doesn't necessarily require any typechecking, then a
> macro is fine. Otherwise, an inline's the better choice.
>
> > Either way I'll generate a patch that just does the minimal about to move the
> > inode private data, and seperate the macro question to another patch (or series
> > of patches.)
Here is a patch that stores the inode private data as you talked about above.
There is a little more complexity because you have to handle the cases where:
* new inodes are created via ocfs_mknod and ocfs_symlink, and we need to
start setting private data before ocfs_populate_inode
* reading the root inode in ocfs_read_inode2 (2.4 kernel) or
ocfs_read_locked_inode (2.6 kernel) where we just directly populate the
inode and do not call ocfs_populate_inode()
There is really no difference between a 2.4 and 2.6 build (other then where
to put the code for reading the root inode.)
--rusty
Index: src/inode.c
===================================================================
--- src/inode.c (revision 776)
+++ src/inode.c (working copy)
@@ -251,6 +251,15 @@
BUG();
}
+ if (!inode->u.generic_ip)
+ inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache,
+ GFP_NOFS);
+ if (!inode->u.generic_ip) {
+ /* How can we recover gracefully? */
+ LOG_ERROR_STR("unable to allocate private data for inode");
+ goto bail;
+ }
+
OCFS_SET_INODE_DEV(sb, inode);
inode->i_mode = mode;
inode->i_uid = fe->uid;
@@ -306,6 +315,7 @@
break;
}
+ bail:
LOG_EXIT ();
return;
} /* ocfs_populate_inode */
@@ -337,6 +347,13 @@
LOG_TRACE_ARGS("osb = %x\n", osb);
if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
LOG_TRACE_ARGS("Populating root inode (i_ino = %lu)\n", inode->i_ino);
+ inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
+ if (!inode->u.generic_ip) {
+ /* How can we recover gracefully? */
+ LOG_ERROR_STR("unable to allocate private data for inode");
+ goto bail;
+ }
+
inode->i_mode = S_IFDIR | osb->vol_layout.prot_bits;
inode->i_blksize = 512; /* TODO: fix */
inode->i_blkbits = 9;
@@ -434,6 +451,13 @@
sb = inode->i_sb;
osb = (ocfs_super *) OCFS_GENERIC_SB_P(sb);
if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
+ inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
+ if (!inode->u.generic_ip) {
+ /* How can we recover gracefully? */
+ LOG_ERROR_STR("unable to allocate private data for inode");
+ goto bail;
+ }
+
inode->i_mode = S_IFDIR | osb->vol_layout.prot_bits;
inode->i_blksize = (__u32) osb->vol_layout.cluster_size;
inode->i_size = OCFS_DEFAULT_DIR_NODE_SIZE;
@@ -745,24 +769,14 @@
LOG_TRACE_STR ("inode with oin : clear inode");
oin = GET_INODE_OIN(inode);
- if (oin == osb->oin_root_dir) {
- LOG_TRACE_STR("this is the root inode, doing "
- "cleanup now!");
- ocfs_sync_blockdev(inode->i_sb);
- LOG_TRACE_STR ("syncing past root inode");
- LOG_TRACE_STR ("calling dismount");
- ocfs_dismount_volume (inode->i_sb);
- goto bail;
- } else
+ if (oin != osb->oin_root_dir)
BUG();
-
- ocfs_extent_map_destroy (&oin->map);
- ocfs_extent_map_init (&oin->map);
-
- ocfs_release_cached_oin (osb, oin);
- ocfs_release_oin (oin, true);
- oin = NULL;
- LOG_TRACE_STR ("yeah! done with deallocs!");
+
+ LOG_TRACE_STR("this is the root inode, doing cleanup now!");
+ ocfs_sync_blockdev(inode->i_sb);
+ LOG_TRACE_STR ("syncing past root inode");
+ LOG_TRACE_STR ("calling dismount");
+ ocfs_dismount_volume (inode->i_sb);
} else {
if (!ocfs_lookup_sector_node (osb, offset, &lockres)) {
if (lockres) {
@@ -780,6 +794,9 @@
}
}
+ if (inode->u.generic_ip)
+ kmem_cache_free(OcfsGlobalCtxt.inode_cache,
+ inode->u.generic_ip);
bail:
LOG_EXIT ();
return;
Index: src/super.c
===================================================================
--- src/super.c (revision 776)
+++ src/super.c (working copy)
@@ -782,12 +782,30 @@
}
#endif
+static void ocfs_inode_init_once(void *p, kmem_cache_t *cachep,
+ unsigned long flags)
+{
+ ocfs_inode_private *i = (ocfs_inode_private *) p;
+
+ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+ SLAB_CTOR_CONSTRUCTOR) {
+ i->generic_ip = NULL;
+ i->voteoff = 0;
+ i->feoff = 0;
+ atomic_set(&i->i_clean_buffer_seq, 0);
+ }
+}
+
/*
* ocfs_initialize_mem_lists()
*
*/
static int ocfs_initialize_mem_lists (void)
{
+ OcfsGlobalCtxt.inode_cache = kmem_cache_create("ocfs2_inode",
+ sizeof(ocfs_inode_private), 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
+ ocfs_inode_init_once, NULL);
+
OcfsGlobalCtxt.oin_cache = kmem_cache_create ("ocfs2_oin",
sizeof (ocfs_inode) + OCFS_POINTER_SIZE, 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
NULL, NULL);
@@ -826,6 +844,7 @@
*/
static void ocfs_free_mem_lists (void)
{
+ kmem_cache_destroy (OcfsGlobalCtxt.inode_cache);
kmem_cache_destroy (OcfsGlobalCtxt.oin_cache);
kmem_cache_destroy (OcfsGlobalCtxt.ofile_cache);
kmem_cache_destroy (OcfsGlobalCtxt.fe_cache);
Index: src/inc/ocfs.h
===================================================================
--- src/inc/ocfs.h (revision 776)
+++ src/inc/ocfs.h (working copy)
@@ -239,11 +239,9 @@
__u8 deleted; /* this can be a generic flags field later */
} ocfs_inode_private;
-#define CLEAN_SEQ_OFF ((unsigned long)(&((ocfs_inode_private *)0)->i_clean_buffer_seq))
-#define INODE_PRIVATE_OFF ((unsigned long)(&((struct inode *)0)->u.generic_ip))
-#define GET_INODE_CLEAN_SEQ(i) (atomic_t *)(((unsigned long)i) + INODE_PRIVATE_OFF + CLEAN_SEQ_OFF)
+#define GET_INODE_CLEAN_SEQ(i) (atomic_t *)(&(OCFS_GENERIC_IP(i)->i_clean_buffer_seq))
-#define OCFS_GENERIC_IP(i) ((ocfs_inode_private *)(&(i->u.generic_ip)))
+#define OCFS_GENERIC_IP(i) ((ocfs_inode_private *)(i->u.generic_ip))
#define inode_data_is_oin(i) (OCFS_GENERIC_IP(i)->generic_ip != NULL)
@@ -2081,6 +2079,7 @@
ocfs_obj_id obj_id;
ocfs_sem res;
struct list_head osb_next; /* List of all volumes */
+ kmem_cache_t *inode_cache;
kmem_cache_t *oin_cache;
kmem_cache_t *ofile_cache;
kmem_cache_t *fe_cache;
Index: src/namei.c
===================================================================
--- src/namei.c (revision 776)
+++ src/namei.c (working copy)
@@ -195,7 +195,13 @@
LOG_ERROR_STR("new_inode failed!");
goto leave;
}
-
+
+ inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
+ if (!inode->u.generic_ip) {
+ LOG_ERROR_STATUS(status = -ENOMEM);
+ goto leave;
+ }
+
/* need the offset of our parent directory to lock it */
if (!ocfs_linux_get_inode_offset (dir, &parent_off, NULL)) {
LOG_ERROR_STATUS (status = -ENOENT);
@@ -1342,6 +1348,13 @@
LOG_ERROR_STR("new_inode failed!");
goto bail;
}
+
+ inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
+ if (!inode->u.generic_ip) {
+ LOG_ERROR_STATUS(status = -ENOMEM);
+ goto bail;
+ }
+
//atomic_set(GET_INODE_CLEAN_SEQ(inode), atomic_read(&osb->clean_buffer_seq));
parentInode = dentry->d_parent->d_inode;
^ permalink raw reply [flat|nested] 13+ messages in thread* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-14 16:34 ` Rusty Lynch
@ 2004-03-15 16:16 ` Mark Fasheh
2004-03-15 16:40 ` Rusty Lynch
2004-03-16 18:35 ` Mark Fasheh
0 siblings, 2 replies; 13+ messages in thread
From: Mark Fasheh @ 2004-03-15 16:16 UTC (permalink / raw)
To: ocfs2-devel
On Sun, Mar 14, 2004 at 02:34:40PM -0800, Rusty Lynch wrote:
> Here is a patch that stores the inode private data as you talked about above.
> There is a little more complexity because you have to handle the cases where:
> * new inodes are created via ocfs_mknod and ocfs_symlink, and we need to
> start setting private data before ocfs_populate_inode
> * reading the root inode in ocfs_read_inode2 (2.4 kernel) or
> ocfs_read_locked_inode (2.6 kernel) where we just directly populate the
> inode and do not call ocfs_populate_inode()
this is good. I'm going to do some testing on this today, though it looks
pretty sane.
> There is really no difference between a 2.4 and 2.6 build (other then where
> to put the code for reading the root inode.)
Yeah, and the code is so much cleaner now too :)
Just to be sure, this covers all you need in 2.6 to get the inode stuff
going too, correct? For 2.6, it looks like you're using the generic_ip
route, which is fine if you feel that there aren't any major disadvantages
(the only thing I can think of is memory allocation related).
--Mark
--
Mark Fasheh
Software Developer, Oracle Corp
mark.fasheh@oracle.com
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-15 16:16 ` Mark Fasheh
@ 2004-03-15 16:40 ` Rusty Lynch
2004-03-16 18:35 ` Mark Fasheh
1 sibling, 0 replies; 13+ messages in thread
From: Rusty Lynch @ 2004-03-15 16:40 UTC (permalink / raw)
To: ocfs2-devel
On Mon, Mar 15, 2004 at 02:16:54PM -0800, Mark Fasheh wrote:
> On Sun, Mar 14, 2004 at 02:34:40PM -0800, Rusty Lynch wrote:
> > Here is a patch that stores the inode private data as you talked about above.
> > There is a little more complexity because you have to handle the cases where:
> > * new inodes are created via ocfs_mknod and ocfs_symlink, and we need to
> > start setting private data before ocfs_populate_inode
> > * reading the root inode in ocfs_read_inode2 (2.4 kernel) or
> > ocfs_read_locked_inode (2.6 kernel) where we just directly populate the
> > inode and do not call ocfs_populate_inode()
> this is good. I'm going to do some testing on this today, though it looks
> pretty sane.
>
> > There is really no difference between a 2.4 and 2.6 build (other then where
> > to put the code for reading the root inode.)
> Yeah, and the code is so much cleaner now too :)
> Just to be sure, this covers all you need in 2.6 to get the inode stuff
> going too, correct? For 2.6, it looks like you're using the generic_ip
> route, which is fine if you feel that there aren't any major disadvantages
> (the only thing I can think of is memory allocation related).
yes, this is all the 2.6 port needs to get the private data for inodes correct.
We are basically utilizing the legacy path on 2.6. The only real disadvantage
I see is just that the code is more complex (when you only take the 2.6 code
into consideration.)
With this patch (and also the patch I sent earlier to ocfs_unlink), the only
major functionality holes in 2.6 are:
* when you attempt to umount the volume, ocfs_released_cached_oin() will
stumble across a oin->lock_res that has already been free'ed, but not
set to null (oops'ing when we try to dereference ->signature).
* Something is screwy when we try to write file data. All the file meta
data seems to be correct, and we properly allocate blocks on disk, but
only random garbage makes it into the extents
Other then that I can move files, delete files, read files, make symbolic
links, follow symbolic links, etc.
--rusty
^ permalink raw reply [flat|nested] 13+ messages in thread* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-15 16:16 ` Mark Fasheh
2004-03-15 16:40 ` Rusty Lynch
@ 2004-03-16 18:35 ` Mark Fasheh
1 sibling, 0 replies; 13+ messages in thread
From: Mark Fasheh @ 2004-03-16 18:35 UTC (permalink / raw)
To: ocfs2-devel
Alright, things look good for this patch -- I've committed it to SVN.
I'll prolly change the generic_ip to an ocfs_inode * later.
--Mark
--
Mark Fasheh
Software Developer, Oracle Corp
mark.fasheh@oracle.com
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
@ 2004-03-12 17:40 Villalovos, John L
2004-03-15 15:55 ` Mark Fasheh
0 siblings, 1 reply; 13+ messages in thread
From: Villalovos, John L @ 2004-03-12 17:40 UTC (permalink / raw)
To: ocfs2-devel
> Ok, I finally got a chance to sit down and check this one
> out. So far so
> good, but a couple comments below:
>
> > > The suggested new way of storing private data is to define a new
> > > struct that contains your private data and has an inode
> imbedded inside.
> > > Then the private data can be reached from an inode by
> doing a simple
> > > container_of on the inode. This is possible by hooking into inode
> > > allocation/deallocation via the alloc_inode/destroy_inode
> function
> > > pointers in the super operations.
> > >
> > > (See linux/Documentation/filesystems/port)
> Can we please somehow try to do the similar thing with our 2.4 code?
> Obviously it's slightly different, but allocating the inode
> private data
> and in 2.4, putting it in inode->u->generic_ip is The Right
> Thing (TM).
> You can use a kmem_cache for both.
>
> Also, please feel free to change our own "void * generic_ip" to an
> "ocfs_inode *oin" as that's the only type of structure that
> ever gets put
> there.
Rusty and I will try to work on doing this. Probably won't get done
until Monday or Tuesday though.
> If you're so setup for 2.6 that testing on a 2.4 kernel is
> difficult, I'd be
> happy to help out by testing on my 2.4 setup :)
I think we should be able to debug on a 2.4 system.
> I know earlier that I said we wanted to get rid of our
> macros, but most of
> these are one liners. Could you please just keep them in
> macro form? Also,
> if we make things inline, I think we'd want to drop the
> all-caps as that
> should be reserved for macros. Obviously, we break this rule
> ourselves in
> many places, but much of that is old cruft which we are
> slowly changing :)
> Speaking of which, i noticed that inode_data_is_oin should be
> upper case as
> a macro, so feel free to change that too.
Just curious on why you would ever want to use macros over inline
functions? I'll be honest and express my prejudice against macros right
here and now :) Since the compiler will convert an inline function into
the exact same thing as a macro and you get type checking and
predicatable behavior with a inline function.
As Meyers says (
http://www.amazon.com/exec/obidos/tg/detail/-/0201924889/qid=1079134299/
sr=1-2/ref=pd_ka_2/002-2866874-3073608?v=glance&s=books ) it is good to
prefer const and inline to #define.
And some people think "macros are evil" :)
(http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.5)
Ok. I know macros aren't all that bad but for the ones Rusty did I kind
of thought the usage there wasn't bad.
Using macros sounds good if you want to use the __LINE__, __FILE__, and
etc stuff.
But I am sure Rusty and I will go whichever way the wind is blowing :)
John
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data
2004-03-12 17:40 Villalovos, John L
@ 2004-03-15 15:55 ` Mark Fasheh
0 siblings, 0 replies; 13+ messages in thread
From: Mark Fasheh @ 2004-03-15 15:55 UTC (permalink / raw)
To: ocfs2-devel
On Fri, Mar 12, 2004 at 03:39:42PM -0800, Villalovos, John L wrote:
> Just curious on why you would ever want to use macros over inline
> functions? I'll be honest and express my prejudice against macros right
> here and now :) Since the compiler will convert an inline function into
> the exact same thing as a macro and you get type checking and
> predicatable behavior with a inline function.
Well, better a prejudice against macros, than a bias *towards* using them.
I've seen that before, and it ain't pretty :)
Mainly, for one liners which don't require typechecking, I find macros
easier to read -- there's less on the page there, especially when you've got
a bunch of said macros defined right after another -- compare Rusty's older
inode patch against the macro definitions we've got. Ok, maybe *those*
particular macros aren't the best example, but you get my point! :)
Also, Manish tells me that using a macro in that case reduces gcc's working
set (though that's not really much of an issue).
--Mark
--
Mark Fasheh
Software Developer, Oracle Corp
mark.fasheh@oracle.com
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2004-03-16 18:35 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-10 22:49 [Ocfs2-devel] [PATCH]2.6 mechanism for holding private inode data Rusty Lynch
2004-03-11 15:53 ` Rusty Lynch
2004-03-12 14:47 ` Mark Fasheh
2004-03-12 15:07 ` Rusty Lynch
2004-03-12 18:09 ` Mark Fasheh
2004-03-13 12:40 ` Rusty Lynch
2004-03-13 12:44 ` Wim Coekaerts
2004-03-14 16:34 ` Rusty Lynch
2004-03-15 16:16 ` Mark Fasheh
2004-03-15 16:40 ` Rusty Lynch
2004-03-16 18:35 ` Mark Fasheh
-- strict thread matches above, loose matches on Subject: below --
2004-03-12 17:40 Villalovos, John L
2004-03-15 15:55 ` Mark Fasheh
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.