[PATCH v2 3/7] nilfs-utils: fsck: add functionality of libfsck.la library

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

This patch adds functionality of libfsck.la library (printing routines and raw operations with disk).

With the best regards,
Vyacheslav Dubeyko.
--
From: Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
Subject: [PATCH v2 3/7] nilfs-utils: fsck: add functionality of libfsck.la library

This patch adds functionality of libfsck.la library (printing routines and raw operations with disk).

Signed-off-by: Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
---
diff --git a/include/fsck_messages.def b/include/fsck_messages.def
new file mode 100644
index 0000000..729ae94
--- /dev/null
+++ b/include/fsck_messages.def
@@ -0,0 +1,80 @@
+/*
+ * fsck_messages.def - List of codes and associated messages
+ *                     (fsck.nilfs2)
+ *
+ * Copyright (C) 2012 Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
+ *
+ * This file is part of NILFS.
+ *
+ * NILFS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * NILFS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NILFS; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
+ */
+
+#ifndef NILFS_FSCK_MESSAGE
+#define NILFS_FSCK_MESSAGE(ID, MESSAGE)
+#endif
+
+NILFS_FSCK_MESSAGE(FSCK_OK, "")
+NILFS_FSCK_MESSAGE(UNKNOWN_ERROR, "Unknown error has occured.")
+NILFS_FSCK_MESSAGE(NOT_IMPLEMENTED, "Sorry. Functionality is not implemented yet.")
+NILFS_FSCK_MESSAGE(SUCCESS_FAREWELL, "All is OK. Have a nice day.")
+NILFS_FSCK_MESSAGE(NO_DEVICE, "Device not specified.")
+NILFS_FSCK_MESSAGE(BAD_DEVICE, "Cannot open device.")
+NILFS_FSCK_MESSAGE(NOT_MOUNTED, "Device is not mounted.")
+NILFS_FSCK_MESSAGE(RO_MOUNT, "Device is mounted in RO mode.")
+NILFS_FSCK_MESSAGE(RW_MOUNT, "Device is mounted in RW mode.")
+NILFS_FSCK_MESSAGE(DEVICE_NOT_OPENED, "Device is not opened.")
+NILFS_FSCK_MESSAGE(DEVICE_OPENED_YET, "Device is opened yet.")
+NILFS_FSCK_MESSAGE(INVALID_MODE, "Requested mode is unavailable.")
+NILFS_FSCK_MESSAGE(FLUSH_FAILED, "Flush is failed.")
+NILFS_FSCK_MESSAGE(CANNOT_CLOSE_DEVICE, "Cannot close device.")
+NILFS_FSCK_MESSAGE(INVALID_BLOCK_SIZE, "Invalid block size.")
+NILFS_FSCK_MESSAGE(DATA_PROCCESSED_PARTIALLY, "The requested data are proccessed partially.")
+NILFS_FSCK_MESSAGE(OP_FAILED, "Requested operation has failed.")
+NILFS_FSCK_MESSAGE(INVALID_PARAMETER, "Input parameters are invalid.")
+NILFS_FSCK_MESSAGE(OUT_OF_VOLUME, "Trying to operate out of volume.")
+NILFS_FSCK_MESSAGE(CANNOT_SET_DEV_POS, "Cannot set current position on device.")
+NILFS_FSCK_MESSAGE(CANNOT_ALLOCATE, "Cannot allocate memory.")
+NILFS_FSCK_MESSAGE(CANNOT_FREE, "Cannot free memory.")
+NILFS_FSCK_MESSAGE(CANNOT_READ_SUPERBLOCK, "Cannot read superblock from disk.") +NILFS_FSCK_MESSAGE(INVALID_SB_OFFSET, "Invalid value of superblock offset.") +NILFS_FSCK_MESSAGE(CANNOT_GET_SUPERBLOCKS, "Cannot get superblocks from requested device.") +NILFS_FSCK_MESSAGE(INVALID_NILFS_SIGNATURE, "Superblock signature is invalid. This is *not* NILFS superblock") +NILFS_FSCK_MESSAGE(NILFS_NOT_FOUND, "NILFS superblocks are not detected.") +NILFS_FSCK_MESSAGE(ONLY_SB1_OK_FOUND, "Primary valid superblock was found but secondary *not*.") +NILFS_FSCK_MESSAGE(ONLY_SB1_CORRUPTED_FOUND, "Corrupted primary superblock was found but secondary *not*.") +NILFS_FSCK_MESSAGE(ONLY_SB2_OK_FOUND, "Secondary valid superblock was found but primary *not*..") +NILFS_FSCK_MESSAGE(ONLY_SB2_CORRUPTED_FOUND, "Corrupted secondary superblock was found but primary *not*.") +NILFS_FSCK_MESSAGE(SB1_SB2_CORRUPTED, "Primary and secondary superblocks were found but in corrupted state.") +NILFS_FSCK_MESSAGE(SB1_OK_SB2_CORRUPTED, "Primary superblock is valid but secondary is in corrupted state..") +NILFS_FSCK_MESSAGE(SB1_CORRUPTED_SB2_OK, "Secondary superblock is valid but primary is in corrupted state.") +NILFS_FSCK_MESSAGE(CANNOT_DETECT_SB_STATE, "Cannot detect state of a superblock because of internal error.") +NILFS_FSCK_MESSAGE(SB1_OK_SB2_OK, "NILFS has valid primary and secondary superblocks.") +NILFS_FSCK_MESSAGE(CANNOT_CHECK_SB, "Cannot check superblock validity because of internal error.")
+NILFS_FSCK_MESSAGE(INVALID_SB, "Superblock is in corrupted state.")
+NILFS_FSCK_MESSAGE(INVALID_SB_SIZE, "Superblock contains incorrect size in bytes.") +NILFS_FSCK_MESSAGE(UNSUPPORTED_SB_REV, "It is detected an unsupported revision of NILFS superblock.")
+NILFS_FSCK_MESSAGE(INVALID_CRC, "Invalid checksum was detected.")
+
+NILFS_FSCK_MESSAGE(REQUESTED_DEV, "Requested device:")
+NILFS_FSCK_MESSAGE(DONT_WORK_RO_MOUNT, "FSCK *doesn't* work with RO mounted partition currently.") +NILFS_FSCK_MESSAGE(DONT_WORK_RW_MOUNT, "FSCK *doesn't* work with RW mounted partition.") +NILFS_FSCK_MESSAGE(NOT_NILFS_VOLUME, "!!!This is not NILFS volume or NILFS volume completely *UNRECOVERABLE*!!!") +NILFS_FSCK_MESSAGE(NILFS_HAS_CORRUPTED_SB, "Device contains NILFS volume with *CORRUPTED* superblocks.")
+NILFS_FSCK_MESSAGE(FSCK_DOES_NOTHING, "FSCK currently does nothing.")
+NILFS_FSCK_MESSAGE(RO_CHECK_DOES_NOT_WORK, "Read-only check doesn't supported yet.")
+
+#undef NILFS_FSCK_MESSAGE
diff --git a/include/fsck_messages.h b/include/fsck_messages.h
new file mode 100644
index 0000000..6efe42f
--- /dev/null
+++ b/include/fsck_messages.h
@@ -0,0 +1,126 @@
+/*
+ * fsck_messages.h - Declaration of fsck error, warning, info codes,
+ *                   associated messages and routines (fsck.nilfs2)
+ *
+ * Copyright (C) 2012 Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
+ *
+ * This file is part of NILFS.
+ *
+ * NILFS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * NILFS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NILFS; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
+ */
+
+#ifndef FSCK_MESSAGES_H
+#define FSCK_MESSAGES_H
+
+/* Available verbosity levels of fsck. */
+enum fsck_verbosity_level {
+	KEEP_SILENCE,
+	BE_VERBOSE,
+	DEBUG_SPAM
+}; /* enum fsck_verbosity_level */
+
+/* NILFS error, warning, info codes and associated messages. */
+enum fsck_message_codes {
+
+#define NILFS_FSCK_MESSAGE(ID, MESSAGE) ID,
+#include "fsck_messages.def"
+
+	MAX_MESSAGE_CODE
+}; /* enum fsck_message_codes */
+
+/* Possible severity of FS errors */
+enum fs_error_severity {
+	FS_INFO,
+	FS_WARNING,
+	FS_FATAL_ERROR,
+	FS_CRITICAL_ERROR,
+	FS_MINOR_ERROR,
+	FS_LOOKS_LIKE_ERROR
+}; /* enum fsck_error_severity */
+
+/* NILFS fsck exit codes. */
+enum fsck_exit_codes {
+	RETURN_FSCK_OK                 = 0,
+	RETURN_FSCK_CORRECTED          = 1,
+	RETURN_FSCK_REBOOT             = 2,
+	RETURN_FSCK_ERRORS_UNCORRECTED = 4,
+	RETURN_FSCK_OP_ERROR           = 8,
+	RETURN_FSCK_USAGE_ERROR        = 16,
+	EXIT_LIBRARY                   = 128
+}; /* enum fsck_exit_codes */
+
+/* NILFS fsck message array */
+extern const char *fsck_message[MAX_MESSAGE_CODE];
+
+/* Set verbosity level */
+void set_verbosity_level(int requested_level);
+
+/*****************************************************************************
+ * User Interface (UI) messages
+ */
+
+/* Inform user about something */
+void ui_info(const char *fmt, ...);
+
+/* Warn user about some important but not critical situation */
+void ui_warning(const char *fmt, ...);
+
+/* Report error in way of using the utility */
+void ui_error(const char *fmt, ...);
+
+/*****************************************************************************
+ * Messages inform about file system state
+ */
+
+/* Inform user about file system state */
+void fs_info(const char *fmt, ...);
+
+/* Warn user about some important thing in file system state */
+void fs_warning(const char *fmt, ...);
+
+/* Report about detected unrecoverable file system's error */
+void fs_fatal_error(const char *fmt, ...);
+
+/* Report about detected critical file system's error */
+void fs_critical_error(const char *fmt, ...);
+
+/* Report about detected minor file system's error */
+void fs_minor_error(const char *fmt, ...);
+
+/* Report about detected suspicious state looks like error */
+void fs_looks_like_error(const char *fmt, ...);
+
+/*****************************************************************************
+ * Fsck internal messages
+ */
+
+/* Inform user about fsck common actions */
+void fsck_info(const char *fmt, ...);
+
+/* Warn user about some important situation in fsck states */
+void fsck_warning(const char *fmt, ...);
+
+/* Report about internal fsck errors */
+void fsck_error(const char *fmt, ...);
+
+/* Report about internal fsck errors + print system error message */
+void fsck_perror(const char *fmt, ...);
+
+/* Debug messages of fsck */
+void fsck_debug(const char *fmt, ...);
+
+#endif /* FSCK_MESSAGES_H */
diff --git a/include/fsck_raw_ops.h b/include/fsck_raw_ops.h
new file mode 100644
index 0000000..5d2ee48
--- /dev/null
+++ b/include/fsck_raw_ops.h
@@ -0,0 +1,55 @@
+/*
+ * fsck_raw_ops.h - Declarations for raw operations with disk
+ *
+ * Copyright (C) 2012 Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
+ *
+ * This file is part of NILFS.
+ *
+ * NILFS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * NILFS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NILFS; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
+ */
+
+#ifndef FSCK_RAW_OPS_H
+#define FSCK_RAW_OPS_H
+
+/* Open volume for fsck operations */
+int open_volume(const char *device_name);
+
+/* Get file descriptor of opened volume */
+int device_file_descriptor(void);
+
+/* Close volume after fsck operations */
+int close_volume(void);
+
+/* Return device sector size in bytes */
+int get_device_sector_size(void);
+
+/* Return device size in bytes */
+__u64 get_device_size_in_bytes(void);
+
+/* Read bytes from volume */
+int read_raw_bytes(__u64 device_offset,
+			void *raw_data_buffer,
+			__u32 requested_bytes_count,
+			__u32 *read_bytes_count);
+
+/* Write bytes to volume */
+int write_raw_bytes(__u64 device_offset,
+			void *raw_data_buffer,
+			__u32 requested_bytes_count,
+			__u32 *written_bytes_count);
+
+#endif /* FSCK_RAW_OPS_H */
diff --git a/lib/fsck_messages.c b/lib/fsck_messages.c
new file mode 100644
index 0000000..66885af
--- /dev/null
+++ b/lib/fsck_messages.c
@@ -0,0 +1,274 @@
+/*
+ * fsck_messages.c - Print routines (libfsck)
+ *
+ * Copyright (C) 2012 Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
+ *
+ * This file is part of NILFS.
+ *
+ * NILFS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * NILFS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NILFS; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "fsck_messages.h"
+
+/*****************************************************************************
+ * GLOBAL VARIABLES
+ *****************************************************************************/
+
+/* NILFS fsck message array */
+const char *fsck_message[MAX_MESSAGE_CODE] = {
+
+#define NILFS_FSCK_MESSAGE(ID, MESSAGE) MESSAGE,
+#include "fsck_messages.def"
+
+}; /* const char *fsck_message[MAX_MESSAGE_CODE] */
+
+/* Verbosity level of fsck */
+int verbosity_level = BE_VERBOSE;
+
+/*****************************************************************************
+ * IMPLEMENTATION SECTION
+ *****************************************************************************/
+
+/*****************************************************************************
+ * NAME: set_verbosity_level (libfsck)
+ *
+ * MACRO: Set verbosity level
+ *
+ * PARAMETERS:
+ * @requested_level: Requested level of verbosity.
+ */
+void set_verbosity_level(int requested_level)
+{
+	if (requested_level < KEEP_SILENCE ||
+			requested_level > DEBUG_SPAM) {
+		fprintf(stderr, "[FSCK_ERROR]: unknow verbosity level.");
+		fprintf(stderr, "Keep the same verbosity level.\n");
+		return;
+	}
+
+	verbosity_level = requested_level;
+} /* set_verbosity_level */
+
+/*****************************************************************************
+ * NAME: FSCK_PRINT_MESSAGE (libfsck)
+ *
+ * MACRO: Print fsck message into stdout/stderr
+ *
+ * PARAMETERS:
+ * @granted_verbosity: Verbosity level gives right to print.
+ * @out_stream: Type of the standard output stream [stdout | stderr].
+ * @prefix: Prefix word begins a message.
+ * @fmt: Format of the message.
+ */
+#define FSCK_PRINT_MESSAGE(granted_verbosity, out_stream, prefix, fmt) \
+	do { \
+		va_list args_list; \
+		if (verbosity_level < granted_verbosity) \
+			return; \
+		va_start(args_list, fmt); \
+		fprintf(out_stream, prefix); \
+		vfprintf(out_stream, fmt, args_list); \
+		fprintf(out_stream, "\n"); \
+		va_end(args_list); \
+	} while (0)
+/* FSCK_PRINT_MESSAGE */
+
+/*****************************************************************************
+ * NAME: ui_info (libfsck)
+ *
+ * FUNCTION: Inform user about something
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void ui_info(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stdout, "[UI_INFO]: ", fmt);
+} /* ui_info() */
+
+/*****************************************************************************
+ * NAME: ui_warning (libfsck)
+ *
+ * FUNCTION: Warn user about some important but not critical situation
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void ui_warning(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stdout, "[UI_WARNING]: ", fmt);
+} /* ui_warning() */
+
+/*****************************************************************************
+ * NAME: ui_error (libfsck)
+ *
+ * FUNCTION: Report error in way of using the utility
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void ui_error(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stdout, "[UI_ERROR]: ", fmt);
+} /* ui_error() */
+
+/*****************************************************************************
+ * NAME: fs_info (libfsck)
+ *
+ * FUNCTION: Inform user about file system state
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fs_info(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stdout, "[FS_INFO]: ", fmt);
+} /* fs_info() */
+
+/*****************************************************************************
+ * NAME: fs_warning (libfsck)
+ *
+ * FUNCTION: Warn user about some important thing in file system state
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fs_warning(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stderr, "[FS_WARNING]: ", fmt);
+} /* fs_warning() */
+
+/*****************************************************************************
+ * NAME: fs_fatal_error (libfsck)
+ *
+ * FUNCTION: Report about detected unrecoverable error in file system's metadata
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fs_fatal_error(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stderr, "[FS_FATAL_ERROR]: ", fmt);
+} /* fs_fatal_error() */
+
+/*****************************************************************************
+ * NAME: fs_critical_error (libfsck)
+ *
+ * FUNCTION: Report about detected critical file system's metadata error
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fs_critical_error(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stderr, "[FS_CRITICAL_ERROR]: ", fmt);
+} /* fs_critical_error() */
+
+/*****************************************************************************
+ * NAME: fs_minor_error (libfsck)
+ *
+ * FUNCTION: Report about detected minor file system's metadata error
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fs_minor_error(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stderr, "[FS_MINOR_ERROR]: ", fmt);
+} /* fs_minor_error() */
+
+/*****************************************************************************
+ * NAME: fs_looks_like_error (libfsck)
+ *
+ * FUNCTION: Report about detected suspicious metadata's state looks like error
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fs_looks_like_error(const char *fmt, ...)
+{
+ FSCK_PRINT_MESSAGE(BE_VERBOSE, stderr, "[FS_LOOKS_LIKE_ERROR]: ", fmt);
+} /* fs_looks_like_error() */
+
+/*****************************************************************************
+ * NAME: fsck_info (libfsck)
+ *
+ * FUNCTION: Inform user about fsck common actions
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fsck_info(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stdout, "[FSCK_INFO]: ", fmt);
+} /* fsck_info() */
+
+/*****************************************************************************
+ * NAME: fsck_warning (libfsck)
+ *
+ * FUNCTION: Warn user about some important situation in fsck states
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fsck_warning(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stderr, "[FSCK_WARNING]: ", fmt);
+} /* fsck_warning() */
+
+/*****************************************************************************
+ * NAME: fsck_error (libfsck)
+ *
+ * FUNCTION: Report about internal fsck errors
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fsck_error(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stderr, "[FSCK_ERROR]: ", fmt);
+} /* fsck_error() */
+
+/*****************************************************************************
+ * NAME: fsck_perror (libfsck)
+ *
+ * FUNCTION: Report about internal fsck errors + print system error message
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fsck_perror(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(BE_VERBOSE, stderr, "[FSCK_ERROR]: ", fmt);
+	perror("[SYSTEM_ERROR]");
+} /* fsck_perror() */
+
+/*****************************************************************************
+ * NAME: fsck_debug (libfsck)
+ *
+ * FUNCTION: Debug messages of fsck
+ *
+ * PARAMETERS:
+ * @fmt: Format of the message.
+ */
+void fsck_debug(const char *fmt, ...)
+{
+	FSCK_PRINT_MESSAGE(DEBUG_SPAM, stdout, "[FSCK_DEBUG]: ", fmt);
+} /* fsck_debug() */
diff --git a/lib/fsck_raw_ops.c b/lib/fsck_raw_ops.c
new file mode 100644
index 0000000..04decdd
--- /dev/null
+++ b/lib/fsck_raw_ops.c
@@ -0,0 +1,473 @@
+/*
+ * fsck_raw_ops.c - Raw operations with disk functionality
+ *
+ * Copyright (C) 2012 Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
+ *
+ * This file is part of NILFS.
+ *
+ * NILFS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * NILFS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NILFS; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
+ */
+
+#include <stdio.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif	/* HAVE_STDLIB_H */
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif	/* HAVE_UNISTD_H */
+
+#include <string.h>
+#include <linux/fs.h>
+
+#if HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif	/* HAVE_SYS_IOCTL_H */
+
+#include "nilfs.h"
+#include "fsck_messages.h"
+#include "fsck_raw_ops.h"
+
+/*****************************************************************************
+ * CONSTANTS
+ *****************************************************************************/
+
+#define DEVICE_RO_MODE "rb"
+#define DEVICE_RW_MODE "r+b"
+
+/*****************************************************************************
+ * GLOBAL VARIABLES
+ *****************************************************************************/
+
+/* Pointer on opened device */
+FILE *opened_device_ptr;
+
+/* Block device sector size (default value: 512 bytes) */
+int device_sector_size = DEFAULT_SECTOR_SIZE;
+
+/* Size of the device in bytes */
+__u64 device_size_in_bytes;
+
+/*****************************************************************************
+ * IMPLEMENTATION SECTION
+ *****************************************************************************/
+
+/*****************************************************************************
+ * NAME:  get_device_sector_size (libfsck)
+ *
+ * FUNCTION:  Return device sector size in bytes.
+ *
+ * RETURNS:
+ * It simply returns value of device_sector_size global variable.
+ * The value is set during device opening.
+ */
+int get_device_sector_size(void)
+{
+	return device_sector_size;
+} /* get_device_sector_size() */
+
+/*****************************************************************************
+ * NAME:  get_device_size_in_bytes (libfsck)
+ *
+ * FUNCTION:  Return device size in bytes.
+ *
+ * RETURNS:
+ * It simply returns value of device_size_in_bytes global variable.
+ * The value is set during device opening.
+ */
+__u64 get_device_size_in_bytes(void)
+{
+	return device_size_in_bytes;
+} /* get_device_size_in_bytes() */
+
+/*****************************************************************************
+ * NAME:  open_device (libfsck)
+ *
+ * FUNCTION:  Open device.
+ *
+ * PARAMETERS:
+ * @device_name: Name of the device for opening
+ * @mode: mode of opening [RO | RW]
+ *
+ * RETURNS:
+ * FSCK_OK - device has opened successfully.
+ * %-BAD_DEVICE - cannot open device.
+ */
+static int open_device(const char *device_name, const char *mode)
+{
+	int file_descriptor = 0;
+
+	if (!device_name || !mode) {
+		fsck_debug("<%s>: NULL pointer.", __func__);
+		return -BAD_DEVICE;
+	}
+
+	fsck_debug("<%s>: try to open device %s in %s mode.",
+			__func__, device_name, mode);
+
+	if (opened_device_ptr) {
+		fsck_debug("<%s>: %s Device %s is opened yet.",
+				__func__, fsck_message[BAD_DEVICE],
+				device_name);
+		return -BAD_DEVICE;
+	}
+
+	opened_device_ptr = fopen(device_name, mode);
+	if (!opened_device_ptr) {
+		fsck_debug("<%s>: %s The mode %s is invalid for %s device.",
+				__func__, fsck_message[BAD_DEVICE],
+				device_name, mode);
+		return -BAD_DEVICE;
+	}
+
+	/* In the case of error fileno() returns -1 */
+	file_descriptor = fileno(opened_device_ptr);
+	if (-1 == file_descriptor) {
+		fsck_debug("<%s>: cannot convert pointer into descriptor.",
+				__func__);
+		goto open_success;
+	}
+
+	/* In the case of error ioctl() returns -1 */
+	if (-1 == ioctl(file_descriptor, BLKSSZGET, &device_sector_size))
+		fsck_debug("<%s>: cannot detect device sector size.", __func__);
+	else {
+		fsck_debug("<%s>: sector size %d.",
+				__func__, device_sector_size);
+	}
+
+	/* In the case of error ioctl() returns -1 */
+ if (-1 == ioctl(file_descriptor, BLKGETSIZE64, &device_size_in_bytes)) {
+		fsck_debug("<%s>: cannot detect device size in bytes.",
+				__func__);
+	} else {
+		fsck_debug("<%s>: device size in bytes %lld.",
+				__func__, device_size_in_bytes);
+	}
+
+open_success:
+	fsck_debug("<%s>: device %s is opened in %s mode successfully.",
+			__func__, device_name, mode);
+	return FSCK_OK;
+} /* open_device() */
+
+/*****************************************************************************
+ * NAME:  open_device_ro (libfsck)
+ *
+ * FUNCTION:  Open device in READ-ONLY mode.
+ *
+ * PARAMETERS:
+ * @device_name: Name of the device for opening
+ *
+ * RETURNS:
+ * FSCK_OK - device has opened successfully.
+ * %-BAD_DEVICE - cannot open device.
+ */
+static int open_device_ro(const char *device_name)
+{
+	return open_device(device_name, DEVICE_RO_MODE);
+} /* open_device_ro() */
+
+/*****************************************************************************
+ * NAME:  open_device_rw (libfsck)
+ *
+ * FUNCTION:  Open device in READ-WRITE mode.
+ *
+ * PARAMETERS:
+ * @device_name: Name of the device for opening
+ *
+ * RETURNS:
+ * FSCK_OK - device has opened successfully.
+ * %-BAD_DEVICE - cannot open device.
+ */
+static int open_device_rw(const char *device_name)
+{
+	/* <TODO: add support of RW mode> */
+	ui_error("%s %s", fsck_message[BAD_DEVICE],
+				fsck_message[NOT_IMPLEMENTED]);
+	return -BAD_DEVICE;
+} /* open_device_rw() */
+
+/*****************************************************************************
+ * NAME:  open_volume (libfsck)
+ *
+ * FUNCTION:  Open volume for fsck operations.
+ *
+ * PARAMETERS:
+ * @device_name: Name of the device for opening
+ *
+ * RETURNS:
+ * FSCK_OK - device has opened successfully.
+ * %-BAD_DEVICE - cannot open device.
+ */
+int open_volume(const char *device_name)
+{
+	/* <TODO: Currently it simply opens device in RO mode.
+		  Function should analyze user options and open
+		  device in proper mode.> */
+	return open_device_ro(device_name);
+} /* open_volume() */
+
+/*****************************************************************************
+ * NAME:  device_file_descriptor (libfsck)
+ *
+ * FUNCTION:  Get file descriptor of opened volume.
+ *
+ * RETURNS:
+ * Returns file descriptor or -1 in the case of failure.
+ */
+int device_file_descriptor(void)
+{
+	if (!opened_device_ptr)
+		return -1;
+
+	return fileno(opened_device_ptr);
+} /* device_file_descriptor() */
+
+/*****************************************************************************
+ * NAME:  close_volume (libfsck)
+ *
+ * FUNCTION:  Close volume after fsck operations.
+ *
+ * RETURNS:
+ * FSCK_OK - device has closed successfully.
+ * %-DEVICE_NOT_OPENED - device is not opened.
+ * %-FLUSH_FAILED - some error occurs during flushing.
+ * %-CANNOT_CLOSE_DEVICE - cannot close device.
+ */
+int close_volume(void)
+{
+	int file_descriptor = 0;
+
+	fsck_debug("<%s>: try to close device.", __func__);
+
+	if (!opened_device_ptr) {
+		fsck_debug("<%s>: %s",
+			__func__, fsck_message[DEVICE_NOT_OPENED]);
+		return -DEVICE_NOT_OPENED;
+	}
+
+	/* In the case of error fileno() returns -1 */
+	file_descriptor = fileno(opened_device_ptr);
+	if (-1 == file_descriptor) {
+		fsck_debug("<%s>: cannot convert pointer into descriptor.",
+				__func__);
+		goto close_device;
+	}
+
+	/* In the case of error fsync() returns -1 */
+	if (-1 == fsync(file_descriptor))
+		fsck_debug("<%s>: %s", __func__, fsck_message[FLUSH_FAILED]);
+
+close_device:
+	if (fclose(opened_device_ptr)) {
+		fsck_debug("<%s>: %s",
+			__func__, fsck_message[CANNOT_CLOSE_DEVICE]);
+		return -CANNOT_CLOSE_DEVICE;
+	}
+
+	device_sector_size = DEFAULT_SECTOR_SIZE;
+	device_size_in_bytes = 0;
+
+	fsck_debug("<%s>: device is closed successfully.", __func__);
+	return FSCK_OK;
+} /* close_volume() */
+
+/* Define type of operation with raw bytes */
+enum {
+	OP_READ,
+	OP_WRITE
+};
+
+/*****************************************************************************
+ * NAME:  raw_bytes (libfsck)
+ *
+ * FUNCTION:  Read or write bytes on volume.
+ *
+ * PARAMETERS:
+ * @op_mode: Type of operation with volume.
+ * @device_offset: Offset from device beginning in bytes.
+ * @raw_data_buffer: Pointer on buffer with data.
+ * @requested_bytes_count: Requested count of bytes for operation.
+ * @actual_bytes_count: Actual count of proccessed bytes.
+ *
+ * RETURNS:
+ * FSCK_OK - All requested count of data are proccessed successfully.
+ * %-DEVICE_NOT_OPENED - Device is not opened.
+ * %-DATA_PROCCESSED_PARTIALLY - The requested data are proccessed partially.
+ * %-OP_FAILED - Requested operation has failed.
+ * %-INVALID_PARAMETER - Input parameters are invalid.
+ * %-CANNOT_SET_DEV_POS - Cannot set current position on device.
+ */
+static int raw_bytes(int op_mode,
+			__u64 device_offset,
+			void *raw_data_buffer,
+			__u32 requested_bytes_count,
+			__u32 *actual_bytes_count)
+{
+	int err = FSCK_OK;
+
+	fsck_debug("<%s>: try to proccess %d bytes on %lld offset.",
+			__func__, requested_bytes_count, device_offset);
+
+	if (NULL == raw_data_buffer || NULL == actual_bytes_count) {
+		fsck_debug("<%s>: %s",
+				__func__, fsck_message[INVALID_PARAMETER]);
+		fsck_debug("<%s>: raw_data_buffer is %#x.",
+				__func__, raw_data_buffer);
+		fsck_debug("<%s>: actual_bytes_count is %#x.",
+				__func__, actual_bytes_count);
+		return -INVALID_PARAMETER;
+	}
+
+	(*actual_bytes_count) = 0;
+
+	if (0 == requested_bytes_count) {
+		fsck_debug("<%s>: does nothing.", __func__);
+		return FSCK_OK;
+	}
+
+	if (!opened_device_ptr) {
+		fsck_debug("<%s>: %s",
+			__func__, fsck_message[DEVICE_NOT_OPENED]);
+		return -DEVICE_NOT_OPENED;
+	}
+
+	if (device_offset >= device_size_in_bytes) {
+		fsck_debug("<%s>: ATTENTION!!! Device size is %lld.",
+				__func__, device_size_in_bytes);
+		return -INVALID_PARAMETER;
+	}
+
+	if ((device_offset + requested_bytes_count) > device_size_in_bytes)
+		fsck_debug("<%s>: %s", __func__, fsck_message[OUT_OF_VOLUME]);
+
+	if (0 != fseeko(opened_device_ptr, device_offset, SEEK_SET)) {
+		fsck_debug("<%s>: %s",
+				__func__, fsck_message[CANNOT_SET_DEV_POS]);
+		err = -CANNOT_SET_DEV_POS;
+		goto raw_bytes_op_failed;
+	}
+
+	switch (op_mode) {
+	case OP_READ:
+		(*actual_bytes_count) =
+			fread(raw_data_buffer, 1,
+				requested_bytes_count, opened_device_ptr);
+		break;
+	case OP_WRITE:
+		(*actual_bytes_count) =
+			fwrite(raw_data_buffer, 1,
+				requested_bytes_count, opened_device_ptr);
+		break;
+	default:
+		fsck_debug("<%s>: the requested value %d is invalid mode.",
+				__func__, op_mode);
+		err = -INVALID_PARAMETER;
+		goto raw_bytes_op_failed;
+	}
+
+	if (-1 == (*actual_bytes_count)) {
+		(*actual_bytes_count) = 0;
+		fsck_debug("<%s>: %s", __func__, fsck_message[OP_FAILED]);
+		err = -OP_FAILED;
+		goto raw_bytes_op_failed;
+	} else if ((*actual_bytes_count) != requested_bytes_count) {
+		fsck_debug("<%s>: %s",
+			__func__, fsck_message[DATA_PROCCESSED_PARTIALLY]);
+		fsck_debug("<%s>: Requested %d bytes. Proccessed %d bytes.",
+				__func__, requested_bytes_count,
+				(*actual_bytes_count));
+		err = -DATA_PROCCESSED_PARTIALLY;
+		if (0 != feof(opened_device_ptr)) {
+			clearerr(opened_device_ptr);
+			goto raw_bytes_op_failed;
+		} else
+			goto raw_bytes_finished;
+	} else {
+		fsck_debug("<%s>: Requested %d bytes proccessed successfully.",
+				__func__, requested_bytes_count);
+		goto raw_bytes_finished;
+	}
+
+raw_bytes_op_failed:
+	rewind(opened_device_ptr);
+
+raw_bytes_finished:
+	return err;
+} /* raw_bytes() */
+
+/*****************************************************************************
+ * NAME:  read_raw_bytes (libfsck)
+ *
+ * FUNCTION:  Read bytes from volume.
+ *
+ * PARAMETERS:
+ * @device_offset: Offset from device beginning in bytes.
+ * @raw_data_buffer: Pointer on buffer with read data.
+ * @requested_bytes_count: Requested count of bytes for read.
+ * @read_bytes_count: Actual count of read bytes.
+ *
+ * RETURNS:
+ * FSCK_OK - All requested count of data are proccessed successfully.
+ * %-DEVICE_NOT_OPENED - Device is not opened.
+ * %-DATA_PROCCESSED_PARTIALLY - The requested data are proccessed partially.
+ * %-OP_FAILED - Requested operation has failed.
+ * %-INVALID_PARAMETER - Input parameters are invalid.
+ * %-CANNOT_SET_DEV_POS - Cannot set current position on device.
+ */
+int read_raw_bytes(__u64 device_offset,
+			void *raw_data_buffer,
+			__u32 requested_bytes_count,
+			__u32 *read_bytes_count)
+{
+	return raw_bytes(OP_READ, device_offset, raw_data_buffer,
+				requested_bytes_count,
+				read_bytes_count);
+} /* read_raw_bytes() */
+
+/*****************************************************************************
+ * NAME:  write_raw_bytes (fsck.nilfs2)
+ *
+ * FUNCTION:  Write bytes to volume.
+ *
+ * PARAMETERS:
+ * @device_offset: Offset from device beginning in bytes.
+ * @raw_data_buffer: Pointer on buffer with data for write.
+ * @requested_bytes_count: Requested count of bytes for write.
+ * @written_bytes_count: Actual count of written bytes.
+ *
+ * RETURNS:
+ * FSCK_OK - All requested count of data are proccessed successfully.
+ * %-DEVICE_NOT_OPENED - Device is not opened.
+ * %-DATA_PROCCESSED_PARTIALLY - The requested data are proccessed partially.
+ * %-OP_FAILED - Requested operation has failed.
+ * %-INVALID_PARAMETER - Input parameters are invalid.
+ * %-CANNOT_SET_DEV_POS - Cannot set current position on device.
+ */
+int write_raw_bytes(__u64 device_offset,
+			void *raw_data_buffer,
+			__u32 requested_bytes_count,
+			__u32 *written_bytes_count)
+{
+	/* <TODO: maybe not write full portion of data is error.
+	   Need to think.> */
+	return raw_bytes(OP_WRITE, device_offset, raw_data_buffer,
+				requested_bytes_count,
+				written_bytes_count);
+} /* write_raw_bytes() */
--

--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux BTRFS]     [Linux CIFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux