Better track latency of operations issued to S3.
[bluesky.git] / nfs3 / nfs3.c
index 818cd4b..c5e4448 100644 (file)
@@ -380,6 +380,19 @@ void nfsproc3_write_3_svc(write3args *argp, RPCRequest *req)
         return;
     }
 
+    /* FIXME: Hack to throttle writes when there is too much dirty data still
+     * to be written out. */
+    while (g_atomic_int_get(&fs->cache_dirty) > 4096
+           || g_atomic_int_get(&fs->cache_total) > 8192) {
+        g_print("Too many dirty pages (%d) or total pages (%d); throttling writes...\n",
+                g_atomic_int_get(&fs->cache_dirty),
+                g_atomic_int_get(&fs->cache_total));
+        struct timespec delay;
+        delay.tv_sec = 2;
+        delay.tv_nsec = 0;
+        nanosleep(&delay, NULL);
+    }
+
     g_mutex_lock(inode->lock);
 
     encode_pre_wcc(&wcc, inode);
@@ -754,17 +767,22 @@ 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);
+
+    if (dir1->inum < dir2->inum) {
+        g_mutex_lock(dir1->lock);
+        g_mutex_lock(dir2->lock);
+    } else if (dir1->inum > dir2->inum) {
+        g_mutex_lock(dir2->lock);
+        g_mutex_lock(dir1->lock);
+    }
+    encode_pre_wcc(wcc1, dir1);
     encode_pre_wcc(wcc2, dir1);
 
     gboolean status = bluesky_rename(dir1, argp->from.name,
@@ -780,8 +798,9 @@ void nfsproc3_rename_3_svc(rename3args *argp, RPCRequest *req)
     else
         result.status = NFS3ERR_PERM;
 
-    g_mutex_unlock(dir2->lock);
     g_mutex_unlock(dir1->lock);
+    if (dir1->inum != dir2->inum)
+        g_mutex_unlock(dir2->lock);
     async_rpc_send_reply(req, &result);
 }
 
@@ -1097,7 +1116,7 @@ void nfsproc3_commit_3_svc(commit3args *argp, RPCRequest *req)
     commit3res result;
     memset(&result, 0, sizeof(result));
 
-    result.status = NFS3ERR_NOTSUPP;
+    result.status = NFS3_OK;
 
     BlueSkyInode *inode = lookup_fh(req, &argp->file);
     if (inode == NULL) {