smp8671/android下nand/yaffs2文件莫名丢失及挂起问题分析1

1,现象:
    在smp8671-android数字电视系统开发过程中,系统启动过程中偶尔会出现系统停止的情形。串口中有时会打印(link_image[2329]: failed to link libGLESv1_CM.so,有时还能运行shell命令,有时不能。

2,重现问题
    为了抓取系统停止时的日志,特地做了一个不停重启,并且将日志打印到串口的一个init.rc。期望在正常情况下机器能够不停的重启,未正常运行到animation结束时,机器将保留当时状态。

    在init.rc中添加如下内容:

on property:init.svc.bootanim=stopped
    start reboot_a
service windlogcat /system/bin/logcat_daemon -f /dev/ttyS0 -v time
    oneshot
service reboot_a /reboot.sh
    disabled
	reboot.sh的内容为:
#! /system/bin/sh
echo "waitting 100s to reboot"
sleep 50
echo "reboot now .............."
reboot
    logcat_daemon只是对logcat做的一个包装,将logcat作为后台进程在运行。


3,分析
    A)由于怀疑程序的启动过程有问题,可执行程序的某些库未正常加载,故打开了bionic/linker中的日志开关LOCAL_CFLAGS += -DLINKER_DEBUG=1,打开此开关后,发现并非是linker的问题,问题在于某些so文件确实找不到。
    B)在分析链接库丢失过程中,偶然有一次进入了shell。提示信息为link_image[2329]: failed to link libGLESv1_CM.so。根据日志判断运行mediaserver未成功。

我手动运行mediaserver,得到打印

mediaserver
01-01 01:01:27.228 E/DCCHD ( 6764): [src/CMediaAccess.cpp:395] [Global]MediaAccess object created
link_image[2329]: failed to link mediaserver
CANNOT LINK EXECUTABLE
根据提示failed to link mediaserver,判断是有个so没有找到。后到一个正常的机器查看mediaserver所链接的库,发现是没有找到libGLESv1_CM.so。

然后cd /; busybox find -name "libGLES*",得到如下打印:

cd /; 
busybox find -name "libGLES*"
./system/lib/egl/libGLES_android.so
find: ./system/lib/libGLESv1_CM.so: No such file or directory
./system/lib/libGLESv2.so
很奇怪的打印,libGLESv1_CM.so为何会有如此打印?find的时候竟然能发现这个文件。

