⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 209-mini_fo.patch

📁 Linux Home Server 是专门为家庭和SOHO/SMB 设计的高性价比的ISCSI 存储服务器, 具有如下的特色: 强大的iscsi 存储服务器软件; 混合iscsi 和NAS 服务;
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
+#else+mini_fo_d_revalidate(dentry_t *dentry, int flags)+#endif+{+	int err1 = 1; /* valid = 1, invalid = 0 */+	int err2 = 1;+	dentry_t *hidden_dentry;+	dentry_t *hidden_sto_dentry;+++	check_mini_fo_dentry(dentry);++	hidden_dentry  = dtohd(dentry);+	hidden_sto_dentry = dtohd2(dentry);++	if(hidden_dentry &&+	   hidden_dentry->d_op &&+	   hidden_dentry->d_op->d_revalidate) {+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)+		err1 = hidden_dentry->d_op->d_revalidate(hidden_dentry, nd);+#else+		err1 = hidden_dentry->d_op->d_revalidate(hidden_dentry, flags);+#endif+	}+	if(hidden_sto_dentry &&+	   hidden_sto_dentry->d_op &&+	   hidden_sto_dentry->d_op->d_revalidate) {+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)+		err2 = hidden_sto_dentry->d_op->d_revalidate(hidden_sto_dentry, +							     nd);+#else+		err2 = hidden_sto_dentry->d_op->d_revalidate(hidden_sto_dentry, +							     flags);+#endif+	}++	/* mk: if one of the lower level dentries are valid,+	 * the mini_fo dentry is too.+	 */+	return (err1 || err2);+}+++STATIC int+mini_fo_d_hash(dentry_t *dentry, qstr_t *name)+{+	int err = 0;+	dentry_t *hidden_dentry;+	dentry_t *hidden_sto_dentry;++	/* hidden_dentry = mini_fo_hidden_dentry(dentry);+	 * hidden_sto_dentry = mini_fo_hidden_sto_dentry(dentry); */++	/* state 1, 3, 4, 5: build the hash for the storage dentry */+	if((dtopd(dentry)->state == MODIFIED) ||+	   (dtopd(dentry)->state == CREATED) ||+	   (dtopd(dentry)->state == DEL_REWRITTEN) ||+	   (dtopd(dentry)->state == DELETED)) {+		hidden_sto_dentry = dtohd2(dentry);+		if(hidden_sto_dentry &&+		   hidden_sto_dentry->d_op &&+		   hidden_sto_dentry->d_op->d_hash) {+			err = hidden_sto_dentry->d_op->d_hash(hidden_sto_dentry, name);+		}+		goto out;+	}+	/* state 2: build the hash for the base dentry */+	if(dtopd(dentry)->state == UNMODIFIED) {+		hidden_dentry = dtohd(dentry);+		if(hidden_dentry &&+		   hidden_dentry->d_op &&+		   hidden_dentry->d_op->d_hash) {+			err = hidden_dentry->d_op->d_hash(hidden_dentry, name);+		}+		goto out;+	}+	/* state 6: build hash for the dentry that exists */+	if(dtopd(dentry)->state == NON_EXISTANT) {+		hidden_sto_dentry = dtohd2(dentry);+		if(hidden_sto_dentry &&+		   hidden_sto_dentry->d_op &&+		   hidden_sto_dentry->d_op->d_hash) {+			err = hidden_sto_dentry->d_op->d_hash(hidden_sto_dentry, name);+			goto out;+		}+		hidden_dentry = dtohd(dentry);+		if(hidden_dentry &&+		   hidden_dentry->d_op &&+		   hidden_dentry->d_op->d_hash) {+			err = hidden_dentry->d_op->d_hash(hidden_dentry, name);+			goto out;+		}+	}++	printk(KERN_CRIT "mini_fo: d_hash: invalid state detected.\n");++ out:+	return err;+}+++STATIC int+mini_fo_d_compare(dentry_t *dentry, qstr_t *a, qstr_t *b)+{+	int err;+	dentry_t *hidden_dentry=NULL;++	/* hidden_dentry = mini_fo_hidden_dentry(dentry); */+	if(dtohd2(dentry))+		hidden_dentry = dtohd2(dentry);+	else if(dtohd(dentry))+		hidden_dentry = dtohd(dentry);++	if (hidden_dentry && hidden_dentry->d_op && hidden_dentry->d_op->d_compare) {+		err = hidden_dentry->d_op->d_compare(hidden_dentry, a, b);+	} else {+		err = ((a->len != b->len) || memcmp(a->name, b->name, b->len));+	}++	return err;+}+++int+mini_fo_d_delete(dentry_t *dentry)+{+	dentry_t *hidden_dentry;+	dentry_t *hidden_sto_dentry;+	int err = 0;++	/* this could be a negative dentry, so check first */+	if (!dtopd(dentry)) {+		printk(KERN_CRIT "mini_fo_d_delete: negative dentry passed.\n");+		goto out;+	}+	hidden_dentry = dtohd(dentry);+	hidden_sto_dentry = dtohd2(dentry);++	if(hidden_dentry) {+		if(hidden_dentry->d_op &&+		   hidden_dentry->d_op->d_delete) {+			err = hidden_dentry->d_op->d_delete(hidden_dentry);+		}+	}+	if(hidden_sto_dentry) {+		if(hidden_sto_dentry->d_op &&+		   hidden_sto_dentry->d_op->d_delete) {+			err = hidden_sto_dentry->d_op->d_delete(hidden_sto_dentry);+		}+	}++ out:+	return err;+}+++void+mini_fo_d_release(dentry_t *dentry)+{+	dentry_t *hidden_dentry;+	dentry_t *hidden_sto_dentry;+++	/* this could be a negative dentry, so check first */+	if (!dtopd(dentry)) {+		printk(KERN_CRIT "mini_fo_d_release: no private data.\n");+		goto out;+	}+	hidden_dentry = dtohd(dentry);+	hidden_sto_dentry = dtohd2(dentry);++	if(hidden_dentry) {+		/* decrement hidden dentry's counter and free its inode */+		dput(hidden_dentry);+	}+	if(hidden_sto_dentry) {+                /* decrement hidden dentry's counter and free its inode */+		dput(hidden_sto_dentry);+	}++	/* free private data (mini_fo_dentry_info) here */+	kfree(dtopd(dentry));+	__dtopd(dentry) = NULL;	/* just to be safe */+ out:+	return;+}+++/*+ * we don't really need mini_fo_d_iput, because dentry_iput will call iput() if+ * mini_fo_d_iput is not defined. We left this implemented for ease of+ * tracing/debugging.+ */+void+mini_fo_d_iput(dentry_t *dentry, inode_t *inode)+{+	iput(inode);+}+++struct dentry_operations mini_fo_dops = {+	d_revalidate:	mini_fo_d_revalidate,+	d_hash:		mini_fo_d_hash,+	d_compare:		mini_fo_d_compare,+	d_release:		mini_fo_d_release,+	d_delete:		mini_fo_d_delete,+	d_iput:		mini_fo_d_iput,+};Index: linux-2.6.21.7/fs/mini_fo/file.c===================================================================--- /dev/null+++ linux-2.6.21.7/fs/mini_fo/file.c@@ -0,0 +1,713 @@+/*+ * Copyright (c) 1997-2003 Erez Zadok+ * Copyright (c) 2001-2003 Stony Brook University+ *+ * For specific licensing information, see the COPYING file distributed with+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING.+ *+ * This Copyright notice must be kept intact and distributed with all+ * fistgen sources INCLUDING sources generated by fistgen.+ */+/*+ * Copyright (C) 2004, 2005 Markus Klotzbuecher <mk@creamnet.de>+ *+ * This program 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.+ */++/*+ *  $Id$+ */++#ifdef HAVE_CONFIG_H+# include <config.h>+#endif++#include "fist.h"+#include "mini_fo.h"+#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))++/*******************+ * File Operations *+ *******************/++STATIC loff_t+mini_fo_llseek(file_t *file, loff_t offset, int origin)+{+	loff_t err;+	file_t *hidden_file = NULL;++	if(S_ISDIR(file->f_dentry->d_inode->i_mode)) {+		/* Check if trying to llseek from a directory */+		err = -EISDIR;+		goto out;+	}+	if (ftopd(file) != NULL) {+		if(ftohf2(file)) {+			hidden_file = ftohf2(file);+		} else {+			hidden_file = ftohf(file);+		}+	}++	/* always set hidden position to this one */+	hidden_file->f_pos = file->f_pos;++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)+	memcpy(&(hidden_file->f_ra), +	       &(file->f_ra), +	       sizeof(struct file_ra_state));+#else+	if (file->f_reada) { /* update readahead information if needed */+		hidden_file->f_reada = file->f_reada;+		hidden_file->f_ramax = file->f_ramax;+		hidden_file->f_raend = file->f_raend;+		hidden_file->f_ralen = file->f_ralen;+		hidden_file->f_rawin = file->f_rawin;+	}+#endif+	if (hidden_file->f_op && hidden_file->f_op->llseek)+		err = hidden_file->f_op->llseek(hidden_file, offset, origin);+	else+		err = generic_file_llseek(hidden_file, offset, origin);++	if (err < 0)+		goto out;++	if (err != file->f_pos) {+		file->f_pos = err;+		// ION maybe this?+		// 	file->f_pos = hidden_file->f_pos;+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+		file->f_reada = 0;+#endif+		file->f_version++;+	}++ out:+	return err;+}+++/* mk: fanout capable */+STATIC ssize_t+mini_fo_read(file_t *file, char *buf, size_t count, loff_t *ppos)+{+	int err = -EINVAL;+	file_t *hidden_file = NULL;+	loff_t pos = *ppos;++	if(S_ISDIR(file->f_dentry->d_inode->i_mode)) {+		/* Check if trying to read from a directory */+		/* printk(KERN_CRIT "mini_fo_read: ERROR: trying to read data from a directory.\n"); */+		err = -EISDIR;+		goto out;+	}++	if (ftopd(file) != NULL) {+		if(ftohf2(file)) {+			hidden_file = ftohf2(file);+		} else {+			hidden_file = ftohf(file);+		}+	}++	if (!hidden_file->f_op || !hidden_file->f_op->read)+		goto out;++	err = hidden_file->f_op->read(hidden_file, buf, count, &pos);+	*ppos = pos;++	if (err >= 0) {+		/* atime should also be updated for reads of size zero or more */+		fist_copy_attr_atime(file->f_dentry->d_inode,+				     hidden_file->f_dentry->d_inode);+	}++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+	/*+	 * MAJOR HACK+	 * because pread() does not have any way to tell us that it is+	 * our caller, then we don't know for sure if we have to update+	 * the file positions.  This hack relies on read() having passed us+	 * the "real" pointer of its struct file's f_pos field.+	 */+	if (ppos == &file->f_pos)+		hidden_file->f_pos = *ppos = pos;+	if (hidden_file->f_reada) { /* update readahead information if needed */+		file->f_reada = hidden_file->f_reada;+		file->f_ramax = hidden_file->f_ramax;+		file->f_raend = hidden_file->f_raend;+		file->f_ralen = hidden_file->f_ralen;+		file->f_rawin = hidden_file->f_rawin;+	}+#else+	memcpy(&(file->f_ra),&(hidden_file->f_ra),sizeof(struct file_ra_state));+#endif++ out:+	return err;+}+++/* this mini_fo_write() does not modify data pages! */+STATIC ssize_t+mini_fo_write(file_t *file, const char *buf, size_t count, loff_t *ppos)+{+	int err = -EINVAL;+	file_t *hidden_file = NULL;+	inode_t *inode;+	inode_t *hidden_inode;+	loff_t pos = *ppos;++	/* mk: fan out: */+	if (ftopd(file) != NULL) {+		if(ftohf2(file)) {+			hidden_file = ftohf2(file);+		} else {+			/* This is bad! We have no storage file to write to. This+			 * should never happen because if a file is opened for+			 * writing, a copy should have been made earlier.+			 */+			printk(KERN_CRIT "mini_fo: write : ERROR, no storage file to write.\n");+			err = -EINVAL;+			goto out;+		}+	}++	inode = file->f_dentry->d_inode;+	hidden_inode = itohi2(inode);+	if(!hidden_inode) {+		printk(KERN_CRIT "mini_fo: write: no sto inode found, not good.\n");+		goto out;+	}++	if (!hidden_file->f_op || !hidden_file->f_op->write)+		goto out;++	/* adjust for append -- seek to the end of the file */+	if (file->f_flags & O_APPEND)+		pos = inode->i_size;++	err = hidden_file->f_op->write(hidden_file, buf, count, &pos);++	/*+	 * copy ctime and mtime from lower layer attributes+	 * atime is unchanged for both layers+	 */+	if (err >= 0)+		fist_copy_attr_times(inode, hidden_inode);+	+	*ppos = pos;+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+	/*+	 * XXX: MAJOR HACK+	 *+	 * because pwrite() does not have any way to tell us that it is+	 * our caller, then we don't know for sure if we have to update+	 * the file positions.  This hack relies on write() having passed us+	 * the "real" pointer of its struct file's f_pos field.+	 */+	if (ppos == &file->f_pos)+		hidden_file->f_pos = *ppos = pos;+#endif+	/* update this inode's size */+	if (pos > inode->i_size)+		inode->i_size = pos;++ out:+	return err;+}++/* Global variable to hold a file_t pointer.+ * This serves to allow mini_fo_filldir function to know which file is+ * beeing read, which is required for two reasons:+ *+ *   - be able to call wol functions in order to avoid listing deleted+ *     base files.+ *   - if we're reading a directory which is in state 1, we need to+ *     maintain a list (in mini_fo_filldir) of which files allready + *     have been copied to userspace,to detect files existing in base+ *     and storage and not list them twice.+ */+filldir_t mini_fo_filldir_orig;+file_t *mini_fo_filldir_file;++/* mainly copied from fs/readdir.c */+STATIC int+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)+mini_fo_filldir(void * __buf, const char * name, int namlen, loff_t offset,+		  u64 ino, unsigned int d_type)+#else+mini_fo_filldir(void * __buf, const char * name, int namlen, loff_t offset,+		  ino_t ino, unsigned int d_type)+#endif+{+	struct getdents_callback * buf = (struct getdents_callback *) __buf;+	file_t* file = mini_fo_filldir_file;++	/* In theses states we filter meta files in storage (WOL) */+	if(file && (dtopd(file->f_dentry)->state == MODIFIED ||+		    dtopd(file->f_dentry)->state == CREATED ||+		    dtopd(file->f_dentry)->state == DEL_REWRITTEN)) {++		int tmp = strlen(META_FILENAME);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -