diff options
author | jkar8572 <jkar8572> | 2007-08-23 18:55:27 +0000 |
---|---|---|
committer | jkar8572 <jkar8572> | 2007-08-23 18:55:27 +0000 |
commit | 690f9c08922da8d625732259c5db5f67a17ed4e0 (patch) | |
tree | 71557de433450887299a18a344280547577b6749 | |
parent | 8719bd099ddcab78a31aab6cc72cc37e4b783af1 (diff) |
Made possible to use quota rpc in mixed NFSv3 and NFSv4 environments -
quota(1) and similar tools now use paths without leading / for NFSv4
mounts (Jan Kara)
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | quotaio.c | 1 | ||||
-rw-r--r-- | quotaio.h | 3 | ||||
-rw-r--r-- | rquota_client.c | 14 | ||||
-rw-r--r-- | rquota_server.c | 16 |
5 files changed, 29 insertions, 6 deletions
@@ -1,4 +1,5 @@ Changes in quota-tools from 3.15 to 3.16 +* made possible to use quota rpc in mixed NFSv3 and NFSv4 environments (Jan Kara) * fixed compilation with openLDAP library versions 2.1 and 2.2 (Jan Kara) * always define allow_severity and deny_severity for older versions of libwrap (Martin Jacobs) * cleaned up host_access() handling (Jan Kara) @@ -54,6 +54,7 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt, int flags) h->qh_type = type; sstrncpy(h->qh_quotadev, mnt_fsname, sizeof(h->qh_quotadev)); free((char *)mnt_fsname); + sstrncpy(h->qh_fstype, mnt->mnt_type, MAX_FSTYPE_LEN); if (nfs_fstype(mnt->mnt_type)) { /* NFS filesystem? */ if (fmt != -1 && fmt != QF_RPC) { /* User wanted some other format? */ errstr(_("Only RPC quota format is allowed on NFS filesystem.\n")); @@ -40,6 +40,8 @@ "xfs"\ } +#define MAX_FSTYPE_LEN 16 /* Maximum length of filesystem type name */ + /* Values for format handling */ #define QF_UNKNOWN -3 /* Format cannot be detected from filename */ #define QF_TOONEW -2 /* Quota format is too new to handle */ @@ -82,6 +84,7 @@ struct quota_handle { int qh_fd; /* Handle of file (-1 when IOFL_QUOTAON) */ int qh_io_flags; /* IO flags for file */ char qh_quotadev[PATH_MAX]; /* Device file is for */ + char qh_fstype[MAX_FSTYPE_LEN]; /* Type of the filesystem on qh_quotadev */ int qh_type; /* Type of quotafile */ int qh_fmt; /* Quotafile format */ struct stat qh_stat; /* stat(2) for qh_quotadev */ diff --git a/rquota_client.c b/rquota_client.c index 4620a1f..f6926f2 100644 --- a/rquota_client.c +++ b/rquota_client.c @@ -9,7 +9,7 @@ * * This part does the rpc-communication with the rquotad. * - * Version: $Id: rquota_client.c,v 1.9 2005/03/31 11:48:02 jkar8572 Exp $ + * Version: $Id: rquota_client.c,v 1.10 2007/08/23 18:55:28 jkar8572 Exp $ * * Author: Marco van Wieringen <mvw@planets.elm.net> * @@ -155,6 +155,12 @@ int rpc_rquota_get(struct dquot *dquot) } *pathname++ = '\0'; + /* For NFSv4, we send the filesystem path without initial /. Server prepends proper + * NFS pseudoroot automatically and uses this for detection of NFSv4 mounts. */ + if (!strcmp(dquot->dq_h->qh_fstype, MNTTYPE_NFS4)) { + while (*pathname == '/') + pathname++; + } /* * First try EXT_RQUOTAPROG (Extended (LINUX) RPC quota program) @@ -265,6 +271,12 @@ int rpc_rquota_set(int qcmd, struct dquot *dquot) return -ENOENT; *pathname++ = '\0'; + /* For NFSv4, we send the filesystem path without initial /. Server prepends proper + * NFS pseudoroot automatically and uses this for detection of NFSv4 mounts. */ + if (!strcmp(dquot->dq_h->qh_fstype, MNTTYPE_NFS4)) { + while (*pathname == '/') + pathname++; + } /* * First try EXT_RQUOTAPROG (Extended (LINUX) RPC quota program) diff --git a/rquota_server.c b/rquota_server.c index 863edbb..e734ef5 100644 --- a/rquota_server.c +++ b/rquota_server.c @@ -9,7 +9,7 @@ * * This part does the lookup of the info. * - * Version: $Id: rquota_server.c,v 1.16 2005/06/01 07:20:50 jkar8572 Exp $ + * Version: $Id: rquota_server.c,v 1.17 2007/08/23 18:55:28 jkar8572 Exp $ * * Author: Marco van Wieringen <mvw@planets.elm.net> * @@ -123,12 +123,11 @@ setquota_rslt *setquotainfo(int lflags, caddr_t * argp, struct svc_req *rqstp) struct util_dqblk dqblk; struct dquot *dquot; struct mntent *mnt; - char pathname[PATH_MAX]; + char pathname[PATH_MAX] = {0}; char *pathp = pathname; int id, qcmd, type; struct quota_handle *handles[2] = { NULL, NULL }; - sstrncpy(pathname, nfs_pseudoroot, PATH_MAX); /* * First check authentication. */ @@ -143,6 +142,8 @@ setquota_rslt *setquotainfo(int lflags, caddr_t * argp, struct svc_req *rqstp) qcmd = arguments.ext_args->sqa_qcmd; type = arguments.ext_args->sqa_type; + if (arguments.ext_args->sqa_pathp[0] != '/') + sstrncpy(pathname, nfs_pseudoroot, PATH_MAX); sstrncat(pathname, arguments.ext_args->sqa_pathp, PATH_MAX); servnet2utildqblk(&dqblk, &arguments.ext_args->sqa_dqblk); } @@ -157,6 +158,8 @@ setquota_rslt *setquotainfo(int lflags, caddr_t * argp, struct svc_req *rqstp) qcmd = arguments.args->sqa_qcmd; type = USRQUOTA; + if (arguments.args->sqa_pathp[0] != '/') + sstrncpy(pathname, nfs_pseudoroot, PATH_MAX); sstrncat(pathname, arguments.args->sqa_pathp, PATH_MAX); servnet2utildqblk(&dqblk, &arguments.args->sqa_dqblk); } @@ -212,12 +215,11 @@ getquota_rslt *getquotainfo(int lflags, caddr_t * argp, struct svc_req * rqstp) } arguments; struct dquot *dquot = NULL; struct mntent *mnt; - char pathname[PATH_MAX]; + char pathname[PATH_MAX] = {0}; char *pathp = pathname; int id, type; struct quota_handle *handles[2] = { NULL, NULL }; - sstrncpy(pathname, nfs_pseudoroot, PATH_MAX); /* * First check authentication. */ @@ -225,6 +227,8 @@ getquota_rslt *getquotainfo(int lflags, caddr_t * argp, struct svc_req * rqstp) arguments.ext_args = (ext_getquota_args *) argp; id = arguments.ext_args->gqa_id; type = arguments.ext_args->gqa_type; + if (arguments.ext_args->gqa_pathp[0] != '/') + sstrncpy(pathname, nfs_pseudoroot, PATH_MAX); sstrncat(pathname, arguments.ext_args->gqa_pathp, PATH_MAX); if (type == USRQUOTA && unix_cred->aup_uid && unix_cred->aup_uid != id) { @@ -242,6 +246,8 @@ getquota_rslt *getquotainfo(int lflags, caddr_t * argp, struct svc_req * rqstp) arguments.args = (getquota_args *) argp; id = arguments.args->gqa_uid; type = USRQUOTA; + if (arguments.ext_args->gqa_pathp[0] != '/') + sstrncpy(pathname, nfs_pseudoroot, PATH_MAX); sstrncat(pathname, arguments.args->gqa_pathp, PATH_MAX); if (unix_cred->aup_uid && unix_cred->aup_uid != id) { |