return str->size;
}
+/*
+ * returns 0 if fid got re-opened, 1 if not, < 0 on error */
+static int v9fs_reopen_fid(V9fsState *s, V9fsFidState *f)
+{
+ int err = 1;
+ if (f->fid_type == P9_FID_FILE) {
+ if (f->fs.fd == -1) {
+ do {
+ err = v9fs_co_open(s, f, f->open_flags);
+ } while (err == -EINTR);
+ }
+ } else if (f->fid_type == P9_FID_DIR) {
+ if (f->fs.dir == NULL) {
+ do {
+ err = v9fs_co_opendir(s, f);
+ } while (err == -EINTR);
+ }
+ }
+ return err;
+}
+
static V9fsFidState *get_fid(V9fsState *s, int32_t fid)
{
int err;
* in open later.
*/
f->ref++;
-
/*
* check whether we need to reopen the
* file. We might have closed the fd
* while trying to free up some file
* descriptors.
*/
- if (f->fid_type == P9_FID_FILE) {
- if (f->fs.fd == -1) {
- do {
- err = v9fs_co_open(s, f, f->open_flags);
- } while (err == -EINTR);
- if (err < 0) {
- f->ref--;
- return NULL;
- }
- }
+ err = v9fs_reopen_fid(s, f);
+ if (err < 0) {
+ f->ref--;
+ return NULL;
}
/*
* Mark the fid as referenced so that the LRU
retval = v9fs_co_close(s, fidp->fs.fd);
}
} else if (fidp->fid_type == P9_FID_DIR) {
- retval = v9fs_co_closedir(s, fidp->fs.dir);
+ if (fidp->fs.dir != NULL) {
+ retval = v9fs_co_closedir(s, fidp->fs.dir);
+ }
} else if (fidp->fid_type == P9_FID_XATTR) {
retval = v9fs_xattr_fid_clunk(s, fidp);
}
f->fs.fd = -1;
reclaim_count++;
}
+ } else if (f->fid_type == P9_FID_DIR) {
+ if (f->fs.dir != NULL) {
+ /*
+ * Up the reference count so that
+ * a clunk request won't free this fid
+ */
+ f->ref++;
+ f->rclm_lst = reclaim_list;
+ reclaim_list = f;
+ f->fs_reclaim.dir = f->fs.dir;
+ f->fs.dir = NULL;
+ reclaim_count++;
+ }
}
if (reclaim_count >= open_fd_rc) {
break;
reclaim_list = f->rclm_lst;
if (f->fid_type == P9_FID_FILE) {
v9fs_co_close(s, f->fs_reclaim.fd);
+ } else if (f->fid_type == P9_FID_DIR) {
+ v9fs_co_closedir(s, f->fs_reclaim.dir);
}
f->rclm_lst = NULL;
/*
if (!strcmp(fidp->path.data, str->data)) {
/* Mark the fid non reclaimable. */
fidp->flags |= FID_NON_RECLAIMABLE;
- /* reopen the file if already closed */
- if (fidp->fs.fd == -1) {
- do {
- err = v9fs_co_open(s, fidp, fidp->open_flags);
- } while (err == -EINTR);
- if (err < 0) {
- return -1;
- }
- /*
- * Go back to head of fid list because
- * the list could have got updated when
- * switched to the worker thread
- */
+
+ /* reopen the file/dir if already closed */
+ err = v9fs_reopen_fid(s, fidp);
+ if (err < 0) {
+ return -1;
+ }
+ /*
+ * Go back to head of fid list because
+ * the list could have got updated when
+ * switched to the worker thread
+ */
+ if (err == 0) {
fidp = &head_fid;
}
}
{
size_t size;
+ memset(&qidp->path, 0, sizeof(qidp->path));
size = MIN(sizeof(stbuf->st_ino), sizeof(qidp->path));
memcpy(&qidp->path, &stbuf->st_ino, size);
qidp->version = stbuf->st_mtime ^ (stbuf->st_size << 8);
if (err < 0) {
fidp->fid_type = P9_FID_NONE;
if (fidp->fs.fd > 0) {
- close(fidp->fs.fd);
+ v9fs_co_close(pdu->s, fidp->fs.fd);
}
goto out;
}
if (err < 0) {
goto out;
}
+ v9fs_string_copy(&fidp->path, &fullname);
err = v9fs_co_opendir(pdu->s, fidp);
if (err < 0) {
goto out;
if (err < 0) {
fidp->fid_type = P9_FID_NONE;
if (fidp->fs.fd) {
- close(fidp->fs.fd);
+ v9fs_co_close(pdu->s, fidp->fs.fd);
}
goto out;
}
err = offset;
err += pdu_marshal(pdu, offset, "b", status);
complete_pdu(s, pdu, err);
+ v9fs_string_free(&flock->client_id);
g_free(flock);
}
put_fid(s, fidp);
out_nofid:
complete_pdu(s, pdu, err);
+ v9fs_string_free(&glock->client_id);
g_free(glock);
}