为此,特地写一个程序去读一个文件夹的内容。文件名为test_folder.cpp。此程序首先readdir得到其下所有节点,并且lstat查看这些entry。从运行结果判断是文件系统出了问题,从lstat系统调用开始查起,判断问题大概出在了yaffs驱动中。
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
int main (int argc, const char* argv[]) {
    DIR              *pDir = NULL;
    struct dirent    *ent  = NULL;
    char pathname[2048]= {0};
    const char* folder = argv[1];
    pDir = opendir (folder);
    if (pDir) {
        while ((ent = readdir (pDir)) != NULL) {
            if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..") == 0)
                continue;
            printf ("d_name=%s, d_reclen=%d, d_type=%u, d_off=%lld, d_ino=%llu\n", ent->d_name, ent->d_reclen, ent->d_type, ent->d_off, ent->d_ino);
            memset (pathname, 0, sizeof(pathname));
            strcpy (pathname, folder);
            strcat (pathname, "/");
            strcat (pathname, ent->d_name);
            struct stat buf;
            if (lstat (pathname, &buf) < 0) {
                printf ("%s!\n", strerror (errno));
                continue;
            }

            switch (buf.st_mode & S_IFMT) {
            case S_IFBLK:
                break;
            case S_IFCHR:
                break;
            case S_IFDIR:
                //INFO ("directory %s, not return to filelist", ent->d_name);
                //filelist.push_back(ent->d_name);
                break;
            case S_IFIFO:
                break;
            case S_IFLNK:
                break;
            case S_IFREG:
                //printf ("regular file\n");
                //filelist.push_back(ent->d_name);
                break;
            case S_IFSOCK:
                break;
            default:
                break;
            }
        }
        closedir (pDir);
        return 0;
    } else {
        printf ("opendir error(%s)!\n", folder);
        return -1;
    }
}
该程序运行结果:
d_name=libjni_file_manager_cmd.so, d_reclen=48, d_type=8, d_off=3, d_ino=399
d_name=libFFTEm.so, d_reclen=32, d_type=8, d_off=4, d_ino=398
d_name=libandroid_servers.so, d_reclen=48, d_type=8, d_off=5, d_ino=397
d_name=libstagefright_color_conversion.so, d_reclen=56, d_type=8, d_off=6, d_ino=396
d_name=libicudata.so, d_reclen=40, d_type=8, d_off=7, d_ino=395
d_name=libbinder.so, d_reclen=32, d_type=8, d_off=8, d_ino=394
d_name=libnetutils.so, d_reclen=40, d_type=8, d_off=9, d_ino=393
d_name=libopencore_mp4local.so, d_reclen=48, d_type=8, d_off=10, d_ino=392
d_name=libomx_m4vdec_sharedlibrary.so, d_reclen=56, d_type=8, d_off=11, d_ino=391
d_name=libutils.so, d_reclen=32, d_type=8, d_off=12, d_ino=390
d_name=libjni_latinime.so, d_reclen=40, d_type=8, d_off=13, d_ino=389
d_name=libhardware_legacy.so, d_reclen=48, d_type=8, d_off=14, d_ino=388
d_name=libsystem_server.so, d_reclen=40, d_type=8, d_off=15, d_ino=387
d_name=libomx_aacdec_sharedlibrary.so, d_reclen=56, d_type=8, d_off=16, d_ino=386
d_name=libffi.so, d_reclen=32, d_type=8, d_off=17, d_ino=385
d_name=libomx_mp3dec_sharedlibrary.so, d_reclen=56, d_type=8, d_off=18, d_ino=384
d_name=libstdc++.so, d_reclen=32, d_type=8, d_off=19, d_ino=383
d_name=libOMX.Sigma.Mp3.Decoder.so, d_reclen=48, d_type=8, d_off=20, d_ino=382
d_name=libxml2wbxml.so, d_reclen=40, d_type=8, d_off=21, d_ino=381
d_name=libomx_avcdec_sharedlibrary.so, d_reclen=56, d_type=8, d_off=22, d_ino=380
d_name=libsqlite.so, d_reclen=32, d_type=8, d_off=23, d_ino=379
d_name=libOMX.Sigma.Aac.Decoder.so, d_reclen=48, d_type=8, d_off=24, d_ino=378
d_name=librmlibplay_default_plugin.so, d_reclen=56, d_type=8, d_off=25, d_ino=377
d_name=libsmartinput_oem.so, d_reclen=40, d_type=8, d_off=26, d_ino=376
d_name=libstagefright_avc_common.so, d_reclen=48, d_type=8, d_off=27, d_ino=375
d_name=libSR_AudioIn.so, d_reclen=40, d_type=8, d_off=28, d_ino=374
d_name=libopencore_common.so, d_reclen=48, d_type=8, d_off=29, d_ino=373
d_name=libsurfaceflinger_client.so, d_reclen=48, d_type=8, d_off=30, d_ino=372
d_name=libjnigraphics.so, d_reclen=40, d_type=8, d_off=31, d_ino=371
d_name=libdcchd_android.so, d_reclen=40, d_type=8, d_off=32, d_ino=370
d_name=libiprouteutil.so, d_reclen=40, d_type=8, d_off=33, d_ino=369
d_name=libterm.so, d_reclen=32, d_type=8, d_off=34, d_ino=368
d_name=librdhdmi.so, d_reclen=32, d_type=8, d_off=35, d_ino=367
d_name=libhomecfg.so, d_reclen=40, d_type=8, d_off=36, d_ino=366
d_name=libexif.so, d_reclen=32, d_type=8, d_off=37, d_ino=365
d_name=libomx_amrenc_sharedlibrary.so, d_reclen=56, d_type=8, d_off=38, d_ino=364
d_name=libomx_amrdec_sharedlibrary.so, d_reclen=56, d_type=8, d_off=39, d_ino=363
d_name=liblog.so, d_reclen=32, d_type=8, d_off=40, d_ino=362
d_name=libthread_db.so, d_reclen=40, d_type=8, d_off=41, d_ino=361
d_name=libopencore_player.so, d_reclen=48, d_type=8, d_off=42, d_ino=360
d_name=libdrm1.so, d_reclen=32, d_type=8, d_off=43, d_ino=359
d_name=libskiagl.so, d_reclen=32, d_type=8, d_off=44, d_ino=358
d_name=libntp_server.so, d_reclen=40, d_type=8, d_off=45, d_ino=357
d_name=libemoji.so, d_reclen=32, d_type=8, d_off=46, d_ino=356
d_name=libstagefright.so, d_reclen=40, d_type=8, d_off=47, d_ino=355
d_name=libssl.so, d_reclen=32, d_type=8, d_off=48, d_ino=354
d_name=librmlibplay_realmedia_plugin.so, d_reclen=56, d_type=8, d_off=49, d_ino=353
d_name=libstlport.so, d_reclen=40, d_type=8, d_off=50, d_ino=352
d_name=libvorbisidec.so, d_reclen=40, d_type=8, d_off=51, d_ino=351
d_name=libEGL.so, d_reclen=32, d_type=8, d_off=52, d_ino=350
d_name=libfrontpanel.so, d_reclen=40, d_type=8, d_off=53, d_ino=349
d_name=libcore.so, d_reclen=32, d_type=8, d_off=54, d_ino=348
d_name=egl, d_reclen=24, d_type=4, d_off=55, d_ino=346
d_name=libsoundpool.so, d_reclen=40, d_type=8, d_off=56, d_ino=345
d_name=librs_jni.so, d_reclen=32, d_type=8, d_off=57, d_ino=344
d_name=invoke_mock_media_player.so, d_reclen=48, d_type=8, d_off=58, d_ino=343
d_name=libctest.so, d_reclen=32, d_type=8, d_off=59, d_ino=342
d_name=libdl.so, d_reclen=32, d_type=8, d_off=60, d_ino=341
d_name=libc_malloc_debug_qemu.so, d_reclen=48, d_type=8, d_off=61, d_ino=340
d_name=libwebcore.so, d_reclen=40, d_type=8, d_off=62, d_ino=339
d_name=libreference-cdma-sms.so, d_reclen=48, d_type=8, d_off=63, d_ino=338
d_name=libcrypto.so, d_reclen=32, d_type=8, d_off=64, d_ino=337
d_name=librmomx.so, d_reclen=32, d_type=8, d_off=65, d_ino=336
d_name=libstagefright_amrnb_common.so, d_reclen=56, d_type=8, d_off=66, d_ino=335
d_name=libsrec_jni.so, d_reclen=40, d_type=8, d_off=67, d_ino=334
d_name=libdiskconfig.so, d_reclen=40, d_type=8, d_off=68, d_ino=333
d_name=libstagefright_omx.so, d_reclen=48, d_type=8, d_off=69, d_ino=332
d_name=libnativehelper.so, d_reclen=40, d_type=8, d_off=70, d_ino=331
d_name=libdbus.so, d_reclen=32, d_type=8, d_off=71, d_ino=330
d_name=libjni_synctime.so, d_reclen=40, d_type=8, d_off=72, d_ino=329
d_name=libmedia_jni.so, d_reclen=40, d_type=8, d_off=73, d_ino=328
d_name=libc.so, d_reclen=32, d_type=8, d_off=74, d_ino=327
d_name=libz.so, d_reclen=32, d_type=8, d_off=75, d_ino=326
d_name=libhwdata.so, d_reclen=32, d_type=8, d_off=76, d_ino=325
d_name=libopencore_author.so, d_reclen=48, d_type=8, d_off=77, d_ino=324
d_name=libsurfaceflinger.so, d_reclen=40, d_type=8, d_off=78, d_ino=323
d_name=libGLESv1_CM.so, d_reclen=40, d_type=8, d_off=79, d_ino=322
No such file or directory!
d_name=libui.so, d_reclen=32, d_type=8, d_off=80, d_ino=321
d_name=libfactorytest.so, d_reclen=40, d_type=8, d_off=81, d_ino=320
d_name=libc_malloc_debug_leak.so, d_reclen=48, d_type=8, d_off=82, d_ino=319
d_name=libETC1.so, d_reclen=32, d_type=8, d_off=83, d_ino=318
d_name=libdrm.so, d_reclen=32, d_type=8, d_off=84, d_ino=317
d_name=libicui18n.so, d_reclen=40, d_type=8, d_off=85, d_ino=316
d_name=libopencore_rtsp.so, d_reclen=40, d_type=8, d_off=86, d_ino=315
d_name=libandroid_runtime.so, d_reclen=48, d_type=8, d_off=87, d_ino=314
d_name=libsysutils.so, d_reclen=40, d_type=8, d_off=88, d_ino=313
d_name=libttssynthproxy.so, d_reclen=40, d_type=8, d_off=89, d_ino=312
d_name=libmediaplayerservice.so, d_reclen=48, d_type=8, d_off=90, d_ino=311
d_name=libmedia.so, d_reclen=32, d_type=8, d_off=91, d_ino=310
d_name=libcamera_client.so, d_reclen=40, d_type=8, d_off=92, d_ino=309
d_name=libpagemap.so, d_reclen=40, d_type=8, d_off=93, d_ino=308
d_name=libhardware.so, d_reclen=40, d_type=8, d_off=94, d_ino=307
d_name=libfrontpaneljni.so, d_reclen=40, d_type=8, d_off=95, d_ino=306
d_name=libjni_pinyinime.so, d_reclen=40, d_type=8, d_off=96, d_ino=305
d_name=libjni_system_cmd.so, d_reclen=40, d_type=8, d_off=97, d_ino=304
d_name=libudhcp.so, d_reclen=32, d_type=8, d_off=98, d_ino=303
d_name=libreference-ril.so, d_reclen=40, d_type=8, d_off=99, d_ino=302
d_name=libttspico.so, d_reclen=40, d_type=8, d_off=100, d_ino=301
d_name=libopencore_rtspreg.so, d_reclen=48, d_type=8, d_off=101, d_ino=300
d_name=libacc.so, d_reclen=32, d_type=8, d_off=102, d_ino=299
d_name=libopencore_mp4localreg.so, d_reclen=48, d_type=8, d_off=103, d_ino=298
d_name=libril.so, d_reclen=32, d_type=8, d_off=104, d_ino=297
d_name=libpixelflinger.so, d_reclen=40, d_type=8, d_off=105, d_ino=296
d_name=libopencore_download.so, d_reclen=48, d_type=8, d_off=106, d_ino=295
d_name=libwpa_client.so, d_reclen=40, d_type=8, d_off=107, d_ino=294
d_name=libopencore_net_support.so, d_reclen=48, d_type=8, d_off=108, d_ino=293
d_name=libnetlink.so, d_reclen=40, d_type=8, d_off=109, d_ino=292
d_name=libcameraservice.so, d_reclen=40, d_type=8, d_off=110, d_ino=291
d_name=libGLESv2.so, d_reclen=32, d_type=8, d_off=111, d_ino=290
d_name=libplayback.so, d_reclen=40, d_type=8, d_off=112, d_ino=289
d_name=libcutils.so, d_reclen=32, d_type=8, d_off=113, d_ino=288
d_name=libOMX_Core.so, d_reclen=40, d_type=8, d_off=114, d_ino=287
d_name=libdvm.so, d_reclen=32, d_type=8, d_off=115, d_ino=286
d_name=libskia.so, d_reclen=32, d_type=8, d_off=116, d_ino=285
d_name=libdisplay.so, d_reclen=40, d_type=8, d_off=117, d_ino=284
d_name=libwbxml_jni.so, d_reclen=40, d_type=8, d_off=118, d_ino=283
d_name=libcurl.so, d_reclen=32, d_type=8, d_off=119, d_ino=282
d_name=libm.so, d_reclen=32, d_type=8, d_off=120, d_ino=281
d_name=libRS.so, d_reclen=32, d_type=8, d_off=121, d_ino=280
d_name=libmeterreader.so, d_reclen=40, d_type=8, d_off=122, d_ino=279
d_name=libdrm1_jni.so, d_reclen=40, d_type=8, d_off=123, d_ino=278
d_name=libopencore_downloadreg.so, d_reclen=48, d_type=8, d_off=124, d_ino=277
d_name=libaudioflinger.so, d_reclen=40, d_type=8, d_off=125, d_ino=276
d_name=hw, d_reclen=24, d_type=4, d_off=126, d_ino=271
d_name=CVS, d_reclen=24, d_type=4, d_off=127, d_ino=267
d_name=libicuuc.so, d_reclen=32, d_type=8, d_off=128, d_ino=266
d_name=libhw.so, d_reclen=32, d_type=8, d_off=129, d_ino=265
d_name=libOMX.Sigma.Video.Decoder.so, d_reclen=56, d_type=8, d_off=130, d_ino=264
d_name=libomx_sharedlibrary.so, d_reclen=48, d_type=8, d_off=131, d_ino=263
d_name=libsonivox.so, d_reclen=40, d_type=8, d_off=132, d_ino=262
d_name=librmlibrealmedia.so, d_reclen=40, d_type=8, d_off=133, d_ino=261
d_name=libsampleplugin.so, d_reclen=40, d_type=8, d_off=134, d_ino=260
d_name=libexpat.so, d_reclen=32, d_type=8, d_off=135, d_ino=259 

    C)打开yaffs驱动中的调试信息,修改yaffs_vfs_glue.c文件,打开YAFFS_TRACE_OS信息。
