return TRUE;
}
+/* Arrange for a reference to an inode to be dropped when the RPC request
+ * completes. */
+void schedule_inode_unref(RPCRequest *req, BlueSkyInode *inode)
+{
+ struct cleanup_list *c = g_new(struct cleanup_list, 1);
+ c->func = (void (*)(void *))bluesky_inode_unref;
+ c->arg = inode;
+ c->next = req->cleanup;
+ req->cleanup = c;
+}
+
/* Look up a BlueSkyInode given an NFS filehandle. Returns NULL if the
* filehandle is invalid. */
-BlueSkyInode *lookup_fh(nfs_fh3 *fh)
+BlueSkyInode *lookup_fh(RPCRequest *req, nfs_fh3 *fh)
{
BlueSkyInode *inode = NULL;
if (fh->data.data_len == 8) {
uint64_t inum = GUINT64_FROM_BE(*(uint64_t *)(fh->data.data_val));
inode = bluesky_get_inode(fs, inum);
+ if (inode != NULL)
+ schedule_inode_unref(req, inode);
}
return inode;
}
getattr3res result;
memset(&result, 0, sizeof(result));
- BlueSkyInode *inode = lookup_fh(argp);
+ BlueSkyInode *inode = lookup_fh(req, argp);
if (inode != NULL) {
result.status = NFS3_OK;
encode_fattr3(&result.getattr3res_u.attributes, inode);
result.wccstat3_u.wcc.before.present = FALSE;
result.wccstat3_u.wcc.after.present = FALSE;
- BlueSkyInode *inode = lookup_fh(&argp->object);
+ BlueSkyInode *inode = lookup_fh(req, &argp->object);
if (inode == NULL) {
result.status = NFS3ERR_STALE;
async_rpc_send_reply(req, &result);
lookup3res result;
memset(&result, 0, sizeof(result));
- BlueSkyInode *dir = lookup_fh(&argp->dir);
+ BlueSkyInode *dir = lookup_fh(req, &argp->dir);
if (dir == NULL) {
result.status = NFS3ERR_STALE;
result.lookup3res_u.resfail.present = FALSE;
async_rpc_send_reply(req, &result);
return;
}
+ schedule_inode_unref(req, inode);
result.status = NFS3_OK;
result.lookup3res_u.resok.dir_attributes.present = TRUE;
access3res result;
memset(&result, 0, sizeof(result));
- BlueSkyInode *inode = lookup_fh(&argp->object);
+ BlueSkyInode *inode = lookup_fh(req, &argp->object);
if (inode == NULL) {
result.status = NFS3ERR_STALE;
result.access3res_u.resfail.present = FALSE;
readlink3res result;
memset(&result, 0, sizeof(result));
- BlueSkyInode *inode = lookup_fh(argp);
+ BlueSkyInode *inode = lookup_fh(req, argp);
if (inode != NULL) {
if (inode->type == BLUESKY_SYMLINK) {
result.status = NFS3_OK;
memset(&result, 0, sizeof(result));
char buf[32768];
- BlueSkyInode *inode = lookup_fh(&argp->file);
+ BlueSkyInode *inode = lookup_fh(req, &argp->file);
if (inode == NULL) {
result.status = NFS3ERR_STALE;
result.read3res_u.resfail.present = FALSE;
struct wcc_data wcc;
memset(&wcc, 0, sizeof(wcc));
- BlueSkyInode *inode = lookup_fh(&argp->file);
+ BlueSkyInode *inode = lookup_fh(req, &argp->file);
if (inode == NULL) {
result.status = NFS3ERR_STALE;
result.write3res_u.resfail = wcc;
struct wcc_data wcc;
memset(&wcc, 0, sizeof(wcc));
- BlueSkyInode *dir = lookup_fh(&argp->where.dir);
+ BlueSkyInode *dir = lookup_fh(req, &argp->where.dir);
if (dir == NULL) {
result.status = NFS3ERR_STALE;
result.diropres3_u.resfail = wcc;
struct wcc_data wcc;
memset(&wcc, 0, sizeof(wcc));
- BlueSkyInode *dir = lookup_fh(&argp->where.dir);
+ BlueSkyInode *dir = lookup_fh(req, &argp->where.dir);
if (dir == NULL) {
result.status = NFS3ERR_STALE;
result.diropres3_u.resfail = wcc;
struct wcc_data wcc;
memset(&wcc, 0, sizeof(wcc));
- BlueSkyInode *dir = lookup_fh(&argp->where.dir);
+ BlueSkyInode *dir = lookup_fh(req, &argp->where.dir);
if (dir == NULL) {
result.status = NFS3ERR_STALE;
result.diropres3_u.resfail = wcc;
wccstat3 result;
memset(&result, 0, sizeof(result));
- BlueSkyInode *dir = lookup_fh(&argp->dir);
+ BlueSkyInode *dir = lookup_fh(req, &argp->dir);
if (dir == NULL) {
result.status = NFS3ERR_STALE;
async_rpc_send_reply(req, &result);
wccstat3 result;
memset(&result, 0, sizeof(result));
- BlueSkyInode *dir = lookup_fh(&argp->dir);
+ BlueSkyInode *dir = lookup_fh(req, &argp->dir);
if (dir == NULL) {
result.status = NFS3ERR_STALE;
async_rpc_send_reply(req, &result);
async_rpc_send_reply(req, &result);
return;
}
+ schedule_inode_unref(req, inode);
if (inode->type != BLUESKY_DIRECTORY) {
result.status = NFS3ERR_NOTDIR;
wcc_data *wcc1 = &result.rename3res_u.res.fromdir_wcc;
wcc_data *wcc2 = &result.rename3res_u.res.todir_wcc;
- BlueSkyInode *dir1 = lookup_fh(&argp->from.dir);
+ BlueSkyInode *dir1 = lookup_fh(req, &argp->from.dir);
if (dir1 == NULL) {
result.status = NFS3ERR_STALE;
async_rpc_send_reply(req, &result);
}
encode_pre_wcc(wcc1, dir1);
- BlueSkyInode *dir2 = lookup_fh(&argp->to.dir);
+ BlueSkyInode *dir2 = lookup_fh(req, &argp->to.dir);
if (dir2 == NULL) {
result.status = NFS3ERR_STALE;
async_rpc_send_reply(req, &result);
struct wcc_data wcc;
memset(&wcc, 0, sizeof(wcc));
- BlueSkyInode *inode = lookup_fh(&argp->file);
+ BlueSkyInode *inode = lookup_fh(req, &argp->file);
if (inode == NULL) {
result.status = NFS3ERR_STALE;
result.link3res_u.res.linkdir_wcc = wcc;
return;
}
- BlueSkyInode *dir = lookup_fh(&argp->link.dir);
+ BlueSkyInode *dir = lookup_fh(req, &argp->link.dir);
if (dir == NULL) {
result.status = NFS3ERR_STALE;
result.link3res_u.res.linkdir_wcc = wcc;
readdir3res result;
memset(&result, 0, sizeof(result));
- BlueSkyInode *dir = lookup_fh(&argp->dir);
+ BlueSkyInode *dir = lookup_fh(req, &argp->dir);
if (dir == NULL) {
result.status = NFS3ERR_STALE;
result.readdir3res_u.resfail.present = FALSE;
readdirplus3res result;
memset(&result, 0, sizeof(result));
- BlueSkyInode *dir = lookup_fh(&argp->dir);
+ BlueSkyInode *dir = lookup_fh(req, &argp->dir);
if (dir == NULL) {
result.status = NFS3ERR_STALE;
result.readdirplus3res_u.resfail.present = FALSE;
if (count > 0)
dirents[count - 1].nextentry = &dirents[count];
count++;
+ bluesky_inode_unref(inode);
}
i = g_sequence_iter_next(i);
}
fsstat3res result;
memset(&result, 0, sizeof(result));
- BlueSkyInode *inode = lookup_fh(argp);
+ BlueSkyInode *inode = lookup_fh(req, argp);
if (inode == NULL) {
result.status = NFS3ERR_STALE;
result.fsstat3res_u.resfail.present = FALSE;
result.fsinfo3res_u.resok.time_delta.nseconds = 1000;
result.fsinfo3res_u.resok.properties
= FSF3_LINK | FSF3_SYMLINK | FSF3_HOMOGENEOUS | FSF3_CANSETTIME;
+ bluesky_inode_unref(inode);
async_rpc_send_reply(req, &result);
}
result.pathconf3res_u.resok.chown_restricted = TRUE;
result.pathconf3res_u.resok.case_insensitive = FALSE;
result.pathconf3res_u.resok.case_preserving = TRUE;
+ bluesky_inode_unref(inode);
async_rpc_send_reply(req, &result);
}