nfs quota support

nadav danieli nadavd at exanet.com
Wed Dec 3 21:22:27 GMT 2003


I did not have the time to test it in version 3 but it compiles and link.
Also, -lrpcsvc must be added to LIBS in the Makefile


--- samba-3.0.0/source/smbd/quotas.c	2003-06-07 20:57:39.000000000 +0300
+++ samba-3.0.0nfsquota/source/smbd/quotas.c	2003-12-02 18:08:49.000000000 +0200
@@ -89,6 +89,108 @@
 } LINUX_SMB_DISK_QUOTA;
 
 /****************************************************************************
+ Allows querying of remote hosts for quotas on NFS mounted shares.
+ Supports normal NFS and AMD mounts.
+****************************************************************************/
+
+#include <rpc/rpc.h>
+#include <rpc/types.h>
+#include <rpcsvc/rquota.h>
+#include <unistd.h>
+
+static int get_smb_linux_nfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
+{
+	uid_t uid = euser_id;
+	char *mnttype = path;
+	CLIENT *clnt;
+	struct getquota_rslt gqr;
+	struct getquota_args args;
+	char *host, *testpath;
+	int len;
+	static struct timeval timeout = {2,0};
+	enum clnt_stat clnt_stat;
+	fstring cutstr, machname;
+	int ret = -1;
+
+	len=strcspn(mnttype, ":");
+	host = strncpy(cutstr,mnttype, len);
+	cutstr[len] = '\0';
+	DEBUG(5,("nfs_quotas: looking for mount on \"%s\"\n", cutstr));
+	DEBUG(5,("nfs_quotas: of path \"%s\"\n", mnttype));
+	testpath=strchr_m(mnttype, ':');
+	args.gqa_pathp = testpath+1;
+	args.gqa_uid = uid;
+
+	DEBUG(5,("nfs_quotas: Asking for host \"%s\" rpcprog \"%i\" rpcvers \"%i\""
+			 " network \"udp\" path \"%s\" user %u\n",
+			 host, RQUOTAPROG, RQUOTAVERS, args.gqa_pathp, uid));
+
+	if ((clnt = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp")) == NULL) {
+		goto out;
+	}
+	clnt->cl_auth = NULL;
+	if (gethostname(machname, sizeof(machname)) == 0) {
+		struct passwd *pw = getpwuid(uid);
+		if (pw) {
+			clnt->cl_auth = authunix_create(machname, uid, pw->pw_gid, 0, NULL);
+			if (clnt->cl_auth)
+				DEBUG(9,("nfs_quotas: created auth for uid %u gid %u\n",
+						 uid, pw->pw_gid));
+		}
+	}
+	if (!clnt->cl_auth)
+		clnt->cl_auth = authunix_create_default();
+	DEBUG(9,("nfs_quotas: auth_success\n"));
+
+	clnt_stat=clnt_call(clnt, RQUOTAPROC_GETQUOTA, (xdrproc_t) xdr_getquota_args, (caddr_t)&args,
+						(xdrproc_t) xdr_getquota_rslt, (caddr_t)&gqr, timeout);
+
+	if (clnt_stat != RPC_SUCCESS) {
+		DEBUG(9,("nfs_quotas: clnt_call fail\n"));
+		goto out;
+	}
+
+	/* 
+	 * quotastat returns 0 if the rpc call fails, 1 if quotas exist, 2 if there is
+	 * no quota set, and 3 if no permission to get the quota.  If 0 or 3 return
+	 * something sensible.
+	 */   
+
+	switch ( gqr.status ) {
+	case Q_OK:
+		DEBUG(9,("nfs_quotas: Good quota data\n"));
+		dp->softlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit;
+		dp->hardlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit;
+		dp->curblocks = gqr.getquota_rslt_u.gqr_rquota.rq_curblocks;
+		dp->bsize = gqr.getquota_rslt_u.gqr_rquota.rq_bsize;
+		ret = 0;
+		break;
+
+	default:
+		DEBUG(9,("nfs_quotas: Remote Quotas Questionable!  Error \"%i\" \n", gqr.status ));
+		break;
+	}
+
+	DEBUG(10,("nfs_quotas: Let`s look at D a bit closer... status \"%i\" bsize \"%i\" active? \"%i\" bhard \"%i\" bsoft \"%i\" curb \"%i\" \n",
+			gqr.status,
+			gqr.getquota_rslt_u.gqr_rquota.rq_bsize,
+			gqr.getquota_rslt_u.gqr_rquota.rq_active,
+			gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit,
+			gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit,
+			gqr.getquota_rslt_u.gqr_rquota.rq_curblocks));
+  out:
+
+	if (clnt) {
+		if (clnt->cl_auth)
+			auth_destroy(clnt->cl_auth);
+		clnt_destroy(clnt);
+	}
+
+	DEBUG(10,("nfs_quotas: End of nfs_quotas\n" ));
+	return ret;
+}
+
+/****************************************************************************
  Abstract out the XFS Quota Manager quota get call.
 ****************************************************************************/
 
@@ -197,6 +299,9 @@
 	set_effective_uid(0);  
 	if (strcmp(mnt->mnt_type, "xfs") == 0)
 		r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D);
+	else if (strcmp(mnt->mnt_type, "nfs") == 0) {
+		r=get_smb_linux_nfs_quota(mnt->mnt_fsname, euser_id, &D);
+	}
 	else
 		r=get_smb_linux_vfs_quota(mnt->mnt_fsname, euser_id, &D);
 	restore_re_uid();


-----Original Message-----
Subject: Re: nfs quota support


On Mon, Dec 01, 2003 at 07:04:53PM +0200, Nadav Danieli wrote:
> Hello everyone,
> 
> I was quite surprised to find that linux disk_quotas does not handle nfs
> mounts. In fact I was even more surprised to find that quotactl did not.
> Is there a way to make quotactl handle nfs mounts? Or maybe I'm too
> naive.
> Anyway, since we need it I wrote it. The code is based on nfs_quotas of
> the SUNOS5, and is depend on rpcsvc lib.
> The changes made on version 2.x but from what I saw, this code did not
> change much since.
> 

Can you please update this code for 3.0 and post it in the form of 
a diff -u (unified diff format). Otherwise it's difficult to work
out what you changed and why.

Thanks,

	Jeremy.


More information about the samba-technical mailing list