diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-08-04 11:59:38 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-08-04 11:59:38 -0400 |
commit | 97211d29da7769ff979958cb8048f83519cf79f2 (patch) | |
tree | 22d4abfc6e6330d88085cf9d6c4d8a1f27258f2a | |
parent | b58893ba71bd2608ca19564f2f74269462588770 (diff) | |
download | dbfs-97211d29da7769ff979958cb8048f83519cf79f2.tar.gz |
xattr removal fix, cleanup.
fix: when xattr name list becomes empty, delete the node from the
database.
cleanup: use dbmeta_del() when removing an xattr, removing some
duplicate code.
-rw-r--r-- | dbfs-backend.c | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/dbfs-backend.c b/dbfs-backend.c index 0f1b2e9..43ee6f0 100644 --- a/dbfs-backend.c +++ b/dbfs-backend.c @@ -663,6 +663,7 @@ static int dbfs_xattr_list_del(guint64 ino, const char *name) long bytes; void *mem; size_t ssize = 0; + unsigned int entries = 0; /* get list from db */ rc = dbfs_xattr_list_read(&key, &val, keystr, ino); @@ -675,6 +676,7 @@ static int dbfs_xattr_list_del(guint64 ino, const char *name) mem = val.data; bytes = val.size; while (bytes > 0) { + entries++; ent = mem; ssize = dbfs_xlist_next(GUINT32_FROM_LE(ent->namelen)); if (ssize > bytes) { /* data corrupt */ @@ -694,12 +696,19 @@ static int dbfs_xattr_list_del(guint64 ino, const char *name) goto out; } - /* swallow entry */ - memmove(mem, mem + ssize, bytes - ssize); - val.size -= ssize; + /* if at least one entry will exist post-delete, update db */ + if (entries > 1) { + /* swallow entry */ + memmove(mem, mem + ssize, bytes - ssize); + val.size -= ssize; - /* store new list in db */ - rc = gfs->meta->put(gfs->meta, NULL, &key, &val, 0) ? -EIO : 0; + /* store new list in db */ + rc = gfs->meta->put(gfs->meta, NULL, &key, &val, 0) ? -EIO : 0; + } + + /* otherwise, delete db entry */ + else + rc = dbmeta_del(keystr); out: free(val.data); @@ -866,25 +875,16 @@ int dbfs_xattr_set(guint64 ino_n, const char *name, const void *buf, int dbfs_xattr_remove(guint64 ino_n, const char *name, gboolean update_list) { char key_str[DBFS_XATTR_NAME_LEN + 32]; - DBT key; - int rc; snprintf(key_str, sizeof(key_str), "/xattr/%Lu/%s", (unsigned long long) ino_n, name); - memset(&key, 0, sizeof(key)); - key.data = key_str; - key.size = strlen(key_str); - if (update_list) { - rc = dbfs_xattr_list_del(ino_n, name); + int rc = dbfs_xattr_list_del(ino_n, name); if (rc) return rc; } - rc = gfs->meta->del(gfs->meta, NULL, &key, 0); - if (rc == DB_NOTFOUND) - return -ENOENT; - return rc ? -EIO : 0; + return dbmeta_del(key_str); } |