From 458c5eb191d80591b0acd893f092043cb0590fc2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Pierre=20Andr=C3=A9?= Date: Mon, 23 Jan 2012 17:49:38 +0100 Subject: [PATCH] Worked around write checks for ftruncate() and access(W_OK) on OpenIndiana When a file is created with no write permissions, ftruncate and access(W_OK) should be allowed, but this check has to be made by the file system on OpenIndiana. This patch is not active on Linux (#ifdef'ed) --- src/lowntfs-3g.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c index 8c89489e..8898ea4b 100644 --- a/src/lowntfs-3g.c +++ b/src/lowntfs-3g.c @@ -174,13 +174,21 @@ struct open_file { fuse_ino_t ino; fuse_ino_t parent; int state; +#if defined(__sun) && defined (__SVR4) + pid_t tid; +#endif /* defined(__sun) && defined (__SVR4) */ } ; enum { CLOSE_GHOST = 1, CLOSE_COMPRESSED = 2, CLOSE_ENCRYPTED = 4, +#if defined(__sun) && defined (__SVR4) + CLOSE_DMTIME = 8, + CLOSE_WRITING = 16 +#else /* defined(__sun) && defined (__SVR4) */ CLOSE_DMTIME = 8 +#endif /* defined(__sun) && defined (__SVR4) */ }; static struct ntfs_options opts; @@ -1178,6 +1186,31 @@ static void ntfs_fuse_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, fuse_reply_err(req, -err); } +#if defined(__sun) && defined (__SVR4) + +/* + * When a file is created with a read-only mode, + * access for writing and ftruncating are allowed to the thread + * which is creating. + */ + +static BOOL check_open_for_writing(fuse_ino_t ino, pid_t tid) +{ + BOOL ok; + struct open_file *of; + + ok = FALSE; + of = ctx->open_files; + while (of && (of->ino != ino)) + of = of->next; + if (of && (of->state & CLOSE_WRITING) && (of->tid == tid)) { + ok = TRUE; + } + return (ok); +} + +#endif /* defined(__sun) && defined (__SVR4) */ + static void ntfs_fuse_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { @@ -1213,6 +1246,9 @@ static void ntfs_fuse_open(fuse_req_t req, fuse_ino_t ino, #endif if ((res >= 0) && (fi->flags & (O_WRONLY | O_RDWR))) { +#if defined(__sun) && defined (__SVR4) + state |= CLOSE_WRITING; +#endif /* defined(__sun) && defined (__SVR4) */ /* mark a future need to compress the last chunk */ if (na->data_flags & ATTR_COMPRESSION_MASK) state |= CLOSE_COMPRESSED; @@ -1244,6 +1280,13 @@ static void ntfs_fuse_open(fuse_req_t req, fuse_ino_t ino, of->parent = 0; of->ino = ino; of->state = state; +#if defined(__sun) && defined (__SVR4) +#if !KERNELPERMS | (POSIXACLS & !KERNELACLS) + of->tid = security.tid; +#else + of->tid = fuse_req_ctx(req)->pid; +#endif +#endif /* defined(__sun) && defined (__SVR4) */ of->next = ctx->open_files; of->previous = (struct open_file*)NULL; if (ctx->open_files) @@ -1743,8 +1786,14 @@ static void ntfs_fuse_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, } /* size */ if (!res && (to_set & FUSE_SET_ATTR_SIZE)) { +#if defined(__sun) && defined (__SVR4) + res = ntfs_fuse_trunc(&security, ino, attr->st_size, + !fi && !check_open_for_writing(ino, + security.tid), &stbuf); +#else res = ntfs_fuse_trunc(&security, ino, attr->st_size, !fi, &stbuf); +#endif /* defined(__sun) && defined (__SVR4) */ } /* some set of atime/mtime */ if (!res && (to_set & (FUSE_SET_ATTR_ATIME + FUSE_SET_ATTR_MTIME))) { @@ -1776,6 +1825,13 @@ static void ntfs_fuse_access(fuse_req_t req, fuse_ino_t ino, int mask) else res = -EOPNOTSUPP; } else { +#if defined(__sun) && defined (__SVR4) + if ((mask & W_OK) && check_open_for_writing(ino, + security.tid)) { + fuse_reply_err(req, 0); + return; + } +#endif /* defined(__sun) && defined (__SVR4) */ ni = ntfs_inode_open(ctx->vol, INODE(ino)); if (!ni) { res = -errno; @@ -1952,7 +2008,12 @@ exit: if (of) { of->parent = 0; of->ino = e->ino; +#if defined(__sun) && defined (__SVR4) + of->state = state | CLOSE_WRITING; + of->tid = security.tid; +#else /* defined(__sun) && defined (__SVR4) */ of->state = state; +#endif /* defined(__sun) && defined (__SVR4) */ of->next = ctx->open_files; of->previous = (struct open_file*)NULL; if (ctx->open_files) -- 2.11.0