Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/libntfs
In directory usw-pr-cvs1:/tmp/cvs-serv473
Modified Files:
ntfsd.c
Log Message:
ntfsd should be finished now
Index: ntfsd.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/libntfs/ntfsd.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -U2 -r1.2 -r1.3
--- ntfsd.c 2001/04/07 00:53:38 1.2
+++ ntfsd.c 2001/04/07 17:29:41 1.3
@@ -22,5 +22,4 @@
*/
-#include <linux/bitops.h>
#include <sys/time.h>
#include <signal.h>
@@ -28,29 +27,91 @@
#include <stdio.h>
#include <errno.h>
+#include <sched.h>
#include "ntfsd.h"
-#include "support.h"
+/*
+ * Keep track of mounted volumes so we can walk the list and sync them all.
+ */
+LISTHEAD(ntfs_mounted_volumes);
+atomic_t nr_ntfs_mounted_volumes = 0;
+spinlock_t ntfs_mounted_volumes_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Global flags describing ntfsd state.
+ */
+int ntfsd_flags = 0;
+static atomic_t ntfsd_times_started = ATOMIC_INIT(0);
+
+/*
+ * We need this global to preserve the old sigalrm_action between calls to
+ * ntfsd_start() and ntfsd_stop().
+ */
+static struct sigaction ntfsd_old_sigalrm_action;
+
+/* Convenience strings. */
+static const char *ntfsd_internal_error = "Internal error.";
+static const char *ntfsd_sigalrm_not_supported = "The system does not support "
+ "the SIGALRM signal.";
+
+/*
+ * The ntfsd daemon / thread which syncs all volumes everytime it is called.
+ * (Every 5 seconds.)
+ */
static void ntfsd_thread(int i)
{
+ int i, j, t;
+ struct list_head *tmp;
+ ntfs_volume *vol;
+
if (!NtfsdStarted(ntfsd_flags) ||
test_and_set_bit(NTFSD_running, &ntfsd_flags))
return;
- // TODO: Sync all volumes.
+ if (atomic_read(&nr_ntfs_mounted_volumes) <= 0) {
+ goto unl_ret;
+ i = 0;
+ while (!spin_trylock(&ntfs_mounted_volumes_lock) && i++ < 100)
+ sched_yield();
+ if (!spin_is_locked(&ntfs_mounted_volumes_lock))
+ goto unl_ret;
+ list_for_each(tmp, &ntfs_mounted_volumes) {
+ vol = list_entry(tmp, ntfs_volume, v_list);
+ i = j = t = 0;
+repeat_sync:
+ if (!ntfs_sync_volume(vol)) {
+ switch (errno) {
+ case EBUSY:
+ if (j++ < 100 && t++ < 1000) {
+ i = 0;
+ sched_yield();
+ goto repeat_sync;
+ }
+ break;
+ case EINTR:
+ case EAGAIN:
+ if (i++ < 3 && t++ < 1000) {
+ j = 0;
+ goto repeat_sync;
+ }
+ break;
+ }
+ fprintf(stderr, "Linux-NTFS: ntfsd: sync_volume() "
+ "failed for volume %s (%s): %s",
+ vol->vol_name, vol->dev_name,
+ strerror(errno));
+ }
+ }
+ spin_unlock(&ntfs_mounted_volumes_lock);
+unl_ret:
ClearNtfsdRunning(ntfsd_flags);
return;
}
-static struct sigaction ntfsd_old_sigalrm_action;
-
-static const char *ntfsd_internal_error = "Internal error.";
-static const char *ntfsd_sigalrm_not_supported = "The system does not support "
- "the SIGALRM signal.";
-
-int ntfsd_start()
+BOOL ntfsd_start(void)
{
+ int tries, err;
const char *ntfsd_start_error = "Linux-NTFS: failed to start ntfsd.";
- struct sigaction act;
- int tries;
+ struct sigaction action;
+ struct itimerval timer_val;
if (test_and_set_bit(NTFSD_busy, &ntfsd_flags)) {
@@ -58,65 +119,105 @@
return FALSE;
}
- if (test_and_set_bit(NTFSD_started, &ntfsd_flags)) {
-unl_ret_true:
- ClearNtfsdBusy(ntfsd_flags);
- return TRUE;
+ if (atomic_inc_and_test(&ntfsd_times_started)) {
+ fprinf(stderr, "Linux-NTFS: ntfsd started counter "
+ "would overflow. Not starting.\n");
+ atomic_dec(&ntfsd_times_started);
+ errno = EMFILE;
+ return FALSE;
}
+ if (NtfsdStarted(ntfsd_flags))
+ goto unl_ret_true;
memset(&ntfsd_old_sigalrm_action, 0, sizeof(struct sigaction));
tries = 0;
retry_get_action:
- if (sigaction(SIGALRM, NULL, &act)) {
- int e = errno;
- switch (e) {
- case EFAULT:
- fprintf(stderr, "%s %s\n", ntfsd_start_error,
- ntfsd_internal_error);
+ if (sigaction(SIGALRM, NULL, &action)) {
+ switch (err = errno) {
+ case EINTR:
+ if (tries++ < 2)
+ goto retry_get_action;
+ perror(ntfsd_start_error);
break;
case EINVAL:
fprintf(stderr, "%s %s\n", ntfsd_start_error,
ntfsd_sigalrm_not_supported);
+ err = ENOTSUP;
break;
- case EINTR:
- if (tries++ < 2)
- goto retry_get_action;
- /* else fall through to default. */
+ case EFAULT:
+ fprintf(stderr, "%s %s\n", ntfsd_start_error,
+ ntfsd_internal_error);
+ break;
default:
perror(ntfsd_start_error);
+ err = EFAULT;
}
- errno = e;
- return FALSE;
+ goto unl_ret_false;
}
- if (act.sa_handler == &ntfsd_thread)
+ if (action.sa_handler == &ntfsd_thread)
goto unl_ret_true;
- memset(&act, 0, sizeof(struct sigaction));
+ memset(&action, 0, sizeof(struct sigaction));
tries = 0;
retry_set_action:
- act.sa_handler = &ntfsd_thread;
- if (sigaction(SIGALRM, &act, &ntfsd_old_sigalrm_action)) {
- int e = errno;
- switch (e) {
+ action.sa_handler = &ntfsd_thread;
+ if (sigaction(SIGALRM, &action, &ntfsd_old_sigalrm_action)) {
+ switch (err = errno) {
+ case EINTR:
+ if (tries++ < 2)
+ goto retry_set_action;
+ perror(ntfsd_start_error);
+ break;
+ case EINVAL:
+ fprintf(stderr, "%s %s\n", ntfsd_start_error,
+ ntfsd_sigalrm_not_supported);
+ err = ENOTSUP;
+ break;
case EFAULT:
fprintf(stderr, "%s %s\n", ntfsd_start_error,
ntfsd_internal_error);
break;
- case EINTR:
- if (tries++ < 2)
- goto retry_set_action;
- /* else fall through to default. */
default:
perror(ntfsd_start_error);
+ err = EFAULT;
}
- errno = e;
- return FALSE;
+ goto unl_ret_false;
}
- // Set the timer.
- goto unl_ret_true;
+ memset(&timer_val, 0, sizeof(struct itimerval));
+ timer_val.it_interval.tv_sec = 5;
+ timer_val.it_value.tv_sec = 5;
+ if (setitimer(ITIMER_REAL, &timer_val, NULL)) {
+ switch (errno) {
+ case EINVAL:
+ case EFAULT:
+ fprintf(stderr, "%s %s\n", ntfsd_start_error,
+ ntfsd_internal_error);
+ break;
+ default:
+ perror(ntfsd_start_error);
+ }
+ err = EFAULT;
+ tries = 0;
+retry_reset_action:
+ if (sigaction(SIGALRM, &ntfsd_old_sigalrm_action, NULL)) {
+ if (errno == EINTR && tries++ < 2)
+ goto retry_reset_action;
+ err = ECANCELED;
+ }
+ goto unl_ret_false;
+ }
+ SetNtfsdStarted(ntfsd_flags);
+unl_ret_true:
+ ClearNtfsdBusy(ntfsd_flags);
+ return TRUE;
+unl_ret_false:
+ atomic_dec(&ntfsd_times_started);
+ ClearNtfsdBusy(ntfsd_flags);
+ errno = err;
+ return FALSE;
}
-int ntfsd_stop()
+BOOL ntfsd_stop(void)
{
+ int tries, err;
const char *ntfsd_stop_error = "Linux-NTFS: failed to stop ntfsd.";
- struct sigaction act;
- int tries;
+ struct itimerval timer_val;
if (test_and_set_bit(NTFSD_busy, &ntfsd_flags)) {
@@ -124,30 +225,65 @@
return FALSE;
}
- if (!test_and_clear_bit(NTFSD_started, &ntfsd_flags)) {
-unl_ret_true:
- ClearNtfsdBusy(ntfsd_flags);
- return TRUE;
+ if (atomic_read(&ntfsd_times_started) > 0 &&
+ !atomic_dec_and_test(&ntfsd_times_started))
+ goto unl_ret_true;
+ atomic_set(&ntfsd_times_started, 0);
+ if (!test_and_clear_bit(NTFSD_started, &ntfsd_flags))
+ goto unl_ret_true;
+ memset(&timer_val, 0, sizeof(struct itimerval));
+ timer_val.it_interval.tv_sec = 0;
+ timer_val.it_value.tv_sec = 0;
+ if (setitimer(ITIMER_REAL, &timer_val, NULL)) {
+ switch (errno) {
+ case EFAULT:
+ case EINVAL:
+ fprintf(stderr, "%s %s\n", ntfsd_stop_error,
+ ntfsd_internal_error);
+ break;
+ default:
+ perror(ntfsd_stop_error);
+ }
+ err = EFAULT;
+ goto unl_ret_false;
}
- // Stop the timer.
tries = 0;
retry_set_action:
if (sigaction(SIGALRM, &ntfsd_old_sigalrm_action, NULL)) {
- int e = errno;
- switch (e) {
+ switch (err = errno) {
+ case EINTR:
+ if (tries++ < 2)
+ goto retry_set_action;
+ perror(ntfsd_stop_error);
+ break;
+ case EINVAL:
+ fprintf(stderr, "%s %s\n", ntfsd_stop_error,
+ ntfsd_sigalrm_not_supported);
+ err = ENOTSUP;
+ break;
case EFAULT:
fprintf(stderr, "%s %s\n", ntfsd_stop_error,
ntfsd_internal_error);
break;
- case EINTR:
- if (tries++ < 2)
- goto retry_set_action;
- /* else fall through to default. */
default:
perror(ntfsd_stop_error);
+ err = EFAULT;
}
- errno = e;
- return FALSE;
+ timer_val.it_interval.tv_sec = 5;
+ timer_val.it_value.tv_sec = 5;
+ if (setitimer(ITIMER_REAL, &timer_val, NULL)) {
+ err = ECANCELED;
+ goto unl_ret_false_stopped;
+ }
}
- goto unl_ret_true;
+unl_ret_true:
+ ClearNtfsdBusy(ntfsd_flags);
+ return TRUE;
+unl_ret_false:
+ atomic_inc(&ntfsd_times_started);
+ SetNtfsdStarted(ntfsd_flags);
+unl_ret_false_stopped:
+ errno = err;
+ ClearNtfsdBusy(ntfsd_flags);
+ return FALSE;
}
|