diff options
| author | Anand Avati <avati@gluster.com> | 2011-05-31 01:30:02 +0000 | 
|---|---|---|
| committer | Anand Avati <avati@gluster.com> | 2011-05-31 09:11:41 -0700 | 
| commit | 9dcb29b5abfc0f221890780901fc855acd73ba48 (patch) | |
| tree | 0f3190b0055ea3f122c3737754ba522ba6a5dbf2 | |
| parent | 537b65f44dfa463cc1a522f5ad5f1fc9f11d99a6 (diff) | |
cluster/dht: detect linkfiles mismatching gfid and delete+recreate
Signed-off-by: Anand Avati <avati@gluster.com>
BUG: 2522 ([glusterfs-3.1.3qa8]: rm -rf shows invalid argument)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2522
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 182 | 
1 files changed, 109 insertions, 73 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index d4b5a7211..8a0897bd1 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -520,6 +520,101 @@ unwind:  	return 0;  } +int +dht_lookup_everywhere_done (call_frame_t *frame, xlator_t *this) +{ +        int           ret = 0; +        dht_local_t  *local = NULL; +        xlator_t     *hashed_subvol = NULL; +        xlator_t     *cached_subvol = NULL; + + +        local = frame->local; +        hashed_subvol = local->hashed_subvol; +        cached_subvol = local->cached_subvol; + +        if (local->file_count && local->dir_count) { +                gf_log (this->name, GF_LOG_ERROR, +                        "path %s exists as a file on one subvolume " +                        "and directory on another. " +                        "Please fix it manually", +                        local->loc.path); +                DHT_STACK_UNWIND (lookup, frame, -1, EIO, NULL, NULL, NULL, +                                  NULL); +                return 0; +        } + +        if (local->dir_count) { +                dht_lookup_directory (frame, this, &local->loc); +                return 0; +        } + +        if (!cached_subvol) { +                DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, NULL, NULL, NULL, +                                  NULL); +                return 0; +        } +        if (!hashed_subvol) { +                gf_log (this->name, GF_LOG_INFO, +                        "cannot create linkfile file for %s on %s: " +                        "hashed subvolume cannot be found.", +                        local->loc.path, cached_subvol->name); + +                local->op_ret = 0; +                local->op_errno = 0; + +                ret = dht_layout_preset (frame->this, cached_subvol, +                                         local->inode); +                if (ret < 0) { +                        gf_log (this->name, GF_LOG_INFO, +                                "failed to set layout for subvol %s", +                                cached_subvol ? cached_subvol->name : +                                "<nil>"); +                        local->op_ret = -1; +                        local->op_errno = EINVAL; +                } + +                if (local->loc.parent) +                        local->postparent.ia_ino = +                                local->loc.parent->ino; + +                WIPE (&local->postparent); + +                DHT_STACK_UNWIND (lookup, frame, local->op_ret, +                                  local->op_errno, local->inode, +                                  &local->stbuf, local->xattr, +                                  &local->postparent); +                return 0; +        } + +        gf_log (this->name, GF_LOG_DEBUG, +                "linking file %s existing on %s to %s (hash)", +                local->loc.path, cached_subvol->name, +                hashed_subvol->name); + +        ret = dht_linkfile_create (frame, +                                   dht_lookup_linkfile_create_cbk, +                                   cached_subvol, hashed_subvol, &local->loc); + +        return ret; +} + + +int +dht_lookup_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                       int op_ret, int op_errno, +                       struct iatt *preparent, struct iatt *postparent) +{ +        int  this_call_cnt = 0; + +        this_call_cnt = dht_frame_return (frame); +        if (is_last_call (this_call_cnt)) { +                dht_lookup_everywhere_done (frame, this); +        } + +        return 0; +} +  int  dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -536,9 +631,6 @@ dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this,  	xlator_t     *subvol        = NULL;  	loc_t        *loc           = NULL;  	xlator_t     *link_subvol   = NULL; -	xlator_t     *hashed_subvol = NULL; -	xlator_t     *cached_subvol = NULL; -        int           ret = -1;  	conf   = this->private; @@ -556,7 +648,7 @@ dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this,  			goto unlock;  		}                  if (uuid_is_null (local->gfid)) -                        memcpy (local->gfid, buf->ia_gfid, 16); +                        uuid_copy (local->gfid, buf->ia_gfid);  		is_linkfile = check_is_linkfile (inode, buf, xattr);  		is_dir = check_is_dir (inode, buf, xattr); @@ -607,78 +699,15 @@ unlock:  		gf_log (this->name, GF_LOG_DEBUG,  			"deleting stale linkfile %s on %s",  			loc->path, subvol->name); -		dht_linkfile_unlink (frame, this, subvol, loc); -	} +	        STACK_WIND (frame, dht_lookup_unlink_cbk, +                            subvol, subvol->fops->unlink, loc); +                return 0; +        }  	this_call_cnt = dht_frame_return (frame);  	if (is_last_call (this_call_cnt)) { -		hashed_subvol = local->hashed_subvol; -		cached_subvol = local->cached_subvol; - -                if (local->file_count && local->dir_count) { -                        gf_log (this->name, GF_LOG_ERROR, -                                "path %s exists as a file on one subvolume "  -                                "and directory on another. " -                                "Please fix it manually", -                                loc->path); -                        DHT_STACK_UNWIND (lookup, frame, -1, EIO, NULL, NULL, NULL, -                                          NULL); -                        return 0; -                } - -                if (local->dir_count) { -                        dht_lookup_directory (frame, this, &local->loc); -                        return 0; -                } - -		if (!cached_subvol) { -			DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, NULL, NULL, NULL, -                                          NULL); -			return 0; -		} - -                if (!hashed_subvol) { -                        gf_log (this->name, GF_LOG_DEBUG, -                                "cannot create linkfile file for %s on %s: " -                                "hashed subvolume cannot be found.", -                                loc->path, cached_subvol->name); -                         -                        local->op_ret = 0; -                        local->op_errno = 0; - -                        ret = dht_layout_preset (frame->this, cached_subvol, -                                                 local->inode); -                        if (ret < 0) { -                                gf_log (this->name, GF_LOG_DEBUG, -                                        "failed to set layout for subvol %s", -                                        cached_subvol ? cached_subvol->name : -                                        "<nil>"); -                                local->op_ret = -1; -                                local->op_errno = EINVAL; -                        } - -                        if (local->loc.parent) -                                local->postparent.ia_ino = -                                        local->loc.parent->ino; - -                        WIPE (&local->postparent); - -                        DHT_STACK_UNWIND (lookup, frame, local->op_ret, -                                          local->op_errno, local->inode, -                                          &local->stbuf, local->xattr, -                                          &local->postparent); -                        return 0; -                } - -                gf_log (this->name, GF_LOG_DEBUG, -                        "linking file %s existing on %s to %s (hash)", -                        loc->path, cached_subvol->name, -                        hashed_subvol->name); -                         -                dht_linkfile_create (frame,  -                                     dht_lookup_linkfile_create_cbk, -                                     cached_subvol, hashed_subvol, loc); -	} +                dht_lookup_everywhere_done (frame, this); +        }  	return 0;  } @@ -757,6 +786,13 @@ dht_lookup_linkfile_cbk (call_frame_t *frame, void *cookie,                  goto err;          } +        if (uuid_compare (local->gfid, stbuf->ia_gfid)) { +                gf_log (this->name, GF_LOG_WARNING, +                        "%s: gfid different on data file on %s", +                        local->loc.path, subvol->name); +                goto err; +        } +  	if ((stbuf->ia_nlink == 1)  	    && (conf && conf->unhashed_sticky_bit)) {  		stbuf->ia_prot.sticky = 1;  | 
