From: <tak...@us...> - 2012-10-24 07:47:39
|
Revision: 6924 http://gfarm.svn.sourceforge.net/gfarm/?rev=6924&view=rev Author: takuya-i Date: 2012-10-24 07:47:28 +0000 (Wed, 24 Oct 2012) Log Message: ----------- * limit the gfarm.ncopy xattr less than or equal to the number of registered gfsd hosts. (revise r6703 for #453 - replica_check: check and fix the number of replicas automatically) * simplify inode_has_desired_number(), and reduce malloc() Revision Links: -------------- http://gfarm.svn.sourceforge.net/gfarm/?rev=6703&view=rev Modified Paths: -------------- gfarm_v2/branches/2.5/server/gfmd/host.c gfarm_v2/branches/2.5/server/gfmd/host.h gfarm_v2/branches/2.5/server/gfmd/inode.c gfarm_v2/branches/2.5/server/gfmd/inode.h gfarm_v2/branches/2.5/server/gfmd/xattr.c Modified: gfarm_v2/branches/2.5/server/gfmd/host.c =================================================================== --- gfarm_v2/branches/2.5/server/gfmd/host.c 2012-10-24 07:24:56 UTC (rev 6923) +++ gfarm_v2/branches/2.5/server/gfmd/host.c 2012-10-24 07:47:28 UTC (rev 6924) @@ -1007,6 +1007,26 @@ } /* + * PREREQUISITE: giant_lock + * LOCKS: host::back_channel_mutex + * SLEEPS: no + */ +int +host_number() +{ + struct gfarm_hash_iterator it; + struct host *h; + int nhosts = 0; + + FOR_ALL_HOSTS(&it) { + h = host_iterator_access(&it); + if (host_is_valid(h)) + ++nhosts; + } + return (nhosts); +} + +/* * just select randomly XXX FIXME: needs to improve */ static void Modified: gfarm_v2/branches/2.5/server/gfmd/host.h =================================================================== --- gfarm_v2/branches/2.5/server/gfmd/host.h 2012-10-24 07:24:56 UTC (rev 6923) +++ gfarm_v2/branches/2.5/server/gfmd/host.h 2012-10-24 07:47:28 UTC (rev 6924) @@ -62,6 +62,7 @@ gfarm_error_t host_array_alloc(int *, struct host ***); gfarm_error_t host_from_all(int (*)(struct host *, void *), void *, gfarm_int32_t *, struct host ***); +int host_number(); gfarm_error_t host_from_all_except(int *, struct host **, int (*)(struct host *, void *), void *, gfarm_int32_t *, struct host ***); Modified: gfarm_v2/branches/2.5/server/gfmd/inode.c =================================================================== --- gfarm_v2/branches/2.5/server/gfmd/inode.c 2012-10-24 07:24:56 UTC (rev 6923) +++ gfarm_v2/branches/2.5/server/gfmd/inode.c 2012-10-24 07:47:28 UTC (rev 6924) @@ -5664,22 +5664,13 @@ return GFARM_ERR_NO_ERROR; } -/* This assumes that the "gfarm.ncopy" xattr is cached. */ int -inode_has_desired_number(struct inode *inode, int *desired_numberp) +inode_xattr_convert_desired_number( + const void *value, size_t size, int *desired_numberp) { - void *value; - size_t size; - unsigned char *s; int i, n; + const unsigned char *s = value; - if (inode_xattr_get_cache(inode, 0, "gfarm.ncopy", &value, &size) != - GFARM_ERR_NO_ERROR) - return (0); - - if (value == NULL) - return (0); - s = value; for (i = 0; i < size && isspace(s[i]); i++) ; if (i < size && isdigit(s[i])) { @@ -5687,14 +5678,24 @@ for (; i < size && isdigit(s[i]); i++) n = n * 10 + (s[i] - '0'); *desired_numberp = n; - free(value); return (1); } - free(value); return (0); } +/* This assumes that the "gfarm.ncopy" xattr is cached. */ int +inode_has_desired_number(struct inode *inode, int *desired_numberp) +{ + struct xattr_entry *ent = xattr_find(&inode->i_xattrs, "gfarm.ncopy"); + + if (ent == NULL || ent->cached_attrvalue == NULL) + return (0); + return (inode_xattr_convert_desired_number( + ent->cached_attrvalue, ent->cached_attrsize, desired_numberp)); +} + +int inode_traverse_desired_replica_number(struct inode *dir, int *desired_numberp) { DirEntry entry; Modified: gfarm_v2/branches/2.5/server/gfmd/inode.h =================================================================== --- gfarm_v2/branches/2.5/server/gfmd/inode.h 2012-10-24 07:24:56 UTC (rev 6923) +++ gfarm_v2/branches/2.5/server/gfmd/inode.h 2012-10-24 07:47:28 UTC (rev 6924) @@ -211,6 +211,7 @@ gfarm_error_t inode_xattr_list_get_cached_by_patterns(gfarm_ino_t, char **, int, struct xattr_list **, size_t *); +int inode_xattr_convert_desired_number(const void *, size_t, int *); int inode_has_desired_number(struct inode *, int *); int inode_traverse_desired_replica_number(struct inode *, int *); Modified: gfarm_v2/branches/2.5/server/gfmd/xattr.c =================================================================== --- gfarm_v2/branches/2.5/server/gfmd/xattr.c 2012-10-24 07:24:56 UTC (rev 6923) +++ gfarm_v2/branches/2.5/server/gfmd/xattr.c 2012-10-24 07:47:28 UTC (rev 6924) @@ -34,6 +34,7 @@ #include "dir.h" #include "acl.h" #include "user.h" +#include "host.h" #include "replica_check.h" #include "gfm_proto.h" @@ -195,12 +196,51 @@ } static gfarm_error_t +xattr_check_desired_number( + int xmlMode, struct inode *inode, const char *attrname, + const void *value, size_t size, int *have, int *change) +{ + int num_new, num_old, num_host; + + if (xmlMode || strcmp("gfarm.ncopy", attrname) != 0) { + *have = 0; + *change = 0; + return (GFARM_ERR_NO_ERROR); + } + if (!inode_xattr_convert_desired_number(value, size, &num_new) || + num_new < 0) { + gflog_debug(GFARM_MSG_UNFIXED, + "invalid format for gfarm.ncopy"); + return (GFARM_ERR_INVALID_ARGUMENT); + } + num_host = host_number(); + if (num_new > num_host) { + gflog_debug(GFARM_MSG_UNFIXED, + "too large number of gfarm.ncopy: %d > num_host(%d)", + num_new, num_host); + return (GFARM_ERR_VALUE_TOO_LARGE_TO_BE_STORED_IN_DATA_TYPE); + } + if (inode_has_desired_number(inode, &num_old) && + num_new == num_old) { + *have = 1; + *change = 0; + gflog_debug(GFARM_MSG_UNFIXED, + "gfarm.ncopy=%d: not changed", num_new); + return (GFARM_ERR_NO_ERROR); + } + *have = 1; + *change = 1; + return (GFARM_ERR_NO_ERROR); /* update */ +} + +static gfarm_error_t setxattr(int xmlMode, struct inode *inode, char *attrname, void **valuep, size_t size, int flags, struct db_waitctx *waitctx, int *addattr) { gfarm_error_t e; void *value; + int have_ncopy, change_ncopy; *addattr = 0; if (!isvalid_attrname(attrname)) { @@ -218,6 +258,16 @@ return GFARM_ERR_ILLEGAL_BYTE_SEQUENCE; } + e = xattr_check_desired_number( + xmlMode, inode, attrname, *valuep, size, + &have_ncopy, &change_ncopy); + if (e != GFARM_ERR_NO_ERROR) { + gflog_debug(GFARM_MSG_UNFIXED, + "xattr_check_desired_number(): %s", gfarm_error_string(e)); + return (e); + } else if (have_ncopy && !change_ncopy) + return (GFARM_ERR_NO_ERROR); /* not add/modify */ + if (!xmlMode) { gfarm_acl_type_t acltype; if (strcmp(attrname, GFARM_ACL_EA_ACCESS) == 0) @@ -292,6 +342,8 @@ return (e); } } + if (change_ncopy) + replica_check_signal_update_xattr(); if (*addattr) { e = db_xattr_add(xmlMode, inode_get_number(inode), @@ -303,20 +355,6 @@ return e; } -static int -xattr_ncopy_compare( - int xmlMode, struct inode *inode, const char *attrname, - const void *value, size_t size) -{ - if (!xmlMode && - strcmp("gfarm.ncopy", attrname) == 0) { - if (!inode_xattr_cache_is_same( - inode, xmlMode, attrname, value, size)) - return (1); /* different value */ - } - return (0); -} - gfarm_error_t gfm_server_setxattr(struct peer *peer, int from_client, int skip, int xmlMode) { @@ -331,7 +369,7 @@ gfarm_int32_t fd; struct inode *inode; struct db_waitctx ctx, *waitctx; - int addattr, change_ncopy = 0; + int addattr; e = gfm_server_get_request(peer, diag, "sBi", &attrname, &size, &value, &flags); @@ -386,18 +424,12 @@ gflog_debug(GFARM_MSG_1003035, "xattr_access() failed: %s", gfarm_error_string(e)); - } else { - change_ncopy = xattr_ncopy_compare( - xmlMode, inode, attrname, value, size); + } else e = setxattr(xmlMode, inode, attrname, &value, size, flags, waitctx, &addattr); - } giant_unlock(); if (e == GFARM_ERR_NO_ERROR) { - if (change_ncopy) - replica_check_signal_update_xattr(); - e = dbq_waitret(waitctx); if (e == GFARM_ERR_NO_ERROR) { giant_lock(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |