diff options
| -rw-r--r-- | xlators/features/locks/src/common.c | 53 | ||||
| -rw-r--r-- | xlators/features/locks/src/common.h | 2 | ||||
| -rw-r--r-- | xlators/features/locks/src/entrylk.c | 1 | ||||
| -rw-r--r-- | xlators/features/locks/src/inodelk.c | 1 | ||||
| -rw-r--r-- | xlators/features/locks/src/locks.h | 15 | ||||
| -rw-r--r-- | xlators/features/locks/src/posix.c | 1 | 
6 files changed, 66 insertions, 7 deletions
diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c index 08dc451e1..b9037688a 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 @@ -43,7 +44,7 @@ static void  __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock);  static pl_dom_list_t * -allocate_domain(const char *volume) +allocate_domain (const char *volume)  {          pl_dom_list_t *dom = NULL; @@ -95,6 +96,56 @@ found:          return dom;  } + +int +__pl_inode_is_empty (pl_inode_t *pl_inode) +{ +        pl_dom_list_t *dom = NULL; +        int            is_empty = 1; + +        if (!list_empty (&pl_inode->ext_list)) +                is_empty = 0; + +        list_for_each_entry (dom, &pl_inode->dom_list, inode_list) { +                if (!list_empty (&dom->entrylk_list)) +                        is_empty = 0; + +                if (!list_empty (&dom->inodelk_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 fabe8bd84..59201c907 100644 --- a/xlators/features/locks/src/common.h +++ b/xlators/features/locks/src/common.h @@ -65,4 +65,6 @@ void  grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,  			   pl_entry_lock_t *unlocked, pl_dom_list_t *dom); +void pl_update_refkeeper (xlator_t *this, inode_t *inode); +  #endif /* __COMMON_H__ */ diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c index f1536f803..e22a8305d 100644 --- a/xlators/features/locks/src/entrylk.c +++ b/xlators/features/locks/src/entrylk.c @@ -534,6 +534,7 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,  	op_ret = 0;  out: +        pl_update_refkeeper (this, inode);  	if (unwind) {  		STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);  	} diff --git a/xlators/features/locks/src/inodelk.c b/xlators/features/locks/src/inodelk.c index 4c76f64bb..1cb2c9522 100644 --- a/xlators/features/locks/src/inodelk.c +++ b/xlators/features/locks/src/inodelk.c @@ -525,6 +525,7 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,  	op_ret = 0;  unwind: +        pl_update_refkeeper (this, inode);  	STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);  out:  	return 0; diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h index 4ad16c714..9d030f15e 100644 --- a/xlators/features/locks/src/locks.h +++ b/xlators/features/locks/src/locks.h @@ -86,12 +86,12 @@ struct __pl_rw_req_t {  typedef struct __pl_rw_req_t pl_rw_req_t;  struct __pl_dom_list_t { -        const char *domain; -        struct list_head inode_list;       /* list_head back to pl_inode_t */ -        struct list_head entrylk_list;     /* List of entry locks */ -        struct list_head blocked_entrylks; /* List of all blocked entrylks */ -        struct list_head inodelk_list;     /* List of inode locks */ -        struct list_head blocked_inodelks; /* List of all blocked inodelks */ +        struct list_head   inode_list;       /* list_head back to pl_inode_t */ +        const char        *domain; +        struct list_head   entrylk_list;     /* List of entry locks */ +        struct list_head   blocked_entrylks; /* List of all blocked entrylks */ +        struct list_head   inodelk_list;     /* List of inode locks */ +        struct list_head   blocked_inodelks; /* List of all blocked inodelks */  };  typedef struct __pl_dom_list_t pl_dom_list_t; @@ -123,6 +123,9 @@ struct __pl_inode {  	struct list_head ext_list;       /* list of fcntl 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 f2e73b9cb..50958a2ed 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -686,6 +686,7 @@ pl_lk (call_frame_t *frame, xlator_t *this,  	}  unwind: +        pl_update_refkeeper (this, fd->inode);  	STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, flock);  out:  	return 0;  | 
