[PATCH v4 03/15] nilfs-utils: fsck: add libfsck.la library into nilfs-utils package

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

 



Hi,

This patch adds libfsck.la library into nilfs-utils package. The library has purpose to encapsulate common functionality of fsck.

With the best regards,
Vyacheslav Dubeyko.
--
From: Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
Subject: [PATCH v4 03/15] nilfs-utils: fsck: add libfsck.la library into nilfs-utils package

This patch adds libfsck.la library into nilfs-utils package. The library has purpose to encapsulate common functionality of fsck.

Signed-off-by: Vyacheslav Dubeyko <slava@xxxxxxxxxxx>
---
 include/fsck_raw_ops.h |   55 ++++++
 lib/fsck_raw_ops.c     |  467 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 522 insertions(+)
 create mode 100644 include/fsck_raw_ops.h
 create mode 100644 lib/fsck_raw_ops.c

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_raw_ops.c b/lib/fsck_raw_ops.c
new file mode 100644
index 0000000..7bad51a
--- /dev/null
+++ b/lib/fsck_raw_ops.c
@@ -0,0 +1,467 @@
+/*
+ * 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 "nilfs_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 = -1;
+
+/*****************************************************************************
+ * 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:
+ * NILFS_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) {
+		internal_debug("%s", "NULL pointer.");
+		return -BAD_DEVICE;
+	}
+
+	internal_debug("try to open device %s in %s mode.",
+			device_name, mode);
+
+	if (opened_device_ptr) {
+		internal_debug("%s Device %s is opened yet.",
+				nilfs_message[BAD_DEVICE], device_name);
+		return -BAD_DEVICE;
+	}
+
+	opened_device_ptr = fopen(device_name, mode);
+	if (!opened_device_ptr) {
+		internal_debug("%s The mode %s is invalid for %s device.",
+				nilfs_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) {
+		internal_debug("%s",
+				"cannot convert pointer into descriptor.");
+		goto open_success;
+	}
+
+	/* In the case of error ioctl() returns -1 */
+	if (-1 == ioctl(file_descriptor, BLKSSZGET, &device_sector_size))
+		internal_debug("%s", "cannot detect device sector size.");
+	else
+		internal_debug("sector size %d.", device_sector_size);
+
+	/* In the case of error ioctl() returns -1 */
+	if (-1 == ioctl(file_descriptor, BLKGETSIZE64, &device_size_in_bytes))
+		internal_debug("%s", "cannot detect device size in bytes.");
+	else
+		internal_debug("device size in bytes %lld.",
+					device_size_in_bytes);
+
+open_success:
+	internal_debug("device %s is opened in %s mode successfully.",
+			device_name, mode);
+	return NILFS_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:
+ * NILFS_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:
+ * NILFS_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", nilfs_message[BAD_DEVICE],
+				nilfs_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:
+ * NILFS_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:
+ * NILFS_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;
+
+	internal_debug("%s", "try to close device.");
+
+	if (!opened_device_ptr) {
+		internal_debug("%s", nilfs_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) {
+		internal_debug("%s",
+				"cannot convert pointer into descriptor.");
+		goto close_device;
+	}
+
+	/* In the case of error fsync() returns -1 */
+	if (-1 == fsync(file_descriptor))
+		internal_debug("%s", nilfs_message[FLUSH_FAILED]);
+
+close_device:
+	if (fclose(opened_device_ptr)) {
+		internal_debug("%s",
+			nilfs_message[CANNOT_CLOSE_DEVICE]);
+		return -CANNOT_CLOSE_DEVICE;
+	}
+
+	device_sector_size = DEFAULT_SECTOR_SIZE;
+	device_size_in_bytes = 0;
+
+	internal_debug("%s", "device is closed successfully.");
+	return NILFS_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:
+ * NILFS_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 = NILFS_OK;
+
+	internal_debug("try to proccess %d bytes on %lld offset.",
+			requested_bytes_count, device_offset);
+
+	if (!raw_data_buffer || !actual_bytes_count) {
+		internal_debug("%s",
+				nilfs_message[INVALID_PARAMETER]);
+		internal_debug("raw_data_buffer is %p.",
+				raw_data_buffer);
+		internal_debug("actual_bytes_count is %p.",
+				actual_bytes_count);
+		return -INVALID_PARAMETER;
+	}
+
+	(*actual_bytes_count) = 0;
+
+	if (0 == requested_bytes_count) {
+		internal_debug("%s", "does nothing.");
+		return NILFS_OK;
+	}
+
+	if (!opened_device_ptr) {
+		internal_debug("%s", nilfs_message[DEVICE_NOT_OPENED]);
+		return -DEVICE_NOT_OPENED;
+	}
+
+	if (device_offset >= device_size_in_bytes) {
+		internal_debug("ATTENTION!!! Device size is %lld.",
+				device_size_in_bytes);
+		return -INVALID_PARAMETER;
+	}
+
+	if ((device_offset + requested_bytes_count) > device_size_in_bytes) {
+		internal_debug("%s",
+				nilfs_message[OUT_OF_VOLUME]);
+	}
+
+	if (0 != fseeko(opened_device_ptr, device_offset, SEEK_SET)) {
+		internal_debug("%s",
+				nilfs_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:
+		internal_debug("the requested value %d is invalid mode.",
+				op_mode);
+		err = -INVALID_PARAMETER;
+		goto raw_bytes_op_failed;
+	}
+
+	if (-1 == (*actual_bytes_count)) {
+		(*actual_bytes_count) = 0;
+		internal_debug("%s", nilfs_message[OP_FAILED]);
+		err = -OP_FAILED;
+		goto raw_bytes_op_failed;
+	} else if ((*actual_bytes_count) != requested_bytes_count) {
+		internal_debug("%s",
+				nilfs_message[DATA_PROCCESSED_PARTIALLY]);
+		internal_debug("Requested %d bytes. Proccessed %d bytes.",
+				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 {
+		internal_debug("Requested %d bytes proccessed successfully.",
+				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:
+ * NILFS_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 (libfsck)
+ *
+ * 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:
+ * NILFS_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() */
-- 
1.7.9.5



--
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