Hi all,
Hoping you all might be able to learn me something, I ask you:
1. Why does 2.3.10 ext2 always (currently) call
block_write_partial_page? Why not block_write_full_page when it
writes a full page? Is this a scheduled-for-2.3.11 thing or
something?
2. Is fsync() supposed to sync all outstanding writes for that file
handle only, or for the inode that is referenced by it?
In other words, if process A writes 100mb of data to /file1 and
then process B writes 1 block to /file1 and does fsync(), is the
fsync() supposed to return after writing the 100mb+1 block out, or
after process B's single block? (plus assorted metadata of course).
What do the relevant standards say?
In linux, for example, nfs syncs only the file, ext2 syncs the
inode. Syncing the file only is probably more logical, but dirty
buffers are hard to distinguish I guess.
3. Why does the fsync() file operation have a dentry argument? There
are some comments in the kernel about msync() calling fsync()
without a 'struct file *'. I couldn't find this anywhere in the
kernel. I've also run a linux-2.2.10-fsynccheck (yes, 2.2.10) which
basically does 'if (filp == NULL) printk("foo!\n");' and my logs
showed nothing? (But then again, I don't run X or shm stuff).
Is there some magic incantation or ritual for having an fsync()
operation called with a NULL "struct file *" ptr?
I'd be more logical which to have the fsync() _file_ operation only
have a "struct file" argument, right? I've made some patches which
do this, and it all seems to work. (But then _again_, I don't run X
or shm stuff :-)
4. [offtopic?] Why does the ioctl() file operation have an inode
argument? If it wants the inode it can do file->f_dentry->d_inode,
right? Few other file operations have an inode pointer.
5. I was doing fdatasync() yesterday (currently it does the same as
fsync(), I'm trying to fix that) when I had the following thoughts:
1. fdatasync() only syncs the data, not the metadata
2. So, it would likely be correct not to sync the inode itself on a
fdatasync()
3. Unfortunately, if a file has grown the inode must be updated to
reflect this.
4. So even fdatasync() might need to sync the metadata sometimes.
5. But fdatasync() never needs to sync the superblock.
Am I right here? If I am:
6. So, the only time when fdatasync() syncs the actual inode is when
something other than the access/modification times have changed.
Also,
7. The indirect blocks are part of the file data.
So, summarising:
1. superblocks:
fsync(): always ?
fdatasync(): never ?
2. bitmaps:
fsync(): ?
fdatasync(): never ?
3. inode table:
fsync(): yes ?
fdatasync(): only when something other than the time was
changed?
4. data blocks (including indirect blocks):
fsync(): yes
fdatasync(): yes
Comments?
6. I was planning on doing fdatasync by something like:
int (*fsync)(struct file *filp, int sync_metadata); or
int (*fsync)(struct file *filp, int full_fsync); or
int (*fsync)(struct file *filp, int sync_all);
Ideas?
I have some patches which remove the dentry argument from fsync(). I
also have patches which try to implement fdatasync correctly on
ext2. If anyone could answer (some of) these questions it would really
help improving these.
Thanks,
Lennert Buytenhek
<[EMAIL PROTECTED]>