unsigned int yaffs_trace_mask = YAFFS_TRACE_BAD_BLOCKS | YAFFS_TRACE_ALWAYS | YAFFS_TRACE_OS;
    D)出现新现象,一直打印flushing obj 1027,分析代码发现unlink和flush同时对ip-up-vpn进行了操作。
[   24.296000] flushing obj 516
[   24.300000] yaffs_lookup for 276:ip-up-vpn
[   24.308000] flushing obj 515
[   24.312000] flushing obj 514
[   24.316000] flushing obj 513
[   24.320000] flushing obj 262
[   24.324000] flushing obj 267
[   24.328000] flushing obj 518
[   24.332000] flushing obj 295
[   24.336000] flushing obj 292
[   24.340000] flushing obj 260
[   24.344000] flushing obj 1025
[   24.348000] flushing obj 259
[   24.356000] flushing obj 269
[   24.360000] flushing obj 261
[   24.364000] yaffs_lookup found 1027
[   24.368000] flushing obj 270
[   24.372000] yaffs_get_inode for object 1027
[   24.376000] flushing obj 1
[   24.380000] yaffs_iget for 1027
[   24.388000] yaffs_write_super
[   24.392000] yaffs_do_sync_fs: gc-urgency 0 dirty no checkpoint
[   24.400000] yaffs_fill_inode mode 816d uid 0 gid 0 size 5248 count 1
[   24.408000] yaffs_loookup dentry 
[   24.412000] flushing obj 257
[   24.416000] yaffs_unlink 276:ip-up-vpn
[   24.420000] flushing obj 1
[   24.424000] yaffs_write_super
[   24.428000] yaffs_do_sync_fs: gc-urgency 0 dirty no checkpoint
[   24.436000] yaffs_touch_super() sb = 92c89000
[   24.448000] flushing obj 1027
[   24.452000] yaffs_delete_inode: ino 1027, count 0 object exists
[   24.460000] flushing obj 1027
[   24.464000] flushing obj 1027
[   24.468000] flushing obj 1027
[   24.472000] flushing obj 1027
[   24.476000] flushing obj 1027
[   24.480000] flushing obj 1027
[   24.484000] flushing obj 1027
[   24.488000] flushing obj 1027
[   24.492000] yaffs_file_flush object 865 (clean)
[   24.500000] yaffs_file_flush object 865 (clean)
[   24.504000] flushing obj 1027
[   24.508000] flushing obj 1027

    E)分析代码,怀疑是fs/yaffs2/yaffs_vfs_glue.c中的yaffs_flush_inodes函数有问题。将list_for_each_entry改为list_for_each_entry_safe测试。
    F)改过代码后,问题依旧,仍然不停打印flushing obj,分析代码发现,可能是链表被破坏了,导致一直在flushing某一个节点。修改yaffs_flush_inodes为如下,打印出链表的节点(曾经是只打印之后一个节点,证实了我的猜测,为了确定是什么地方改坏链表,特定将next_next打印出来,可以看出何时链表被破坏)。
