X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=nfs3%2Fnfs3.c;h=72ec9cb7a26173e6a0732a428a901d0c0af99597;hb=50c08ba526a6638e8e3c4eec0503365a2c110a85;hp=8be68bd5977fef5f2f746a2ca51eb7fcfc6a263a;hpb=3c5c5e9b5a8650e0549712e20e007ba2399656bf;p=bluesky.git diff --git a/nfs3/nfs3.c b/nfs3/nfs3.c index 8be68bd..72ec9cb 100644 --- a/nfs3/nfs3.c +++ b/nfs3/nfs3.c @@ -104,8 +104,7 @@ void set_attributes(BlueSkyInode *inode, sattr3 *attributes) break; } - inode->ctime = now; - inode->change_count++; + bluesky_inode_update_ctime(inode, FALSE); } /* Copy inode attributes into NFS response. The BlueSkyInode should be locked @@ -162,7 +161,9 @@ void nfsproc3_getattr_3_svc(nfs_fh3 *argp, RPCRequest *req) BlueSkyInode *inode = lookup_fh(req, argp); if (inode != NULL) { result.status = NFS3_OK; + g_mutex_lock(inode->lock); encode_fattr3(&result.getattr3res_u.attributes, inode); + g_mutex_unlock(inode->lock); } else { result.status = NFS3ERR_STALE; } @@ -184,12 +185,14 @@ void nfsproc3_setattr_3_svc(setattr3args *argp, RPCRequest *req) return; } + g_mutex_lock(inode->lock); encode_pre_wcc(&result.wccstat3_u.wcc, inode); if (argp->guard.check) { if (inode->ctime != decode_nfstime3(&argp->guard.sattrguard3_u.ctime)) { result.status = NFS3ERR_NOT_SYNC; result.wccstat3_u.wcc.after.present = TRUE; encode_fattr3(&result.wccstat3_u.wcc.after.post_op_attr_u.attributes, inode); + g_mutex_unlock(inode->lock); async_rpc_send_reply(req, &result); return; } @@ -202,6 +205,7 @@ void nfsproc3_setattr_3_svc(setattr3args *argp, RPCRequest *req) inode); result.status = NFS3_OK; + g_mutex_unlock(inode->lock); async_rpc_send_reply(req, &result); } @@ -218,6 +222,7 @@ void nfsproc3_lookup_3_svc(diropargs3 *argp, RPCRequest *req) return; } + g_mutex_lock(dir->lock); result.lookup3res_u.resfail.present = TRUE; encode_fattr3(&result.lookup3res_u.resfail.post_op_attr_u.attributes, dir); if (!validate_filename(argp->name)) { @@ -225,6 +230,7 @@ void nfsproc3_lookup_3_svc(diropargs3 *argp, RPCRequest *req) result.status = NFS3ERR_NAMETOOLONG; else result.status = NFS3ERR_NOENT; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -233,15 +239,18 @@ void nfsproc3_lookup_3_svc(diropargs3 *argp, RPCRequest *req) uint64_t inum = bluesky_directory_lookup(dir, argp->name); if (inum == 0) { result.status = NFS3ERR_NOENT; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } BlueSkyInode *inode = bluesky_get_inode(fs, inum); if (inode == NULL) { result.status = NFS3ERR_NOENT; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } + g_mutex_lock(inode->lock); schedule_inode_unref(req, inode); result.status = NFS3_OK; @@ -255,6 +264,8 @@ void nfsproc3_lookup_3_svc(diropargs3 *argp, RPCRequest *req) result.lookup3res_u.resok.object.data.data_len = 8; result.lookup3res_u.resok.object.data.data_val = (char *)&fh_bytes; + g_mutex_unlock(inode->lock); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); } @@ -271,10 +282,12 @@ void nfsproc3_access_3_svc(access3args *argp, RPCRequest *req) return; } + g_mutex_lock(inode->lock); result.status = NFS3_OK; result.access3res_u.resok.obj_attributes.present = TRUE; encode_fattr3(&result.access3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode); result.access3res_u.resok.access = argp->access; + g_mutex_unlock(inode->lock); async_rpc_send_reply(req, &result); } @@ -286,6 +299,7 @@ void nfsproc3_readlink_3_svc(nfs_fh3 *argp, RPCRequest *req) BlueSkyInode *inode = lookup_fh(req, argp); if (inode != NULL) { + g_mutex_lock(inode->lock); if (inode->type == BLUESKY_SYMLINK) { result.status = NFS3_OK; result.readlink3res_u.resok.symlink_attributes.present = TRUE; @@ -296,6 +310,7 @@ void nfsproc3_readlink_3_svc(nfs_fh3 *argp, RPCRequest *req) result.readlink3res_u.resfail.present = TRUE; encode_fattr3(&result.readlink3res_u.resfail.post_op_attr_u.attributes, inode); } + g_mutex_unlock(inode->lock); } else { result.status = NFS3ERR_STALE; } @@ -317,6 +332,8 @@ void nfsproc3_read_3_svc(read3args *argp, RPCRequest *req) return; } + g_mutex_lock(inode->lock); + int count = argp->count; if (argp->offset >= inode->size) { count = 0; @@ -338,6 +355,8 @@ void nfsproc3_read_3_svc(read3args *argp, RPCRequest *req) result.read3res_u.resok.data.data_val = buf; result.read3res_u.resok.data.data_len = count; + g_mutex_unlock(inode->lock); + async_rpc_send_reply(req, &result); } @@ -356,10 +375,13 @@ void nfsproc3_write_3_svc(write3args *argp, RPCRequest *req) return; } + g_mutex_lock(inode->lock); + encode_pre_wcc(&wcc, inode); if (inode->type != BLUESKY_REGULAR) { result.status = NFS3ERR_INVAL; result.write3res_u.resfail = wcc; + g_mutex_unlock(inode->lock); async_rpc_send_reply(req, &result); return; } @@ -382,6 +404,8 @@ void nfsproc3_write_3_svc(write3args *argp, RPCRequest *req) result.write3res_u.resok.count = argp->count; result.write3res_u.resok.committed = FILE_SYNC; + g_mutex_unlock(inode->lock); + async_rpc_send_reply(req, &result); } @@ -400,10 +424,13 @@ void nfsproc3_create_3_svc(create3args *argp, RPCRequest *req) return; } + g_mutex_lock(dir->lock); + encode_pre_wcc(&wcc, dir); if (dir->type != BLUESKY_DIRECTORY) { result.status = NFS3ERR_NOTDIR; result.diropres3_u.resfail = wcc; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -414,6 +441,7 @@ void nfsproc3_create_3_svc(create3args *argp, RPCRequest *req) { result.status = NFS3ERR_EXIST; result.diropres3_u.resfail = wcc; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -428,11 +456,11 @@ void nfsproc3_create_3_svc(create3args *argp, RPCRequest *req) file->ctime = time; file->atime = time; file->ntime = time; + g_mutex_lock(file->lock); bluesky_insert_inode(fs, file); bluesky_directory_insert(dir, argp->where.name, file->inum); - dir->mtime = dir->ctime = bluesky_get_current_time(); - dir->change_count++; + bluesky_inode_update_ctime(dir, TRUE); wcc.after.present = TRUE; encode_fattr3(&wcc.after.post_op_attr_u.attributes, dir); @@ -446,6 +474,9 @@ void nfsproc3_create_3_svc(create3args *argp, RPCRequest *req) result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_len = 8; result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_val = (char *)&fh_bytes; + g_mutex_unlock(file->lock); + g_mutex_unlock(dir->lock); + async_rpc_send_reply(req, &result); } @@ -464,10 +495,13 @@ void nfsproc3_mkdir_3_svc(mkdir3args *argp, RPCRequest *req) return; } + g_mutex_lock(dir->lock); + encode_pre_wcc(&wcc, dir); if (dir->type != BLUESKY_DIRECTORY) { result.status = NFS3ERR_NOTDIR; result.diropres3_u.resfail = wcc; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -478,6 +512,7 @@ void nfsproc3_mkdir_3_svc(mkdir3args *argp, RPCRequest *req) { result.status = NFS3ERR_EXIST; result.diropres3_u.resfail = wcc; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -491,12 +526,12 @@ void nfsproc3_mkdir_3_svc(mkdir3args *argp, RPCRequest *req) file->ctime = time; file->atime = time; file->ntime = time; + g_mutex_lock(file->lock); bluesky_insert_inode(fs, file); bluesky_directory_insert(dir, argp->where.name, file->inum); set_attributes(file, &argp->attributes); - dir->mtime = dir->ctime = bluesky_get_current_time(); - dir->change_count++; + bluesky_inode_update_ctime(dir, TRUE); wcc.after.present = TRUE; encode_fattr3(&wcc.after.post_op_attr_u.attributes, dir); @@ -510,6 +545,8 @@ void nfsproc3_mkdir_3_svc(mkdir3args *argp, RPCRequest *req) result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_len = 8; result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_val = (char *)&fh_bytes; + g_mutex_unlock(file->lock); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); } @@ -527,11 +564,13 @@ void nfsproc3_symlink_3_svc(symlink3args *argp, RPCRequest *req) async_rpc_send_reply(req, &result); return; } + g_mutex_lock(dir->lock); encode_pre_wcc(&wcc, dir); if (dir->type != BLUESKY_DIRECTORY) { result.status = NFS3ERR_NOTDIR; result.diropres3_u.resfail = wcc; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -542,6 +581,7 @@ void nfsproc3_symlink_3_svc(symlink3args *argp, RPCRequest *req) { result.status = NFS3ERR_EXIST; result.diropres3_u.resfail = wcc; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -556,11 +596,11 @@ void nfsproc3_symlink_3_svc(symlink3args *argp, RPCRequest *req) file->atime = time; file->ntime = time; file->symlink_contents = g_strdup(argp->symlink.symlink_data); + g_mutex_lock(file->lock); bluesky_insert_inode(fs, file); bluesky_directory_insert(dir, argp->where.name, file->inum); - dir->mtime = dir->ctime = bluesky_get_current_time(); - dir->change_count++; + bluesky_inode_update_ctime(dir, TRUE); wcc.after.present = TRUE; encode_fattr3(&wcc.after.post_op_attr_u.attributes, dir); @@ -574,6 +614,8 @@ void nfsproc3_symlink_3_svc(symlink3args *argp, RPCRequest *req) result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_len = 8; result.diropres3_u.resok.obj.post_op_fh3_u.handle.data.data_val = (char *)&fh_bytes; + g_mutex_unlock(file->lock); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); } @@ -599,6 +641,8 @@ void nfsproc3_remove_3_svc(diropargs3 *argp, RPCRequest *req) return; } + g_mutex_lock(dir->lock); + encode_pre_wcc(&result.wccstat3_u.wcc, dir); if (!validate_filename(argp->name) @@ -606,6 +650,7 @@ void nfsproc3_remove_3_svc(diropargs3 *argp, RPCRequest *req) || strcmp(argp->name, "..") == 0) { result.status = NFS3ERR_NOENT; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -619,6 +664,7 @@ void nfsproc3_remove_3_svc(diropargs3 *argp, RPCRequest *req) encode_fattr3(&result.wccstat3_u.wcc.after.post_op_attr_u.attributes, dir); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); } @@ -634,6 +680,8 @@ void nfsproc3_rmdir_3_svc(diropargs3 *argp, RPCRequest *req) return; } + g_mutex_lock(dir->lock); + encode_pre_wcc(&result.wccstat3_u.wcc, dir); if (!validate_filename(argp->name) @@ -641,6 +689,7 @@ void nfsproc3_rmdir_3_svc(diropargs3 *argp, RPCRequest *req) || strcmp(argp->name, "..") == 0) { result.status = NFS3ERR_NOENT; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -649,13 +698,17 @@ void nfsproc3_rmdir_3_svc(diropargs3 *argp, RPCRequest *req) BlueSkyInode *inode = bluesky_get_inode(fs, inum); if (inode == NULL) { result.status = NFS3ERR_NOENT; + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } + g_mutex_lock(inode->lock); schedule_inode_unref(req, inode); if (inode->type != BLUESKY_DIRECTORY) { result.status = NFS3ERR_NOTDIR; + g_mutex_unlock(inode->lock); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -663,6 +716,8 @@ void nfsproc3_rmdir_3_svc(diropargs3 *argp, RPCRequest *req) printf("Directory not empty: %d entries\n", g_sequence_get_length(inode->dirents)); result.status = NFS3ERR_NOTEMPTY; + g_mutex_unlock(inode->lock); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -676,6 +731,8 @@ void nfsproc3_rmdir_3_svc(diropargs3 *argp, RPCRequest *req) encode_fattr3(&result.wccstat3_u.wcc.after.post_op_attr_u.attributes, dir); + g_mutex_unlock(inode->lock); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); } @@ -692,14 +749,17 @@ void nfsproc3_rename_3_svc(rename3args *argp, RPCRequest *req) async_rpc_send_reply(req, &result); return; } + g_mutex_lock(dir1->lock); encode_pre_wcc(wcc1, dir1); BlueSkyInode *dir2 = lookup_fh(req, &argp->to.dir); if (dir2 == NULL) { result.status = NFS3ERR_STALE; + g_mutex_unlock(dir1->lock); async_rpc_send_reply(req, &result); return; } + g_mutex_lock(dir2->lock); encode_pre_wcc(wcc2, dir1); gboolean status = bluesky_rename(dir1, argp->from.name, @@ -715,6 +775,8 @@ void nfsproc3_rename_3_svc(rename3args *argp, RPCRequest *req) else result.status = NFS3ERR_PERM; + g_mutex_unlock(dir2->lock); + g_mutex_unlock(dir1->lock); async_rpc_send_reply(req, &result); } @@ -732,19 +794,24 @@ void nfsproc3_link_3_svc(link3args *argp, RPCRequest *req) async_rpc_send_reply(req, &result); return; } + g_mutex_lock(inode->lock); BlueSkyInode *dir = lookup_fh(req, &argp->link.dir); if (dir == NULL) { result.status = NFS3ERR_STALE; result.link3res_u.res.linkdir_wcc = wcc; + g_mutex_unlock(inode->lock); async_rpc_send_reply(req, &result); return; } + g_mutex_lock(dir->lock); encode_pre_wcc(&wcc, dir); if (dir->type != BLUESKY_DIRECTORY) { result.status = NFS3ERR_NOTDIR; result.link3res_u.res.linkdir_wcc = wcc; + g_mutex_unlock(inode->lock); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -756,6 +823,8 @@ void nfsproc3_link_3_svc(link3args *argp, RPCRequest *req) { result.status = NFS3ERR_EXIST; result.link3res_u.res.linkdir_wcc = wcc; + g_mutex_unlock(inode->lock); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -763,11 +832,14 @@ void nfsproc3_link_3_svc(link3args *argp, RPCRequest *req) if (!bluesky_directory_insert(dir, argp->link.name, inode->inum)) { result.status = NFS3ERR_EXIST; result.link3res_u.res.linkdir_wcc = wcc; + g_mutex_unlock(inode->lock); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } inode->nlink++; - bluesky_inode_update_ctime(inode, 0); + bluesky_inode_update_ctime(inode, FALSE); + bluesky_inode_update_ctime(dir, TRUE); result.status = NFS3_OK; wcc.after.present = TRUE; @@ -776,6 +848,8 @@ void nfsproc3_link_3_svc(link3args *argp, RPCRequest *req) encode_fattr3(&result.link3res_u.res.file_attributes.post_op_attr_u.attributes, inode); result.link3res_u.res.linkdir_wcc = wcc; + g_mutex_unlock(inode->lock); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); } @@ -795,6 +869,7 @@ void nfsproc3_readdir_3_svc(readdir3args *argp, RPCRequest *req) async_rpc_send_reply(req, &result); return; } + g_mutex_lock(dir->lock); result.status = NFS3_OK; result.readdir3res_u.resok.dir_attributes.present = TRUE; @@ -827,6 +902,7 @@ void nfsproc3_readdir_3_svc(readdir3args *argp, RPCRequest *req) result.readdir3res_u.resok.reply.entries = NULL; result.readdir3res_u.resok.reply.eof = g_sequence_iter_is_end(i); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); } @@ -849,6 +925,7 @@ void nfsproc3_readdirplus_3_svc(readdirplus3args *argp, RPCRequest *req) async_rpc_send_reply(req, &result); return; } + g_mutex_lock(dir->lock); result.status = NFS3_OK; result.readdirplus3res_u.resok.dir_attributes.present = TRUE; @@ -869,12 +946,17 @@ void nfsproc3_readdirplus_3_svc(readdirplus3args *argp, RPCRequest *req) while (count < MAX_READDIR_DIRENTS && !g_sequence_iter_is_end(i)) { BlueSkyDirent *d = g_sequence_get(i); BlueSkyInode *inode = bluesky_get_inode(fs, d->inum); + g_mutex_lock(inode->lock); if (inode != NULL) { dircount += 24 + ((strlen(d->name) + 3) & ~3); attrcount += 88 + 8 + 8; if (dircount > argp->dircount || dircount + attrcount > argp->maxcount) + { + g_mutex_unlock(inode->lock); + bluesky_inode_unref(inode); break; + } dirents[count].fileid = d->inum; dirents[count].name = d->name; dirents[count].cookie = d->cookie; @@ -889,6 +971,7 @@ void nfsproc3_readdirplus_3_svc(readdirplus3args *argp, RPCRequest *req) if (count > 0) dirents[count - 1].nextentry = &dirents[count]; count++; + g_mutex_unlock(inode->lock); bluesky_inode_unref(inode); } i = g_sequence_iter_next(i); @@ -900,6 +983,7 @@ void nfsproc3_readdirplus_3_svc(readdirplus3args *argp, RPCRequest *req) result.readdirplus3res_u.resok.reply.entries = NULL; result.readdirplus3res_u.resok.reply.eof = g_sequence_iter_is_end(i); + g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); } @@ -915,6 +999,7 @@ void nfsproc3_fsstat_3_svc(nfs_fh3 *argp, RPCRequest *req) async_rpc_send_reply(req, &result); return; } + g_mutex_lock(inode->lock); result.status = NFS3_OK; result.fsstat3res_u.resok.obj_attributes.present = TRUE; @@ -928,6 +1013,7 @@ void nfsproc3_fsstat_3_svc(nfs_fh3 *argp, RPCRequest *req) result.fsstat3res_u.resok.afiles = 0; result.fsstat3res_u.resok.invarsec = 0; + g_mutex_unlock(inode->lock); async_rpc_send_reply(req, &result); } @@ -937,6 +1023,7 @@ void nfsproc3_fsinfo_3_svc(nfs_fh3 *argp, RPCRequest *req) memset(&result, 0, sizeof(result)); BlueSkyInode *inode = bluesky_get_inode(fs, 1); + g_mutex_lock(inode->lock); result.status = NFS3_OK; result.fsinfo3res_u.resok.obj_attributes.present = TRUE; encode_fattr3(&result.fsinfo3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode); @@ -952,8 +1039,9 @@ void nfsproc3_fsinfo_3_svc(nfs_fh3 *argp, RPCRequest *req) 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); + g_mutex_unlock(inode->lock); + bluesky_inode_unref(inode); async_rpc_send_reply(req, &result); } @@ -963,6 +1051,7 @@ void nfsproc3_pathconf_3_svc(nfs_fh3 *argp, RPCRequest *req) memset(&result, 0, sizeof(result)); BlueSkyInode *inode = bluesky_get_inode(fs, 1); + g_mutex_lock(inode->lock); result.status = NFS3_OK; result.pathconf3res_u.resok.obj_attributes.present = TRUE; encode_fattr3(&result.pathconf3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode); @@ -972,8 +1061,9 @@ void nfsproc3_pathconf_3_svc(nfs_fh3 *argp, RPCRequest *req) 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); + g_mutex_unlock(inode->lock); + bluesky_inode_unref(inode); async_rpc_send_reply(req, &result); }