萬盛學電腦網

 萬盛學電腦網 >> 服務器教程 >> Linux系統調用fsync函數詳解

Linux系統調用fsync函數詳解

   功能描述:

  同步內存中所有已修改的文件數據到儲存設備。

  用法:

  #include

  int fsync(int fd);

  參數:

  fd:文件描述詞。

  返回說明:

  成功執行時,返回0。失敗返回-1,errno被設為以下的某個值

  EBADF: 文件描述詞無效

  EIO : 讀寫的過程中發生錯誤

  EROFS, EINVAL:文件所在的文件系統不支持同步

  強制把系統緩存寫入文件sync和fsync函數,, fflush和fsync的聯系和區別2010-05-10 11:25傳統的U N I X實現在內核中設有緩沖存儲器,大多數磁盤I / O都通過緩存進行。當將數據寫

  到文件上時,通常該數據先由內核復制到緩存中,如果該緩存尚未寫滿,則並不將其排入輸出

  隊列,而是等待其寫滿或者當內核需要重用該緩存以便存放其他磁盤塊數據時,再將該緩存排

  入輸出隊列,然後待其到達隊首時,才進行實際的I / O操作。這種輸出方式被稱之為延遲寫

  (delayed write)(Bach 〔1 9 8 6〕第3章詳細討論了延遲寫)。延遲寫減少了磁盤讀寫次數,但是

  第4章文件和目錄8 7

  下載

  卻降低了文件內容的更新速度,使得欲寫到文件中的數據在一段時間內並沒有寫到磁盤上。當

  系統發生故障時,這種延遲可能造成文件更新內容的丟失。為了保證磁盤上實際文件系統與緩

  存中內容的一致性,U N I X系統提供了s y n c和f s y n c兩個系統調用函數。

  #include

  void sync(void);

  int fsync(intf i l e d e s) ;

  返回:若成功則為0,若出錯則為-1

  s y n c只是將所有修改過的塊的緩存排入寫隊列,然後就返回,它並不等待實際I / O操作結束。

  系統精靈進程(通常稱為u p d a t e )一般每隔3 0秒調用一次s y n c函數。這就保證了定期刷新內

  核的塊緩存。命令s y n c ( 1 )也調用s y n c函數。

  函數f s y n c只引用單個文件(由文件描述符f i l e d e s指定),它等待I / O結束,然後返回。f s y n c可

  用於數據庫這樣的應用程序,它確保修改過的塊立即寫到磁盤上。比較一下f s y n c和O _ S Y N C標

  志(見3 . 1 3節)。當調用f s y n c時,它更新文件的內容,而對於O _ S Y N C,則每次對文件調用w r i t e

  函數時就更新文件的內容。

  fflush和fsync的聯系和區別

  [zz ] http://blog.chinaunix.net/u2/73874/showart_1421917.html

  1.提供者fflush是libc.a中提供的方法,fsync是系統提供的系統調用。2.原形fflush接受一個參數FILE *.fflush(FILE *);fsync接受的時一個Int型的文件描述符。fsync(int fd);3.功能fflush:是把C庫中的緩沖調用write函數寫到磁盤[其實是寫到內核的緩沖區]。fsync:是把內核緩沖刷到磁盤上。

  c庫緩沖-----fflush---------〉內核緩沖--------fsync-----〉磁盤

  再轉一篇英文的

  Write-back support

  UBIFS supports write-back, which means that file changes do not go to the flash media straight away, but they are cached and go to the flash later, when it is absolutely necessary. This helps to greatly reduce the amount of I/O which results in better performance. Write-back caching is a standard technique which is used by most file systems like ext3 or XFS.

  In contrast, JFFS2 does not have write-back support and all the JFFS2 file system changes go the flash synchronously. Well, this is not completely true and JFFS2 does have a small buffer of a NAND page size (if the underlying flash is NAND). This buffer contains last written data and is flushed once it is full. However, because the amount of cached data are very small, JFFS2 is very close to a synchronous file system.

  Write-back support requires the application programmers to take extra care about synchronizing important files in time. Otherwise the files may corrupt or disappear in case of power-cuts, which happens very often in many embedded devices. Let's take a glimpse at Linux manual pages:

  $ man 2 write

  ....

  NOTES

  A successful return from write() does not make any guarantee that data

  has been committed to disk. In fact, on some buggy implementations, it

  does not even guarantee that space has successfully been reserved for

  the data. The only way to be sure is to call fsync(2) after you are

  done writing all your data.

  ...

  This is true for UBIFS (except of the "some buggy implementations" part, because UBIFS does reserves space for cached dirty data). This is also true for JFFS2, as well as for any other Linux file system.

  However, some (perhaps not very good) user-space programmers do not take write-back into account. They do not read manual pages carefully. When such applications are used in embedded systems which run JFFS2 - they work fine, because JFFS2 is almost synchronous. Of course, the applications are buggy, but they appear to work well enough with JFFS2. But the bugs show up when UBIFS is used instead. Please, be careful and check/test your applications with respect to power cut tolerance if you switch from JFFS2 to UBIFS. The following is a list of useful hints and advices.

  If you want to switch into synchronous mode, use the -o sync option when mounting UBIFS; however, the file system performance will drop - be careful; Also remember that UBIFS mounted in synchronous mode provides less guarantees than JFFS2 - refer this section for details.

  Always keep in mind the above statement from the manual pages and run fsync() for all important files you change; of course, there is no need to synchronize "throw-away" temporary files; Just think how important is the file data and decide; and do not use fsync() unnecessarily, because this will hit the performance;

  If you want to be more accurate, you may use fdatasync(), in which cases only data changes will be flushed, but not inode meta-data changes (e.g., "mtime" or permissions); this might be more optimal than using fsync() if the synchronization is done often, e.g., in a loop; otherwise just stick with fsync();

  In shell, the sync command may be used, but it synchronizes whole file system which might be not very optimal; and there is a similar libc sync() function;

  You may use the O_SYNC flag of the open() call; this will make sure all the data (but not meta-data) changes go to the media before the write() operation returns; but in general, it is better to use fsync(), because O_SYNC makes each write to be synchronous, while fsync() allows to accumulate many writes and synchronize them at once;

  It is possible to make certain inodes to be synchronous by default by setting the "sync" inode flag; in a shell, the chattr +S command may be used; in C programs, use the FS_IOC_SETFLAGS ioctl command; Note, the mkfs.ubifs tool checks for the "sync" flag in the original FS tree, so the synchronous files in the original FS tree will be synchronous in the resulting UBIFS image.

  Let us stress that the above items are true for any Linux file system, including JFFS2.

  fsync() may be called for directories - it synchronizes the directory inode meta-data. The "sync" flag may also be set for directories to make the directory inode synchronous. But the flag is inherited, which means all new children of this directory will also have this flag. New files and sub-directories of this directory will also be synchronous, and their children, and so forth. This feature is very useful if one needs to create a whole sub-tree of synchronous files and directories, or to make all new children of some directory to be synchronous by default (e.g., /etc).

  The fdatasync() call for directories is "no-op" in UBIFS and all UBIFS operations which change directory entries are synchronous. However, you should not assume this for portability (e.g., this is not true for ext2). Similarly, the "dirsync" inode flag has no effect in UBIFS.

  The functions mentioned above work on file-descriptors,

copyright © 萬盛學電腦網 all rights reserved