static void yaffs_flush_inodes(struct super_block *sb)
{
    struct inode *iptr, *next, *next_next;
    yaffs_obj_t *obj;

    list_for_each_entry_safe(iptr,next,&sb->s_inodes, i_sb_list){
        obj = yaffs_InodeToObject(iptr);
        if(obj){
            yaffs_dev_t *dev = obj->my_dev;
            if (next)
                next_next = list_entry(next->i_sb_list.next, typeof(*iptr), i_sb_list);
            else
                next_next = NULL;
            T(YAFFS_TRACE_OS, (TSTR("flushing obj %d, iptr 0x%p(0x%p, 0x%p), dev 0x%p, sb 0x%p\n"),
                               obj->obj_id, iptr, next, next_next, dev, sb));

            //yaffs_gross_lock(dev); //本来试图在这里加锁,发现程序不能运行,查代码发现外层已经加锁了,所以这里不需要加锁
            yaffs_flush_file(obj, 1, 0);
            //yaffs_gross_unlock(dev);
        }
    }
}
    G)增加打印后,出现状况时的日志如下,可以发现sync_supers内核进程开始做文件系统同步时,来了一个yaffs_delete_inode,出现这个之后就发现链表已经不对了。
[   48.000000] windsome sync_supers
[   48.008000] yaffs_write_super
[   48.012000] yaffs_touch_super() sb = 92cd2200
[   48.024000] Added object 295 to dirty directories
[   48.032000] yaffs_do_sync_fs: gc-urgency 0 dirty no checkpoint
[   48.048000] yaffs_touch_super() sb = 92cd2200
[   48.052000] yaffs_background
[   48.052000] Update dirty directories
[   48.064000] yaffs_touch_super() sb = 92cd2200
[   48.072000] flushing obj 1031, iptr 0x935622e0(0x93562408, 0x93562d48), dev 0x92d51000, sb 0x92cd2200
[   48.080000] yaffs_delete_inode: ino 1033, count 0 object exists
[   48.100000] flushing obj 1033, iptr 0x93562408(0x93562408, 0x93562408), dev 0x92d51000, sb 0x92cd2200
[   48.128000] flushing obj 1033, iptr 0x93562408(0x93562408, 0x93562408), dev 0x92d51000, sb 0x92cd2200
[   48.156000] flushing obj 1033, iptr 0x93562408(0x93562408, 0x93562408), dev 0x92d51000, sb 0x92cd2200
[   48.184000] flushing obj 1033, iptr 0x93562408(0x93562408, 0x93562408), dev 0x92d51000, sb 0x92cd2200
[   48.212000] flushing obj 1033, iptr 0x93562408(0x93562408, 0x93562408), dev 0x92d51000, sb 0x92cd2200
    H)分析前一步日志,检查yaffs_delete_inode函数,发现此在此时应该被阻塞着。继续查调用此函数的地方。
