--- util-linux-2.13-pre6/mount/nfs_mount4.h.fsc 2006-04-21 08:22:13.000000000 -0400 +++ util-linux-2.13-pre6/mount/nfs_mount4.h 2006-04-21 08:23:08.000000000 -0400 @@ -57,6 +57,7 @@ struct nfs_mount_data { #define NFS_MOUNT_NONLM 0x0200 /* 3 */ #define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */ #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */ +#define NFS_MOUNT_FSCACHE 0x4000 /* security pseudoflavors */ --- util-linux-2.13-pre6/mount/nfsmount.c.fsc 2006-04-21 08:22:13.000000000 -0400 +++ util-linux-2.13-pre6/mount/nfsmount.c 2006-04-21 08:27:54.000000000 -0400 @@ -50,6 +50,7 @@ #include #include #include +#include #include "sundries.h" #include "nfsmount.h" @@ -130,6 +131,15 @@ void rpc_strerror() fprintf(stderr, "System Error: %d (%s)\n", cf_errno, strerror(cf_errno)); } } +#ifndef KEY_SPEC_THREAD_KEYRING +#define KEY_SPEC_THREAD_KEYRING -1 +#endif +int nfs_add_key(char *des, char *payload, size_t plen) +{ + return syscall(__NR_add_key, "user", + des, payload, plen, KEY_SPEC_THREAD_KEYRING); +} +static char *fsctag = NULL; /* Define the order in which to probe for UDP/TCP services */ static const u_int * @@ -819,6 +829,15 @@ parse_options(char *old_opts, struct nfs goto bad_parameter; } strncpy(data->context, context, NFS_MAX_CONTEXT_LEN); + } else if (!strcmp(opt, "fsctag")) { + char *tmp = opteq + 1; + + if (strlen(tmp) > BUFSIZ) { + printf(_("fsctag parameter exceeds limit of %d\n"), + BUFSIZ); + goto bad_parameter; + } + fsctag = strdup(tmp); } else if (!sloppy) goto bad_parameter; sprintf(cbuf, "%s=%s,", opt, opteq+1); @@ -836,6 +855,10 @@ parse_options(char *old_opts, struct nfs data->flags &= ~NFS_MOUNT_SOFT; if (val) data->flags |= NFS_MOUNT_SOFT; + } else if (!strcmp(opt, "fsc")) { + data->flags &= ~NFS_MOUNT_FSCACHE; + if (val) + data->flags |= NFS_MOUNT_FSCACHE; } else if (!strcmp(opt, "hard")) { data->flags &= ~NFS_MOUNT_SOFT; if (!val) @@ -1283,6 +1306,14 @@ noauth_flavours: "excessively long option argument\n")); goto fail; } + if (data.flags & NFS_MOUNT_FSCACHE) { + char *tmp = fsctag ? fsctag : node; + + val = nfs_add_key("mount:nfs:fsctag", tmp, strlen(tmp)+1); + if (val < 0) + fprintf(stderr, "mount: Warning: Unable to set fsctag:" + "error: %d (%s)\n", errno, strerror(errno)); + } snprintf(cbuf, sizeof(cbuf)-1, "addr=%s", s); strcat(new_opts, cbuf); --- util-linux-2.13-pre6/mount/nfs4mount.c.fsc 2006-04-21 08:22:12.000000000 -0400 +++ util-linux-2.13-pre6/mount/nfs4mount.c 2006-04-21 08:23:45.000000000 -0400 @@ -77,7 +77,9 @@ char *GSSDLCK = DEFAULT_DIR "/rpcgssd"; #endif extern int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int); -extern void rpc_strerror(); +extern void rpc_strerror(void); +extern int nfs_add_key(char *des, char *payload, size_t plen); +static char *fsctag = NULL; struct { char *flavour; @@ -205,10 +207,10 @@ int nfs4mount(const char *spec, const ch char *hostname, *dirname, *old_opts; char new_opts[1024]; char *opt, *opteq; - char *s; + char *s, *tmp; int val; int bg, soft, intr; - int nocto, noac; + int nocto, noac, fscache; int retry; int retval; @@ -258,6 +260,7 @@ int nfs4mount(const char *spec, const ch intr = NFS4_MOUNT_INTR; nocto = 0; noac = 0; + fscache = 0; retry = 10000; /* 10000 minutes ~ 1 week */ /* @@ -314,6 +317,14 @@ int nfs4mount(const char *spec, const ch num_flavour = parse_sec(opteq+1, pseudoflavour); if (!num_flavour) goto fail; + } else if (!strcmp(opt, "fsctag")) { + tmp = opteq + 1; + if (strlen(tmp) > BUFSIZ) { + printf(_("fsctag parameter exceeds limit of %d\n"), + BUFSIZ); + goto fail; + } + fsctag = strdup(tmp); } else if (!strcmp(opt, "addr")) { /* ignore */; } else { @@ -337,6 +348,8 @@ int nfs4mount(const char *spec, const ch soft = !val; else if (!strcmp(opt, "intr")) intr = val; + else if (!strcmp(opt, "fsc")) + fscache = val; else if (!strcmp(opt, "cto")) nocto = !val; else if (!strcmp(opt, "ac")) @@ -354,7 +367,8 @@ int nfs4mount(const char *spec, const ch data.flags = (soft ? NFS4_MOUNT_SOFT : 0) | (intr ? NFS4_MOUNT_INTR : 0) | (nocto ? NFS4_MOUNT_NOCTO : 0) - | (noac ? NFS4_MOUNT_NOAC : 0); + | (noac ? NFS4_MOUNT_NOAC : 0) + | (fscache ? NFS4_MOUNT_FSCACHE : 0); /* * Give a warning if the rpc.idmapd daemon is not running @@ -420,6 +434,13 @@ int nfs4mount(const char *spec, const ch fprintf(stderr, "mount to NFS server '%s' failed.\n", data.hostname.data); goto fail; } + if (data.flags & NFS4_MOUNT_FSCACHE) { + tmp = fsctag ? fsctag : (char *)node; + val = nfs_add_key("mount:nfs4:fsctag", tmp, strlen(tmp)+1); + if (val < 0) + fprintf(stderr, "mount: Warning: Unable to set fsctag:" + "error: %d (%s)\n", errno, strerror(errno)); + } *mount_opts = (char *) &data; /* clean up */ --- util-linux-2.13-pre6/mount/nfs4_mount.h.fsc 2006-04-21 08:22:12.000000000 -0400 +++ util-linux-2.13-pre6/mount/nfs4_mount.h 2006-04-21 08:23:08.000000000 -0400 @@ -65,6 +65,7 @@ struct nfs4_mount_data { #define NFS4_MOUNT_NOCTO 0x0010 /* 1 */ #define NFS4_MOUNT_NOAC 0x0020 /* 1 */ #define NFS4_MOUNT_STRICTLOCK 0x1000 /* 1 */ +#define NFS4_MOUNT_FSCACHE 0x2000 /* 1 */ #define NFS4_MOUNT_FLAGMASK 0xFFFF /* pseudoflavors: */ --- util-linux-2.13-pre6/mount/nfs.5.fsc 2006-04-21 08:22:14.000000000 -0400 +++ util-linux-2.13-pre6/mount/nfs.5 2006-04-21 08:26:00.000000000 -0400 @@ -267,6 +267,10 @@ default UDP protocol. Many NFS servers .I udp Mount the NFS filesystem using the UDP protocol. This is the default. +.TP 1.5i +.I fsc +Unable the use of persistent caching to the local disk using +the FS-Cache facility for the given mount point. .P All of the non-value options have corresponding nooption forms. For example, nointr means don't allow file operations to be @@ -421,6 +425,10 @@ This extracts a server performance penalty but it allows two different NFS clients to get reasonable good results when both clients are actively writing to common filesystem on the server. +.TP 1.5i +.I fsc +Unable the use of persistent caching to the local disk using +the FS-Cache facility for the given mount point. .P All of the non-value options have corresponding nooption forms. For example, nointr means don't allow file operations to be