From 27f2044484dbc177d9ad5a3d9dcf5a23a3ed2a18 Mon Sep 17 00:00:00 2001 From: shadow Date: Tue, 8 Sep 2009 08:09:28 +0000 Subject: [PATCH] resolve race with saving updates to lov_objid file. Branch HEAD b=20464 i=adilger i=green --- libcfs/include/libcfs/bitmap.h | 12 +++++++++--- libcfs/include/libcfs/user-bitops.h | 8 ++++++-- lustre/include/liblustre.h | 30 ------------------------------ lustre/mdd/mdd_lov.c | 2 ++ lustre/mds/mds_lov.c | 8 ++++++-- 5 files changed, 23 insertions(+), 37 deletions(-) diff --git a/libcfs/include/libcfs/bitmap.h b/libcfs/include/libcfs/bitmap.h index 1d795de..a593701 100644 --- a/libcfs/include/libcfs/bitmap.h +++ b/libcfs/include/libcfs/bitmap.h @@ -64,19 +64,25 @@ bitmap_t *ALLOCATE_BITMAP(int size) static inline void cfs_bitmap_set(bitmap_t *bitmap, int nbit) { - set_bit(nbit, bitmap->data); + set_bit(nbit, bitmap->data); } static inline void cfs_bitmap_clear(bitmap_t *bitmap, int nbit) { - clear_bit(nbit, bitmap->data); + test_and_clear_bit(nbit, bitmap->data); } static inline int cfs_bitmap_check(bitmap_t *bitmap, int nbit) { - return test_bit(nbit, bitmap->data); + return test_bit(nbit, bitmap->data); +} + +static inline +int cfs_bitmap_test_and_clear(bitmap_t *bitmap, int nbit) +{ + return test_and_clear_bit(nbit, bitmap->data); } /* return 0 is bitmap has none set bits */ diff --git a/libcfs/include/libcfs/user-bitops.h b/libcfs/include/libcfs/user-bitops.h index ae7d569..cd0d220 100644 --- a/libcfs/include/libcfs/user-bitops.h +++ b/libcfs/include/libcfs/user-bitops.h @@ -42,7 +42,7 @@ #define __LIBCFS_USER_BITOPS_H__ /* test if bit nr is set in bitmap addr; returns previous value of bit nr */ -static __inline__ int set_bit(int nr, unsigned long *addr) +static __inline__ int test_and_set_bit(int nr, unsigned long *addr) { unsigned long mask; @@ -53,8 +53,10 @@ static __inline__ int set_bit(int nr, unsigned long *addr) return nr; } +#define set_bit(n, a) test_and_set_bit(n, a) + /* clear bit nr in bitmap addr; returns previous value of bit nr*/ -static __inline__ int clear_bit(int nr, unsigned long *addr) +static __inline__ int test_and_clear_bit(int nr, unsigned long *addr) { unsigned long mask; @@ -65,6 +67,8 @@ static __inline__ int clear_bit(int nr, unsigned long *addr) return nr; } +#define clear_bit(n, a) test_and_clear_bit(n, a) + static __inline__ int test_bit(int nr, const unsigned long *addr) { return ((1UL << (nr & (BITS_PER_LONG - 1))) & diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h index de9f343..8a3332d 100644 --- a/lustre/include/liblustre.h +++ b/lustre/include/liblustre.h @@ -324,36 +324,6 @@ int in_group_p(gid_t gid); #define might_sleep_if(c) #define smp_mb() -static inline -int test_and_set_bit(int nr, unsigned long *addr) -{ - int oldbit; - - while (nr >= sizeof(long)) { - nr -= sizeof(long); - addr++; - } - - oldbit = (*addr) & (1 << nr); - *addr |= (1 << nr); - return oldbit; -} - -static inline -int test_and_clear_bit(int nr, unsigned long *addr) -{ - int oldbit; - - while (nr >= sizeof(long)) { - nr -= sizeof(long); - addr++; - } - - oldbit = (*addr) & (1 << nr); - *addr &= ~(1 << nr); - return oldbit; -} - #define libcfs_memory_pressure_get() (0) #define libcfs_memory_pressure_put() do {} while (0) #define libcfs_memory_pressure_clr() do {} while (0) diff --git a/lustre/mdd/mdd_lov.c b/lustre/mdd/mdd_lov.c index bbf079a..d692736 100644 --- a/lustre/mdd/mdd_lov.c +++ b/lustre/mdd/mdd_lov.c @@ -410,6 +410,8 @@ int mdd_lov_create(const struct lu_env *env, struct mdd_device *mdd, if (spec->no_create != 0) { *lmm = (struct lov_mds_md *)spec->u.sp_ea.eadata; *lmm_size = spec->u.sp_ea.eadatalen; + LASSERT(*lmm_size == lov_mds_md_size((*lmm)->lmm_stripe_count, + (*lmm)->lmm_magic)); RETURN(0); } diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c index 39f2092..80b1658 100644 --- a/lustre/mds/mds_lov.c +++ b/lustre/mds/mds_lov.c @@ -452,6 +452,9 @@ int mds_lov_write_objids(struct obd_device *obd) LASSERT(data != NULL); + if (!cfs_bitmap_test_and_clear(mds->mds_lov_page_dirty, i)) + continue; + /* check for particaly filled last page */ if (i == mds->mds_lov_objid_lastpage) size = (mds->mds_lov_objid_lastidx+1) * sizeof(obd_id); @@ -459,9 +462,10 @@ int mds_lov_write_objids(struct obd_device *obd) CDEBUG(D_INFO, "write %lld - %u\n", off, size); rc = fsfilt_write_record(obd, mds->mds_lov_objid_filp, data, size, &off, 0); - if (rc < 0) + if (rc < 0) { + cfs_bitmap_set(mds->mds_lov_page_dirty, i); break; - cfs_bitmap_clear(mds->mds_lov_page_dirty, i); + } } if (rc >= 0) rc = 0; -- 1.8.3.1