static void yaffs_delete_inode(struct inode *inode)
{
    yaffs_obj_t *obj = yaffs_InodeToObject(inode);
    yaffs_dev_t *dev;

    T(YAFFS_TRACE_OS,
        (TSTR("yaffs_delete_inode: ino %d, count %d %s\n"), (int)inode->i_ino,
        atomic_read(&inode->i_count),
        obj ? "object exists" : "null object"));

    if (obj) {
        dev = obj->my_dev;
        yaffs_gross_lock(dev);
        //T(YAFFS_TRACE_OS, (TSTR("yaffs_delete_inode: windsome step 1\n")));
        yaffs_del_obj(obj);
        //T(YAFFS_TRACE_OS, (TSTR("yaffs_delete_inode: windsome step 2\n")));
        yaffs_gross_unlock(dev);
    }
    T(YAFFS_TRACE_OS, (TSTR("yaffs_delete_inode: return from lock\n")));
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
    truncate_inode_pages(&inode->i_data, 0);
#endif
    clear_inode(inode);
    T(YAFFS_TRACE_OS,
        (TSTR("yaffs_delete_inode: end\n")));
}
#endif
    I)分析发现yaffs_delete_inode是在fs/inode.c中被generic_delete_inode调用,此函数在调用delete_inode之前,已经调用list_del_init(&inode->i_sb_list);重新设置了此inode的指针,将此inode从链表中剔除了。调用 list_del_init后,inode已经指向自己,所以从程序上看就一直在循环了。
