Defined option delay_mtime to delay updates of mtime+ctime

This patch avoid updating the time stamps whenever a file is modified,
by delaying the time stamps updating until the file is closed.
This is mostly useful when the ntfs file system hosts another loop-monted
file system to avoid frequent updates of the time stamps in the outer
file system.
This commit is contained in:
Jean-Pierre André 2011-10-07 11:16:23 +02:00
parent 8a762bee41
commit a7c61d83a7
5 changed files with 39 additions and 6 deletions

View File

@ -179,7 +179,8 @@ struct open_file {
enum {
CLOSE_GHOST = 1,
CLOSE_COMPRESSED = 2,
CLOSE_ENCRYPTED = 4
CLOSE_ENCRYPTED = 4,
CLOSE_DMTIME = 8
};
static struct ntfs_options opts;
@ -1219,6 +1220,9 @@ static void ntfs_fuse_open(fuse_req_t req, fuse_ino_t ino,
&& (ni->flags & FILE_ATTR_ENCRYPTED))
state |= CLOSE_ENCRYPTED;
#endif /* HAVE_SETXATTR */
/* mark a future need to update the mtime */
if (ctx->dmtime)
state |= CLOSE_DMTIME;
/* deny opening metadata files for writing */
if (ino < FILE_first_user)
res = -EPERM;
@ -1355,7 +1359,7 @@ static void ntfs_fuse_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
total += ret;
}
res = total;
if (res > 0)
if ((res > 0) && !ctx->dmtime)
ntfs_fuse_update_times(na->ni, NTFS_UPDATE_MCTIME);
exit:
if (na)
@ -1911,6 +1915,8 @@ static int ntfs_fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name,
&& (ni->flags & FILE_ATTR_ENCRYPTED))
state |= CLOSE_ENCRYPTED;
#endif /* HAVE_SETXATTR */
if (fi && ctx->dmtime)
state |= CLOSE_DMTIME;
ntfs_inode_update_mbsname(dir_ni, name, ni->mft_no);
NInoSetDirty(ni);
e->ino = ni->mft_no;
@ -2381,7 +2387,9 @@ static void ntfs_fuse_release(fuse_req_t req, fuse_ino_t ino,
of = (struct open_file*)(long)fi->fh;
/* Only for marked descriptors there is something to do */
if (!of || !(of->state & (CLOSE_COMPRESSED | CLOSE_ENCRYPTED))) {
if (!of
|| !(of->state & (CLOSE_COMPRESSED
| CLOSE_ENCRYPTED | CLOSE_DMTIME))) {
res = 0;
goto out;
}
@ -2396,6 +2404,8 @@ static void ntfs_fuse_release(fuse_req_t req, fuse_ino_t ino,
goto exit;
}
res = 0;
if (of->state & CLOSE_DMTIME)
ntfs_inode_update_times(ni,NTFS_UPDATE_MCTIME);
if (of->state & CLOSE_COMPRESSED)
res = ntfs_attr_pclose(na);
#ifdef HAVE_SETXATTR /* extended attributes interface required */

View File

@ -199,6 +199,12 @@ this option doesn't break applications that need to know
if a file has been read since the last time it was modified.
This is the default behaviour.
.TP
.B delay_mtime
Delay the updating of file modification time and file change time until
the file is closed. This is mainly useful for files which are written
to without changing their size, such as databases or file system images
mounted as loop.
.TP
.B show_sys_files
Show the metafiles in directory listings. Otherwise the default behaviour is
to hide the metafiles, which are special files used to store the NTFS

View File

@ -140,7 +140,8 @@ typedef struct {
enum {
CLOSE_COMPRESSED = 1,
CLOSE_ENCRYPTED = 2
CLOSE_ENCRYPTED = 2,
CLOSE_DMTIME = 4
};
static struct ntfs_options opts;
@ -1167,6 +1168,9 @@ static int ntfs_fuse_open(const char *org_path,
&& (ni->flags & FILE_ATTR_ENCRYPTED))
fi->fh |= CLOSE_ENCRYPTED;
#endif /* HAVE_SETXATTR */
/* mark a future need to update the mtime */
if (ctx->dmtime)
fi->fh |= CLOSE_DMTIME;
/* deny opening metadata files for writing */
if (ni->mft_no < FILE_first_user)
res = -EPERM;
@ -1289,7 +1293,7 @@ static int ntfs_fuse_write(const char *org_path, const char *buf, size_t size,
total += ret;
}
res = total;
if (res > 0)
if ((res > 0) && !ctx->dmtime)
ntfs_fuse_update_times(na->ni, NTFS_UPDATE_MCTIME);
exit:
if (na)
@ -1315,7 +1319,7 @@ static int ntfs_fuse_release(const char *org_path,
int stream_name_len, res;
/* Only for marked descriptors there is something to do */
if (!(fi->fh & (CLOSE_COMPRESSED | CLOSE_ENCRYPTED))) {
if (!(fi->fh & (CLOSE_COMPRESSED | CLOSE_ENCRYPTED | CLOSE_DMTIME))) {
res = 0;
goto out;
}
@ -1335,6 +1339,8 @@ static int ntfs_fuse_release(const char *org_path,
goto exit;
}
res = 0;
if (fi->fh & CLOSE_DMTIME)
ntfs_inode_update_times(na->ni,NTFS_UPDATE_MCTIME);
if (fi->fh & CLOSE_COMPRESSED)
res = ntfs_attr_pclose(na);
#ifdef HAVE_SETXATTR /* extended attributes interface required */
@ -1712,6 +1718,9 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev,
&& (ni->flags & FILE_ATTR_ENCRYPTED))
fi->fh |= CLOSE_ENCRYPTED;
#endif /* HAVE_SETXATTR */
/* mark a need to update the mtime */
if (fi && ctx->dmtime)
fi->fh |= CLOSE_DMTIME;
NInoSetDirty(ni);
/*
* closing ni requires access to dir_ni to
@ -1781,6 +1790,8 @@ static int ntfs_fuse_create_stream(const char *path,
&& (ni->flags & FILE_ATTR_ENCRYPTED))
fi->fh |= CLOSE_ENCRYPTED;
#endif /* HAVE_SETXATTR */
if (ctx->dmtime)
fi->fh |= CLOSE_DMTIME;
}
if (ntfs_inode_close(ni))

View File

@ -76,6 +76,7 @@ const struct DEFOPTION optionlist[] = {
{ "noatime", OPT_NOATIME, FLGOPT_BOGUS },
{ "atime", OPT_ATIME, FLGOPT_BOGUS },
{ "relatime", OPT_RELATIME, FLGOPT_BOGUS },
{ "delay_mtime", OPT_DMTIME, FLGOPT_BOGUS },
{ "fake_rw", OPT_FAKE_RW, FLGOPT_BOGUS },
{ "fsname", OPT_FSNAME, FLGOPT_NOSUPPORT },
{ "no_def_opts", OPT_NO_DEF_OPTS, FLGOPT_BOGUS },
@ -238,6 +239,9 @@ char *parse_mount_options(ntfs_fuse_context_t *ctx,
case OPT_RELATIME :
ctx->atime = ATIME_RELATIVE;
break;
case OPT_DMTIME :
ctx->dmtime = TRUE;
break;
case OPT_NO_DEF_OPTS :
no_def_opts = TRUE; /* Don't add default options. */
ctx->silent = FALSE; /* cancel default silent */

View File

@ -50,6 +50,7 @@ enum {
OPT_NOATIME,
OPT_ATIME,
OPT_RELATIME,
OPT_DMTIME,
OPT_FAKE_RW,
OPT_FSNAME,
OPT_NO_DEF_OPTS,
@ -116,6 +117,7 @@ typedef struct {
unsigned int dmask;
ntfs_fuse_streams_interface streams;
ntfs_atime_t atime;
BOOL dmtime;
BOOL ro;
BOOL show_sys_files;
BOOL hide_hid_files;