int fs_link(const char *srcpath, const char *dstpath) { struct inode *ino; int r; if ((r = inode_open(srcpath, &ino)) < 0) return r; if (S_ISDIR(ino->i_mode)) return -EPERM; ino->i_ctime = time(NULL); return inode_link(srcpath, dstpath); }
int glfsh_link_inode_update_loc (loc_t *loc, struct iatt *iattr) { inode_t *link_inode = NULL; int ret = -1; link_inode = inode_link (loc->inode, NULL, NULL, iattr); if (link_inode == NULL) goto out; inode_unref (loc->inode); loc->inode = link_inode; ret = 0; out: return ret; }
int fs_rename(const char *srcpath, const char *dstpath) { int r; link_retry: if ((r = inode_link(srcpath, dstpath)) < 0) switch(-r) { case EEXIST: if (strcmp(srcpath, dstpath) == 0) return 0; if ((r = inode_unlink(dstpath)) < 0) return r; goto link_retry; default: return r; } return inode_unlink(srcpath); }
struct glfs_object * glfs_h_create_from_handle (struct glfs *fs, unsigned char *handle, int len, struct stat *stat) { loc_t loc = {0, }; int ret = -1; struct iatt iatt = {0, }; inode_t *newinode = NULL; xlator_t *subvol = NULL; struct glfs_object *object = NULL; /* validate in args */ if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) { errno = EINVAL; return NULL; } __glfs_entry_fs (fs); /* get the active volume */ subvol = glfs_active_subvol (fs); if (!subvol) { errno = EIO; goto out; } memcpy (loc.gfid, handle, GFAPI_HANDLE_LENGTH); newinode = inode_find (subvol->itable, loc.gfid); if (newinode) loc.inode = newinode; else { loc.inode = inode_new (subvol->itable); if (!loc.inode) { errno = ENOMEM; goto out; } } ret = syncop_lookup (subvol, &loc, 0, &iatt, 0, 0); DECODE_SYNCOP_ERR (ret); if (ret) { gf_log (subvol->name, GF_LOG_WARNING, "inode refresh of %s failed: %s", uuid_utoa (loc.gfid), strerror (errno)); goto out; } newinode = inode_link (loc.inode, 0, 0, &iatt); if (newinode) inode_lookup (newinode); else { gf_log (subvol->name, GF_LOG_WARNING, "inode linking of %s failed: %s", uuid_utoa (loc.gfid), strerror (errno)); errno = EINVAL; goto out; } /* populate stat */ if (stat) glfs_iatt_to_stat (fs, &iatt, stat); object = GF_CALLOC (1, sizeof(struct glfs_object), glfs_mt_glfs_object_t); if (object == NULL) { errno = ENOMEM; ret = -1; goto out; } /* populate the return object */ object->inode = newinode; uuid_copy (object->gfid, object->inode->gfid); out: /* TODO: Check where the inode ref is being held? */ loc_wipe (&loc); glfs_subvol_done (fs, subvol); return object; }
void fs_test(void) { struct inode *ino, *ino2; int r; char *blk; uint32_t bits[4096]; // back up bitmap memmove(bits, bitmap, 4096); // allocate block if ((r = alloc_block()) < 0) panic("alloc_block: %s", strerror(-r)); // check that block was free assert(bits[r/32] & (1 << (r%32))); // and is not free any more assert(!(bitmap[r/32] & (1 << (r%32)))); free_block(r); printf("alloc_block is good\n"); if ((r = inode_open("/not-found", &ino)) < 0 && r != -ENOENT) panic("inode_open /not-found: %s", strerror(-r)); else if (r == 0) panic("inode_open /not-found succeeded!"); if ((r = inode_open("/msg", &ino)) < 0) panic("inode_open /msg: %s", strerror(-r)); printf("inode_open is good\n"); if ((r = inode_get_block(ino, 0, &blk)) < 0) panic("inode_get_block: %s", strerror(-r)); if (strcmp(blk, msg) != 0) panic("inode_get_block returned wrong data"); printf("inode_get_block is good\n"); if ((r = inode_set_size(ino, 0)) < 0) panic("inode_set_size: %s", strerror(-r)); assert(ino->i_direct[0] == 0); printf("inode_truncate is good\n"); if ((r = inode_set_size(ino, strlen(msg))) < 0) panic("inode_set_size 2: %s", strerror(-r)); if ((r = inode_get_block(ino, 0, &blk)) < 0) panic("inode_get_block 2: %s", strerror(-r)); strcpy(blk, msg); printf("file rewrite is good\n"); if ((r = inode_link("/msg", "/linkmsg")) < 0) panic("inode_link /msg /linkmsg: %s", strerror(-r)); if ((r = inode_open("/msg", &ino)) < 0) panic("inode_open /msg: %s", strerror(-r)); if ((r = inode_open("/linkmsg", &ino2)) < 0) panic("inode_open /linkmsg: %s", strerror(-r)); if (ino != ino2) panic("linked files do not point to same inode"); if (ino->i_nlink != 2) panic("link count incorrect: %u, expected 2", ino->i_nlink); printf("inode_link is good\n"); if ((r = inode_unlink("/linkmsg")) < 0) panic("inode_unlink /linkmsg: %s", strerror(-r)); if ((r = inode_open("/linkmsg", &ino2)) < 0 && r != -ENOENT) panic("inode_open /linkmsg after unlink: %s", strerror(-r)); else if (r == 0) panic("inode_open /linkmsg after unlink succeeded!"); if ((r = inode_open("/msg", &ino)) < 0) panic("inode_open /msg after /linkmsg unlinked: %s", strerror(-r)); if (ino->i_nlink != 1) panic("link count incorrect: %u, expected 1", ino->i_nlink); printf("inode_unlink is good\n"); }