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

📄 truncate.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
字号:
/* *  linux/fs/xiafs/truncate.c * *  Copyright (C) Q. Frank Xia, 1993. *   *  Based on Linus' minix/truncate.c *  Copyright (C) Linus Torvalds, 1991, 1992. * *  This software may be redistributed per Linux Copyright. */#include <linux/errno.h>#include <linux/sched.h>#include <linux/xia_fs.h>#include <linux/stat.h>#include <linux/fcntl.h>#include "xiafs_mac.h"/* * Linus' comment: * * Truncate has the most races in the whole filesystem: coding it is * a pain in the a**. Especially as I don't do any locking... * * The code may look a bit weird, but that's just because I've tried to * handle things like file-size changes in a somewhat graceful manner. * Anyway, truncating a file at the same time somebody else writes to it * is likely to result in pretty weird behaviour... * * The new code handles normal truncates (size = 0) as well as the more * general case (size = XXX). I hope. */#define DT_ZONE		((inode->i_size + XIAFS_ZSIZE(inode->i_sb) - 1) \			 >> XIAFS_ZSIZE_BITS(inode->i_sb) )static int trunc_direct(struct inode * inode){    u_long * lp;    struct buffer_head * bh;    int i, tmp;    int retry = 0;repeat:    for (i = DT_ZONE ; i < 8 ; i++) {        if (i < DT_ZONE)	    goto repeat;        lp=i + inode->u.xiafs_i.i_zone;        if (!(tmp = *lp))	    continue;	bh = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));	if (i < DT_ZONE) {	    brelse(bh);	    goto repeat;	}	if ((bh && bh->b_count != 1) || tmp != *lp)	    retry = 1;	else {	    *lp = 0;	    inode->i_dirt = 1;	    inode->i_blocks-=2 << XIAFS_ZSHIFT(inode->i_sb);	    xiafs_free_zone(inode->i_sb, tmp);	}	brelse(bh);    }    return retry;}static int trunc_indirect(struct inode * inode, int addr_off, u_long * lp){#define INDT_ZONE 	(DT_ZONE - addr_off)    struct buffer_head * bh, * ind_bh;    int i, tmp;    u_long * indp;    int retry = 0;    if ( !(tmp=*lp) )        return 0;    ind_bh = bread(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));    if (tmp != *lp) {        brelse(ind_bh);	return 1;    }    if (!ind_bh) {        *lp = 0;	return 0;    }repeat:    for (i = INDT_ZONE<0?0:INDT_ZONE; i < XIAFS_ADDRS_PER_Z(inode->i_sb); i++) {        if (i < INDT_ZONE)	    goto repeat;        indp = i+(u_long *) ind_bh->b_data;	if (!(tmp=*indp))	    continue;	bh = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));	if (i < INDT_ZONE) {	    brelse(bh);	    goto repeat;	}	if ((bh && bh->b_count != 1) || tmp != *indp)	    retry = 1;	else {	    *indp = 0;	    mark_buffer_dirty(ind_bh, 1);	    inode->i_blocks-= 2 << XIAFS_ZSHIFT(inode->i_sb);	    xiafs_free_zone(inode->i_sb, tmp);	}	brelse(bh);    }    indp = (u_long *) ind_bh->b_data;    for (i = 0; i < XIAFS_ADDRS_PER_Z(inode->i_sb) && !(*indp++); i++) ;    if (i >= XIAFS_ADDRS_PER_Z(inode->i_sb)) {      if (ind_bh->b_count != 1)	   retry = 1;      else {	  tmp = *lp;	  *lp = 0;	  inode->i_blocks-= 2 << XIAFS_ZSHIFT(inode->i_sb);	  xiafs_free_zone(inode->i_sb, tmp);      }    }    brelse(ind_bh);    return retry;}		static int trunc_dindirect(struct inode * inode){#define DINDT_ZONE \    ((DT_ZONE-XIAFS_ADDRS_PER_Z(inode->i_sb)-8)>>XIAFS_ADDRS_PER_Z_BITS(inode->i_sb))    int i, tmp;    struct buffer_head * dind_bh;    u_long * dindp, * lp;    int retry = 0;    lp = &(inode->u.xiafs_i.i_dind_zone);    if (!(tmp = *lp))        return 0;    dind_bh = bread(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));    if (tmp != *lp) {        brelse(dind_bh);	return 1;    }    if (!dind_bh) {        *lp = 0;	return 0;    }repeat:    for (i=DINDT_ZONE<0?0:DINDT_ZONE ; i < XIAFS_ADDRS_PER_Z(inode->i_sb) ; i ++) {        if (i < DINDT_ZONE)	    goto repeat;        dindp = i+(u_long *) dind_bh->b_data;	retry |= trunc_indirect(inode, 				8+((1+i)<<XIAFS_ADDRS_PER_Z_BITS(inode->i_sb)), 				dindp);	mark_buffer_dirty(dind_bh, 1);    }    dindp = (u_long *) dind_bh->b_data;    for (i = 0; i < XIAFS_ADDRS_PER_Z(inode->i_sb) && !(*dindp++); i++);    if (i >= XIAFS_ADDRS_PER_Z(inode->i_sb)) {        if (dind_bh->b_count != 1)	    retry = 1;	else {	    tmp = *lp;	    *lp = 0;	    inode->i_dirt = 1;	    inode->i_blocks-=2 << XIAFS_ZSHIFT(inode->i_sb);	    xiafs_free_zone(inode->i_sb, tmp);	}    }    brelse(dind_bh);    return retry;}void xiafs_truncate(struct inode * inode){    int retry;    if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||	  S_ISLNK(inode->i_mode)))        return;    while (1) {        retry = trunc_direct(inode);        retry |= trunc_indirect(inode, 8, &(inode->u.xiafs_i.i_ind_zone));         retry |= trunc_dindirect(inode);	if (!retry)	    break;	current->counter = 0;	schedule();    }    inode->i_ctime = inode->i_mtime = CURRENT_TIME;    inode->i_dirt = 1;}

⌨️ 快捷键说明

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