Enabled Posix ACLs with older kernels

N2009_11_14_FIXES
jpandre 2009-09-18 19:40:59 +00:00
parent 12437acea9
commit b46c8daad5
2 changed files with 53 additions and 3 deletions

View File

@ -51,6 +51,7 @@
/** Minor version number of this interface */
#ifdef POSIXACLS
#define FUSE_KERNEL_MINOR_VERSION 12
#define FUSE_KERNEL_MINOR_FALLBACK 8
#else
#define FUSE_KERNEL_MINOR_VERSION 8
#endif
@ -83,7 +84,7 @@ struct fuse_attr {
__u32 gid;
__u32 rdev;
#ifdef POSIXACLS
__u64 filling; /* JPA needed, but do not know how to fill */
__u64 filling; /* JPA needed for minor >= 12, but meaning unknown */
#endif
};
@ -181,6 +182,7 @@ enum fuse_opcode {
/* The read buffer is required to be at least 8k, but may be much larger */
#define FUSE_MIN_READ_BUFFER 8192
#define FUSE_COMPAT_ENTRY_OUT_SIZE 120 /* JPA */
struct fuse_entry_out {
__u64 nodeid; /* Inode ID */
@ -197,6 +199,8 @@ struct fuse_forget_in {
__u64 nlookup;
};
#define FUSE_COMPAT_FUSE_ATTR_OUT_SIZE 96 /* JPA */
struct fuse_attr_out {
__u64 attr_valid; /* Cache timeout for the attributes */
__u32 attr_valid_nsec;

View File

@ -331,7 +331,12 @@ int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
memset(&arg, 0, sizeof(arg));
fill_entry(&arg, e);
#ifdef POSIXACLS
return send_reply_ok(req, &arg, (req->f->conn.proto_minor >= 12
? sizeof(arg) : FUSE_COMPAT_ENTRY_OUT_SIZE));
#else
return send_reply_ok(req, &arg, sizeof(arg));
#endif
}
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
@ -344,8 +349,20 @@ int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
memset(&arg, 0, sizeof(arg));
fill_entry(&arg.e, e);
#ifdef POSIXACLS
if (req->f->conn.proto_minor < 12) {
fill_open((struct fuse_open_out*)
((char*)&arg + FUSE_COMPAT_ENTRY_OUT_SIZE), f);
return send_reply_ok(req, &arg,
FUSE_COMPAT_ENTRY_OUT_SIZE + sizeof(struct fuse_open_out));
} else {
fill_open(&arg.o, f);
return send_reply_ok(req, &arg, sizeof(arg));
}
#else
fill_open(&arg.o, f);
return send_reply_ok(req, &arg, sizeof(arg));
#endif
}
int fuse_reply_attr(fuse_req_t req, const struct stat *attr,
@ -358,7 +375,12 @@ int fuse_reply_attr(fuse_req_t req, const struct stat *attr,
arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout);
convert_stat(attr, &arg.attr);
#ifdef POSIXACLS
return send_reply_ok(req, &arg, (req->f->conn.proto_minor >= 12
? sizeof(arg) : FUSE_COMPAT_FUSE_ATTR_OUT_SIZE));
#else
return send_reply_ok(req, &arg, sizeof(arg));
#endif
}
int fuse_reply_readlink(fuse_req_t req, const char *linkname)
@ -657,9 +679,19 @@ static void do_write(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
fi.fh_old = fi.fh;
fi.writepage = arg->write_flags & 1;
if (req->f->op.write)
if (req->f->op.write) {
#ifdef POSIXACLS
const char *buf;
if (req->f->conn.proto_minor >= 12)
buf = PARAM(arg);
else
buf = ((const char*)arg) + FUSE_COMPAT_WRITE_IN_SIZE;
req->f->op.write(req, nodeid, buf, arg->size, arg->offset, &fi);
#else
req->f->op.write(req, nodeid, PARAM(arg), arg->size, arg->offset, &fi);
else
#endif
} else
fuse_reply_err(req, ENOSYS);
}
@ -1032,7 +1064,21 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
memset(&outarg, 0, sizeof(outarg));
outarg.major = FUSE_KERNEL_VERSION;
/*
* if POSIXACLS is not set, protocol 7.8 provides a good
* compatibility with older kernel modules.
* if POSIXACLS is set, we try to use protocol 7.12 supposed
* to have the ability to process the umask conditionnally,
* but, when using an older kernel module, we fallback to 7.8
*/
#ifdef POSIXACLS
if (arg->major > 7 || (arg->major == 7 && arg->minor >= 12))
outarg.minor = FUSE_KERNEL_MINOR_VERSION;
else
outarg.minor = FUSE_KERNEL_MINOR_FALLBACK;
#else
outarg.minor = FUSE_KERNEL_MINOR_VERSION;
#endif
if (f->conn.async_read)
outarg.flags |= FUSE_ASYNC_READ;
if (f->op.getlk && f->op.setlk)