diff options
| author | Pranith Kumar K <pranithk@gluster.com> | 2012-04-16 14:42:56 +0530 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2012-05-31 16:53:00 -0700 | 
| commit | 4bc0fa312f8a64c7ee0f52e5635d7f082454aaa2 (patch) | |
| tree | 0942b392b9d795419722d3e9119726e36b1cb580 /xlators/storage/posix/src/posix.c | |
| parent | d2ac835ba0d51ce1679dc71640472eecbfbaa704 (diff) | |
storage/posix: Prevent gfid handle leaks
The case which can lead to gfid handle leaks:
Self-heal removes directory '/d' with 10 files in it, in brick b1.
This dir is renamed to <landfill>/<hashval of '<brick-path>/d'>
by posix. Before the janitor thread could remove the directory,
self-heal could remove another directory with same path '/d'.
Then again the rename to same path is done by posix as before.
The gfid-handles of the old '/d', 10 files in it are not unlinked.
To prevent such problems, rename the directory to be removed to
<landfill>/<gfid-str>.
Change-Id: Iad13708e1ebcc5222b64c058aa9a2d372e1bfa5b
BUG: 811970
Signed-off-by: Pranith Kumar K <pranithk@gluster.com>
Reviewed-on: http://review.gluster.com/3159
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators/storage/posix/src/posix.c')
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 10 | 
1 files changed, 6 insertions, 4 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 5bfaa4214cc..e18654cc728 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -1120,6 +1120,7 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,          int32_t op_errno  = 0;          char *  real_path = NULL;          char *  par_path = NULL; +        char *  gfid_str = NULL;          struct iatt   preparent = {0,};          struct iatt   postparent = {0,};          struct iatt   stbuf; @@ -1159,12 +1160,13 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,          }          if (flags) { -                uint32_t hashval = 0; -                char *tmp_path = alloca (strlen (priv->trash_path) + 16); +                gfid_str = uuid_utoa (stbuf.ia_gfid); +                char *tmp_path = alloca (strlen (priv->trash_path) + +                                         strlen ("/") + +                                         strlen (gfid_str) + 1);                  mkdir (priv->trash_path, 0755); -                hashval = gf_dm_hashfn (real_path, strlen (real_path)); -                sprintf (tmp_path, "%s/%u", priv->trash_path, hashval); +                sprintf (tmp_path, "%s/%s", priv->trash_path, gfid_str);                  op_ret = rename (real_path, tmp_path);          } else {                  op_ret = rmdir (real_path);  | 
