Disable most debugging print messages; should help with performance.
[bluesky.git] / nfs3 / nfs3.c
index 2895e5b..061f835 100644 (file)
@@ -9,6 +9,9 @@
 
 extern BlueSkyFS *fs;
 
+#define NFS_BLOCKSIZE 32768
+#define NFS_MAXSIZE (1 << 20)
+
 /* Check that a string is a valid file name.  We require that it be valid
  * UTF-8, that it not be empty, and that it not contain embedded forward
  * slashes.  Also checks that the length of the string is not more than the
@@ -323,7 +326,9 @@ void nfsproc3_read_3_svc(read3args *argp, RPCRequest *req)
 {
     read3res result;
     memset(&result, 0, sizeof(result));
-    char buf[32768];
+    char buf[NFS_MAXSIZE];
+
+    bluesky_flushd_invoke_conditional(fs);
 
     BlueSkyInode *inode = lookup_fh(req, &argp->file);
     if (inode == NULL) {
@@ -340,6 +345,7 @@ void nfsproc3_read_3_svc(read3args *argp, RPCRequest *req)
         count = 0;
         result.read3res_u.resok.eof = TRUE;
     } else {
+        count = MIN(count, NFS_MAXSIZE);
         count = MIN(count, inode->size - argp->offset);
         if (argp->offset + count == inode->size)
             result.read3res_u.resok.eof = TRUE;
@@ -368,6 +374,8 @@ void nfsproc3_write_3_svc(write3args *argp, RPCRequest *req)
     struct wcc_data wcc;
     memset(&wcc, 0, sizeof(wcc));
 
+    bluesky_flushd_invoke_conditional(fs);
+
     BlueSkyInode *inode = lookup_fh(req, &argp->file);
     if (inode == NULL) {
         result.status = NFS3ERR_STALE;
@@ -376,6 +384,21 @@ void nfsproc3_write_3_svc(write3args *argp, RPCRequest *req)
         return;
     }
 
+#if 0
+    /* 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);
+    }
+#endif
+
     g_mutex_lock(inode->lock);
 
     encode_pre_wcc(&wcc, inode);
@@ -452,7 +475,6 @@ void nfsproc3_create_3_svc(create3args *argp, RPCRequest *req)
     file->nlink = 1;
     file->mode = 0755;
     int64_t time = bluesky_get_current_time();
-    printf("time: %"PRIi64"\n", time);
     file->mtime = time;
     file->ctime = time;
     file->atime = time;
@@ -750,17 +772,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,
@@ -776,8 +803,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);
 }
 
@@ -967,8 +995,8 @@ 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) {
+            g_mutex_lock(inode->lock);
             dircount += 24 + ((strlen(d->name) + 3) & ~3);
             attrcount += 88 + 8 + 8;
             if (dircount > argp->dircount
@@ -1048,13 +1076,13 @@ void nfsproc3_fsinfo_3_svc(nfs_fh3 *argp, RPCRequest *req)
     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);
-    result.fsinfo3res_u.resok.rtmax = 32768;
-    result.fsinfo3res_u.resok.rtpref = 32768;
-    result.fsinfo3res_u.resok.rtmult = 4096;
-    result.fsinfo3res_u.resok.wtmax = 32768;
-    result.fsinfo3res_u.resok.wtpref = 32768;
-    result.fsinfo3res_u.resok.wtmult = 4096;
-    result.fsinfo3res_u.resok.dtpref = 4096;
+    result.fsinfo3res_u.resok.rtmax = NFS_MAXSIZE;
+    result.fsinfo3res_u.resok.rtpref = NFS_MAXSIZE;
+    result.fsinfo3res_u.resok.rtmult = NFS_BLOCKSIZE;
+    result.fsinfo3res_u.resok.wtmax = NFS_MAXSIZE;
+    result.fsinfo3res_u.resok.wtpref = NFS_MAXSIZE;
+    result.fsinfo3res_u.resok.wtmult = NFS_BLOCKSIZE;
+    result.fsinfo3res_u.resok.dtpref = NFS_BLOCKSIZE;
     result.fsinfo3res_u.resok.maxfilesize = 0x7fffffffffffffffULL;
     result.fsinfo3res_u.resok.time_delta.seconds = 0;
     result.fsinfo3res_u.resok.time_delta.nseconds = 1000;
@@ -1093,7 +1121,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) {
@@ -1105,7 +1133,7 @@ void nfsproc3_commit_3_svc(commit3args *argp, RPCRequest *req)
     g_mutex_lock(inode->lock);
     encode_pre_wcc(&result.commit3res_u.resok.file_wcc, inode);
 
-    bluesky_inode_do_sync(inode);
+    //bluesky_inode_do_sync(inode);
 
     result.commit3res_u.resok.file_wcc.after.present = TRUE;
     encode_fattr3(&result.commit3res_u.resok.file_wcc.after.post_op_attr_u.attributes, inode);