void generic_delete_inode(struct inode *inode)
{
    const struct super_operations *op = inode->i_sb->s_op;

    list_del_init(&inode->i_list);
    list_del_init(&inode->i_sb_list);
    WARN_ON(inode->i_state & I_NEW);
    inode->i_state |= I_FREEING;
    inodes_stat.nr_inodes--;
    spin_unlock(&inode_lock);

    security_inode_delete(inode);

    if (op->delete_inode) {
        void (*delete)(struct inode *) = op->delete_inode;
        if (!is_bad_inode(inode))
            vfs_dq_init(inode);
        /* Filesystems implementing their own
         * s_op->delete_inode are required to call
         * truncate_inode_pages and clear_inode()
         * internally */
        delete(inode);
    } else {
        truncate_inode_pages(&inode->i_data, 0);
        clear_inode(inode);
    }
    spin_lock(&inode_lock);
    hlist_del_init(&inode->i_hash);
    spin_unlock(&inode_lock);
    wake_up_inode(inode);
    BUG_ON(inode->i_state != I_CLEAR);
    destroy_inode(inode);
}
EXPORT_SYMBOL(generic_delete_inode);
    J)到了这一步,我们就知道怎么改了,inode已经从链表中剔除,也就不再需要做flushing了,修改yaffs_flush_inodes函数,如下:
static void yaffs_flush_inodes(struct super_block *sb)
{
    struct inode *iptr, *next;
    yaffs_obj_t *obj;

    list_for_each_entry_safe(iptr,next,&sb->s_inodes, i_sb_list){
        obj = yaffs_InodeToObject(iptr);
        if(obj){
            yaffs_dev_t *dev = obj->my_dev;
            T(YAFFS_TRACE_OS, (TSTR("yaffs_flush_inodes: flushing obj %d, iptr 0x%p(0x%p), dev 0x%p, sb 0x%p\n"),
                               obj->obj_id, iptr, next, dev, sb));

            if (next == iptr) {
                T(YAFFS_TRACE_OS, (TSTR("yaffs_flush_inodes: point to self! break to next time flushing\n")));
                break;
            }
            yaffs_flush_file(obj, 1, 0);
        }
    }
}

有问题可以联系 agooou@gmail.com


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值