diff options
| author | Anand Avati <avati@gluster.com> | 2009-10-15 19:36:47 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2009-10-16 05:13:01 -0700 | 
| commit | c8f39bea04c6021243d1ab2bcea450a0f067aabc (patch) | |
| tree | fdfcc4c0bc7f852184476a274060c2144ad3c691 | |
| parent | d3722f7546bdcfeed7cf3c2745c1bfafa7fa79a4 (diff) | |
locks: keep ref on the inode while locks are held
keeping refs on the inode while there are held locks prevents the
inode from getting pruned away
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 112 (parallel deletion of files mounted by different clients on the same back-end hangs and/or does not completely delete)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=112
| -rw-r--r-- | xlators/features/locks/src/common.c | 48 | ||||
| -rw-r--r-- | xlators/features/locks/src/common.h | 2 | ||||
| -rw-r--r-- | xlators/features/locks/src/internal.c | 4 | ||||
| -rw-r--r-- | xlators/features/locks/src/locks.h | 3 | ||||
| -rw-r--r-- | xlators/features/locks/src/posix.c | 1 | 
5 files changed, 58 insertions, 0 deletions
diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c index 5f115f6fa53..11841e92d07 100644 --- a/xlators/features/locks/src/common.c +++ b/xlators/features/locks/src/common.c @@ -35,6 +35,7 @@  #include "common-utils.h"  #include "locks.h" +#include "common.h"  static int @@ -48,6 +49,53 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock,  				    ? &pl_inode->ext_list	\  				    : &pl_inode->int_list) + +int +__pl_inode_is_empty (pl_inode_t *pl_inode) +{ +        int is_empty = 1; + +        if (!list_empty (&pl_inode->ext_list)) +                is_empty = 0; + +        if (!list_empty (&pl_inode->int_list)) +                is_empty = 0; + +        if (!list_empty (&pl_inode->dir_list)) +                is_empty = 0; + +        return is_empty; +} + +void +pl_update_refkeeper (xlator_t *this, inode_t *inode) +{ +        pl_inode_t *pl_inode  = NULL; +        int         is_empty  = 0; +        int         need_unref = 0; + +        pl_inode = pl_inode_get (this, inode); + +        pthread_mutex_lock (&pl_inode->mutex); +        { +                is_empty = __pl_inode_is_empty (pl_inode); + +                if (is_empty && pl_inode->refkeeper) { +                        need_unref = 1; +                        pl_inode->refkeeper = NULL; +                } + +                if (!is_empty && !pl_inode->refkeeper) { +                        pl_inode->refkeeper = inode_ref (inode); +                } +        } +        pthread_mutex_unlock (&pl_inode->mutex); + +        if (need_unref) +                inode_unref (inode); +} + +  pl_inode_t *  pl_inode_get (xlator_t *this, inode_t *inode)  { diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h index 06f104f5234..78de8432fad 100644 --- a/xlators/features/locks/src/common.h +++ b/xlators/features/locks/src/common.h @@ -49,4 +49,6 @@ void __delete_lock (pl_inode_t *, posix_lock_t *);  void __destroy_lock (posix_lock_t *); +void pl_update_refkeeper (xlator_t *this, inode_t *inode); +  #endif /* __COMMON_H__ */ diff --git a/xlators/features/locks/src/internal.c b/xlators/features/locks/src/internal.c index 1c122093162..4878265871f 100644 --- a/xlators/features/locks/src/internal.c +++ b/xlators/features/locks/src/internal.c @@ -191,6 +191,7 @@ pl_inodelk (call_frame_t *frame, xlator_t *this,  	op_ret = 0;  unwind:	 +        pl_update_refkeeper (this, loc->inode);  	STACK_UNWIND (frame, op_ret, op_errno);  out:  	return 0; @@ -293,6 +294,7 @@ pl_finodelk (call_frame_t *frame, xlator_t *this,  	op_ret = 0;  unwind:	 +        pl_update_refkeeper (this, fd->inode);  	STACK_UNWIND (frame, op_ret, op_errno);  out:  	return 0; @@ -782,6 +784,7 @@ pl_entrylk (call_frame_t *frame, xlator_t *this,  	op_ret = 0;  out: +        pl_update_refkeeper (this, loc->inode);  	if (unwind) {  		STACK_UNWIND (frame, op_ret, op_errno);  	} @@ -888,6 +891,7 @@ pl_fentrylk (call_frame_t *frame, xlator_t *this,  	op_ret = 0;  out: +        pl_update_refkeeper (this, fd->inode);  	if (unwind) {  		STACK_UNWIND (frame, op_ret, op_errno);  	} diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h index 65da3a3650a..fe1333504ad 100644 --- a/xlators/features/locks/src/locks.h +++ b/xlators/features/locks/src/locks.h @@ -89,6 +89,9 @@ struct __pl_inode {  	struct list_head int_list;       /* list of internal locks */  	struct list_head rw_list;        /* list of waiting r/w requests */  	int              mandatory;      /* if mandatory locking is enabled */ + +        inode_t          *refkeeper;     /* hold refs on an inode while locks are +                                            held to prevent pruning */  };  typedef struct __pl_inode pl_inode_t; diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index f963d5c9316..b1eb7e43518 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -687,6 +687,7 @@ pl_lk (call_frame_t *frame, xlator_t *this,  	}  unwind: +        pl_update_refkeeper (this, fd->inode);  	STACK_UNWIND (frame, op_ret, op_errno, flock);  out:  	return 0;  | 
