dir.c

来自「elinux jffs初始版本 具体了解JFFS的文件系统!」· C语言 代码 · 共 1,279 行 · 第 1/2 页

C
1,279
字号
                i->next->prev = i->prev;                i->prev->next = i->next;		DDPRINTK("ncp_free_inode_info: freeing %s\n",			 i->finfo.i.entryName);                ncp_kfree_s(i, sizeof(struct ncp_inode_info));                if (dir == i) return;                (dir->nused)--;                i = dir;        }}        voidncp_init_root(struct ncp_server *server){        struct ncp_inode_info *root = &(server->root);	struct nw_info_struct *i = &(root->finfo.i);	unsigned short dummy;	DPRINTK("ncp_init_root: server %s\n", server->m.server_name);	DPRINTK("ncp_init_root: i = %x\n", (int)i);        root->finfo.opened = 0;	i->attributes  = aDIR;	i->dataStreamSize = 1024;	i->dirEntNum = i->DosDirNum = 0;	i->volNumber = NCP_NUMBER_OF_VOLUMES+1;	/* illegal volnum */	ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate));	ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate));	ncp_date_unix2dos(0, &dummy, &(i->lastAccessDate));	i->nameLen = 0;	i->entryName[0] = '\0';        root->state = NCP_INODE_LOOKED_UP;        root->nused = 1;        root->dir   = root;        root->next = root->prev = root;        return;}intncp_conn_logged_in(struct ncp_server *server){	if (server->m.mounted_vol[0] == '\0')	{		return 0;	}	str_upper(server->m.mounted_vol);	if (ncp_lookup_volume(server, server->m.mounted_vol,			      &(server->root.finfo.i)) != 0)	{		return -ENOENT;	}	str_lower(server->root.finfo.i.entryName);	return 0;}voidncp_free_all_inodes(struct ncp_server *server){        /* Here nothing should be to do. I do not know whether it's           better to leave some memory allocated or be stuck in an           endless loop */#if 1        struct ncp_inode_info *root = &(server->root);        if (root->next != root)	{                printk("ncp_free_all_inodes: INODES LEFT!!!\n");        }        while (root->next != root)	{                printk("ncp_free_all_inodes: freeing inode\n");                ncp_free_inode_info(root->next);                /* In case we have an endless loop.. */                schedule();        }#endif                        return;}/* We will search the inode that belongs to this name, currently by a   complete linear search through the inodes belonging to this   filesystem. This has to be fixed. */static struct ncp_inode_info *ncp_find_dir_inode(struct inode *dir, const char *name){	struct ncp_server *server = NCP_SERVER(dir);	struct nw_info_struct *dir_info = NCP_ISTRUCT(dir);        struct ncp_inode_info *result = &(server->root);        if (name == NULL)	{                return NULL;	}        do	{		if (   (result->dir->finfo.i.dirEntNum == dir_info->dirEntNum)		    && (result->dir->finfo.i.volNumber == dir_info->volNumber)		    && (strcmp(result->finfo.i.entryName, name) == 0)		    /* The root dir is never looked up using this		     * routine.  Without the following test a root		     * directory 'sys' in a volume named 'sys' could		     * never be looked up, because		     * server->root->dir==server->root. */		    && (result != &(server->root)))		{                        return result;		}                result = result->next;        }	while (result != &(server->root));        return NULL;}static int ncp_lookup(struct inode *dir, const char *__name, int len,           struct inode **result){	struct nw_file_info finfo;	struct ncp_server *server;	struct ncp_inode_info *result_info;	int found_in_cache;	int down_case = 0;	char name[len+1];	*result = NULL;	if (!dir || !S_ISDIR(dir->i_mode))	{		printk("ncp_lookup: inode is NULL or not a directory.\n");		iput(dir);		return -ENOENT;	}	server = NCP_SERVER(dir);	if (!ncp_conn_valid(server))	{		iput(dir);		return -EIO;	}	DPRINTK("ncp_lookup: %s, len %d\n", __name, len);	/* Fast cheat for . */	if (len == 0 || (len == 1 && __name[0] == '.'))	{		*result = dir;		return 0;	}	/* ..and for .. */	if (len == 2 && __name[0] == '.' && __name[1] == '.')	{		struct ncp_inode_info *parent = NCP_INOP(dir)->dir;		if (parent->state == NCP_INODE_CACHED)		{			parent->state = NCP_INODE_LOOKED_UP;		}		*result = iget(dir->i_sb, ncp_info_ino(server, parent));		iput(dir);		if (*result == 0)		{			return -EACCES;		}		else		{			return 0;		}	}	memcpy(name, __name, len);	name[len] = 0;	lock_super(dir->i_sb);	result_info = ncp_find_dir_inode(dir, name);        if (result_info != 0)	{                if (result_info->state == NCP_INODE_CACHED)		{                        result_info->state = NCP_INODE_LOOKED_UP;		}                /* Here we convert the inode_info address into an                   inode number */                *result = iget(dir->i_sb, ncp_info_ino(server, result_info));		unlock_super(dir->i_sb);                iput(dir);                if (*result == NULL)		{                        return -EACCES;                }		return 0;        }        /* If the file is in the dir cache, we do not have to ask the           server. */        found_in_cache = 0;	ncp_lock_dircache();        if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino))	{                int first = c_last_returned_index;                int i;                i = first;                do		{                        DDPRINTK("ncp_lookup: trying index: %d, name: %s\n",				 i, c_entry[i].i.entryName);                        if (strcmp(c_entry[i].i.entryName, name) == 0)			{                                DPRINTK("ncp_lookup: found in cache!\n");				finfo.i = c_entry[i].i;				found_in_cache = 1;				break;                        }                        i = (i + 1) % c_size;                }		while (i != first);        }	ncp_unlock_dircache();        if (found_in_cache == 0)	{		int res;		DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",			 NCP_ISTRUCT(dir)->entryName, name);		if (ncp_is_server_root(dir))		{			str_upper(name);			down_case = 1;			res = ncp_lookup_volume(server, name, &(finfo.i));		}		else		{			if (!ncp_preserve_case(dir))			{				str_upper(name);				down_case = 1;			}			res = ncp_obtain_info(server,					      NCP_ISTRUCT(dir)->volNumber,					      NCP_ISTRUCT(dir)->dirEntNum,					      name, &(finfo.i));		}		if (res != 0)		{			unlock_super(dir->i_sb);                        iput(dir);                        return -ENOENT;                }        }	finfo.opened = 0;	if (down_case != 0)	{		str_lower(finfo.i.entryName);	}	if (!(*result = ncp_iget(dir, &finfo)))	{		unlock_super(dir->i_sb);		iput(dir);		return -EACCES;	}	unlock_super(dir->i_sb);	iput(dir);	return 0;}static int ncp_create(struct inode *dir, const char *name, int len, int mode,           struct inode **result){	struct nw_file_info finfo;	__u8 _name[len+1];	*result = NULL;	if (!dir || !S_ISDIR(dir->i_mode))	{		printk("ncp_create: inode is NULL or not a directory\n");		iput(dir);		return -ENOENT;	}	if (!ncp_conn_valid(NCP_SERVER(dir)))	{		iput(dir);		return -EIO;	}	strncpy(_name, name, len);	_name[len] = '\0';	if (!ncp_preserve_case(dir))	{		str_upper(_name);	}	lock_super(dir->i_sb);	if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),					   NCP_ISTRUCT(dir), _name,					   OC_MODE_CREATE|OC_MODE_OPEN|					   OC_MODE_REPLACE,					   0, AR_READ|AR_WRITE,					   &finfo) != 0)	{		unlock_super(dir->i_sb);		iput(dir);		return -EACCES;	}	ncp_invalid_dir_cache(dir);	if (!ncp_preserve_case(dir))	{		str_lower(finfo.i.entryName);	}	finfo.access = O_RDWR;	if (!(*result = ncp_iget(dir, &finfo)) < 0)	{		ncp_close_file(NCP_SERVER(dir), finfo.file_handle);		unlock_super(dir->i_sb);		iput(dir);		return -EINVAL;	}	unlock_super(dir->i_sb);	iput(dir);	return 0;	}static intncp_mkdir(struct inode *dir, const char *name, int len, int mode){	int error;	struct nw_file_info new_dir;	__u8 _name[len+1];	if (   (name[0] == '.')	    && (   (len == 1)		|| (   (len == 2)		    && (name[1] == '.'))))	{		iput(dir);		return -EEXIST;	}	strncpy(_name, name, len);	_name[len] = '\0';	if (!ncp_preserve_case(dir))	{		str_upper(_name);	}	if (!dir || !S_ISDIR(dir->i_mode))	{		printk("ncp_mkdir: inode is NULL or not a directory\n");		iput(dir);		return -ENOENT;	}	if (!ncp_conn_valid(NCP_SERVER(dir)))	{		iput(dir);		return -EIO;	}	if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),					   NCP_ISTRUCT(dir), _name,					   OC_MODE_CREATE, aDIR, 0xffff,					   &new_dir) != 0)	{		error = -EACCES;	}	else	{		error = 0;                ncp_invalid_dir_cache(dir);        }	iput(dir);	return error;}static intncp_rmdir(struct inode *dir, const char *name, int len){	int error;	__u8 _name[len+1];	if (!dir || !S_ISDIR(dir->i_mode))	{		printk("ncp_rmdir: inode is NULL or not a directory\n");		iput(dir);		return -ENOENT;	}	if (!ncp_conn_valid(NCP_SERVER(dir)))	{		iput(dir);		return -EIO;	}        if (ncp_find_dir_inode(dir, name) != NULL)	{                error = -EBUSY;        }	else	{		strncpy(_name, name, len);		_name[len] = '\0';		if (!ncp_preserve_case(dir))		{			str_upper(_name);		}                if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),						    NCP_ISTRUCT(dir),						    _name)) == 0)		{                        ncp_invalid_dir_cache(dir);		}		else		{			error = -EACCES;		}        }	iput(dir);	return error;}static intncp_unlink(struct inode *dir, const char *name, int len){	int error;	__u8 _name[len+1];	if (!dir || !S_ISDIR(dir->i_mode))	{		printk("ncp_unlink: inode is NULL or not a directory\n");		iput(dir);		return -ENOENT;	}	if (!ncp_conn_valid(NCP_SERVER(dir)))	{		iput(dir);		return -EIO;	}        if (ncp_find_dir_inode(dir, name) != NULL)	{                error = -EBUSY;        }	else	{		strncpy(_name, name, len);		_name[len] = '\0';		if (!ncp_preserve_case(dir))		{			str_upper(_name);		}                if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),						    NCP_ISTRUCT(dir),						    _name)) == 0)		{                        ncp_invalid_dir_cache(dir);		}		else		{			error = -EACCES;		}        }	iput(dir);	return error;}static intncp_rename(struct inode *old_dir, const char *old_name, int old_len,           struct inode *new_dir, const char *new_name, int new_len,           int must_be_dir){	int res;	char _old_name[old_len+1];	char _new_name[new_len+1];	if (!old_dir || !S_ISDIR(old_dir->i_mode))	{		printk("ncp_rename: old inode is NULL or not a directory\n");                res = -ENOENT;                goto finished;	}	if (!ncp_conn_valid(NCP_SERVER(old_dir)))	{		res = -EIO;		goto finished;	}	if (!new_dir || !S_ISDIR(new_dir->i_mode))	{		printk("ncp_rename: new inode is NULL or not a directory\n");                res = -ENOENT;                goto finished;	}        if (   (ncp_find_dir_inode(old_dir, old_name) != NULL)            || (ncp_find_dir_inode(new_dir, new_name) != NULL))	{                res = -EBUSY;                goto finished;        }	strncpy(_old_name, old_name, old_len);	_old_name[old_len] = '\0';	if (!ncp_preserve_case(old_dir))	{		str_upper(_old_name);	}	strncpy(_new_name, new_name, new_len);	_new_name[new_len] = '\0';	if (!ncp_preserve_case(new_dir))	{		str_upper(_new_name);	}	res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),					    NCP_ISTRUCT(old_dir), _old_name,					    NCP_ISTRUCT(new_dir), _new_name);        if (res == 0)	{                ncp_invalid_dir_cache(old_dir);                ncp_invalid_dir_cache(new_dir);        }	else	{		res = -EACCES;	}	 finished:	iput(old_dir); 	iput(new_dir);	return res;}/* The following routines are taken directly from msdos-fs *//* Linear day numbers of the respective 1sts in non-leap years. */static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };		  /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */extern struct timezone sys_tz;static intutc2local(int time){        return time - sys_tz.tz_minuteswest*60 + sys_tz.tz_dsttime*3600;}static intlocal2utc(int time){        return time + sys_tz.tz_minuteswest*60 - sys_tz.tz_dsttime*3600;}/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */intncp_date_dos2unix(unsigned short time,unsigned short date){	int month,year,secs;	month = ((date >> 5) & 15)-1;	year = date >> 9;	secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*	    ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 &&	    month < 2 ? 1 : 0)+3653);			/* days since 1.1.70 plus 80's leap day */	return local2utc(secs);}/* Convert linear UNIX date to a MS-DOS time/date pair. */voidncp_date_unix2dos(int unix_date,unsigned short *time, unsigned short *date){	int day,year,nl_day,month;	unix_date = utc2local(unix_date);	*time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+	    (((unix_date/3600) % 24) << 11);	day = unix_date/86400-3652;	year = day/365;	if ((year+3)/4+365*year > day) year--;	day -= (year+3)/4+365*year;	if (day == 59 && !(year & 3)) {		nl_day = day;		month = 2;	}	else {		nl_day = (year & 3) || day <= 59 ? day : day-1;		for (month = 0; month < 12; month++)			if (day_n[month] > nl_day) break;	}	*date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9);}

⌨️ 快捷键说明

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