Commit dc87c551 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-2.6.39' of git://linux-nfs.org/~bfields/linux

* 'for-2.6.39' of git://linux-nfs.org/~bfields/linux:
  SUNRPC: Remove resource leak in svc_rdma_send_error()
  nfsd: wrong index used in inner loop
  nfsd4: fix comment and remove unused nfsd4_file fields
  nfs41: make sure nfs server return right ca_maxresponsesize_cached
  nfsd: fix compile error
  svcrpc: fix bad argument in unix_domain_find
  nfsd4: fix struct file leak
  nfsd4: minor nfs4state.c reshuffling
  svcrpc: fix rare race on unix_domain creation
  nfsd41: modify the members value of nfsd4_op_flags
  nfsd: add proc file listing kernel's gss_krb5 enctypes
  gss:krb5 only include enctype numbers in gm_upcall_enctypes
  NFSD, VFS: Remove dead code in nfsd_rename()
  nfsd: kill unused macro definition
  locks: use assign_type()
parents 5818fcc8 4be34b9d
...@@ -414,17 +414,7 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, ...@@ -414,17 +414,7 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
fl->fl_ops = NULL; fl->fl_ops = NULL;
fl->fl_lmops = NULL; fl->fl_lmops = NULL;
switch (l->l_type) { return assign_type(fl, l->l_type);
case F_RDLCK:
case F_WRLCK:
case F_UNLCK:
fl->fl_type = l->l_type;
break;
default:
return -EINVAL;
}
return (0);
} }
#endif #endif
......
...@@ -299,7 +299,6 @@ svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old) ...@@ -299,7 +299,6 @@ svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old)
#define EXPORT_HASHBITS 8 #define EXPORT_HASHBITS 8
#define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS)
#define EXPORT_HASHMASK (EXPORT_HASHMAX -1)
static struct cache_head *export_table[EXPORT_HASHMAX]; static struct cache_head *export_table[EXPORT_HASHMAX];
......
...@@ -63,7 +63,6 @@ struct ent { ...@@ -63,7 +63,6 @@ struct ent {
#define ENT_HASHBITS 8 #define ENT_HASHBITS 8
#define ENT_HASHMAX (1 << ENT_HASHBITS) #define ENT_HASHMAX (1 << ENT_HASHBITS)
#define ENT_HASHMASK (ENT_HASHMAX - 1)
static void static void
ent_init(struct cache_head *cnew, struct cache_head *citm) ent_init(struct cache_head *cnew, struct cache_head *citm)
......
...@@ -984,8 +984,8 @@ typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, ...@@ -984,8 +984,8 @@ typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
void *); void *);
enum nfsd4_op_flags { enum nfsd4_op_flags {
ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */
ALLOWED_ON_ABSENT_FS = 2 << 0, /* ops processed on absent fs */ ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */
ALLOWED_AS_FIRST_OP = 3 << 0, /* ops reqired first in compound */ ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */
}; };
struct nfsd4_operation { struct nfsd4_operation {
......
...@@ -148,7 +148,7 @@ static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE]; ...@@ -148,7 +148,7 @@ static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
/* hash table for nfs4_file */ /* hash table for nfs4_file */
#define FILE_HASH_BITS 8 #define FILE_HASH_BITS 8
#define FILE_HASH_SIZE (1 << FILE_HASH_BITS) #define FILE_HASH_SIZE (1 << FILE_HASH_BITS)
#define FILE_HASH_MASK (FILE_HASH_SIZE - 1)
/* hash table for (open)nfs4_stateid */ /* hash table for (open)nfs4_stateid */
#define STATEID_HASH_BITS 10 #define STATEID_HASH_BITS 10
#define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS) #define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS)
...@@ -316,64 +316,6 @@ static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; ...@@ -316,64 +316,6 @@ static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
static struct list_head client_lru; static struct list_head client_lru;
static struct list_head close_lru; static struct list_head close_lru;
static void unhash_generic_stateid(struct nfs4_stateid *stp)
{
list_del(&stp->st_hash);
list_del(&stp->st_perfile);
list_del(&stp->st_perstateowner);
}
static void free_generic_stateid(struct nfs4_stateid *stp)
{
put_nfs4_file(stp->st_file);
kmem_cache_free(stateid_slab, stp);
}
static void release_lock_stateid(struct nfs4_stateid *stp)
{
struct file *file;
unhash_generic_stateid(stp);
file = find_any_file(stp->st_file);
if (file)
locks_remove_posix(file, (fl_owner_t)stp->st_stateowner);
free_generic_stateid(stp);
}
static void unhash_lockowner(struct nfs4_stateowner *sop)
{
struct nfs4_stateid *stp;
list_del(&sop->so_idhash);
list_del(&sop->so_strhash);
list_del(&sop->so_perstateid);
while (!list_empty(&sop->so_stateids)) {
stp = list_first_entry(&sop->so_stateids,
struct nfs4_stateid, st_perstateowner);
release_lock_stateid(stp);
}
}
static void release_lockowner(struct nfs4_stateowner *sop)
{
unhash_lockowner(sop);
nfs4_put_stateowner(sop);
}
static void
release_stateid_lockowners(struct nfs4_stateid *open_stp)
{
struct nfs4_stateowner *lock_sop;
while (!list_empty(&open_stp->st_lockowners)) {
lock_sop = list_entry(open_stp->st_lockowners.next,
struct nfs4_stateowner, so_perstateid);
/* list_del(&open_stp->st_lockowners); */
BUG_ON(lock_sop->so_is_open_owner);
release_lockowner(lock_sop);
}
}
/* /*
* We store the NONE, READ, WRITE, and BOTH bits separately in the * We store the NONE, READ, WRITE, and BOTH bits separately in the
* st_{access,deny}_bmap field of the stateid, in order to track not * st_{access,deny}_bmap field of the stateid, in order to track not
...@@ -446,13 +388,71 @@ static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp) ...@@ -446,13 +388,71 @@ static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp)
return nfs4_access_to_omode(access); return nfs4_access_to_omode(access);
} }
static void release_open_stateid(struct nfs4_stateid *stp) static void unhash_generic_stateid(struct nfs4_stateid *stp)
{
list_del(&stp->st_hash);
list_del(&stp->st_perfile);
list_del(&stp->st_perstateowner);
}
static void free_generic_stateid(struct nfs4_stateid *stp)
{ {
int oflag = nfs4_access_bmap_to_omode(stp); int oflag = nfs4_access_bmap_to_omode(stp);
nfs4_file_put_access(stp->st_file, oflag);
put_nfs4_file(stp->st_file);
kmem_cache_free(stateid_slab, stp);
}
static void release_lock_stateid(struct nfs4_stateid *stp)
{
struct file *file;
unhash_generic_stateid(stp);
file = find_any_file(stp->st_file);
if (file)
locks_remove_posix(file, (fl_owner_t)stp->st_stateowner);
free_generic_stateid(stp);
}
static void unhash_lockowner(struct nfs4_stateowner *sop)
{
struct nfs4_stateid *stp;
list_del(&sop->so_idhash);
list_del(&sop->so_strhash);
list_del(&sop->so_perstateid);
while (!list_empty(&sop->so_stateids)) {
stp = list_first_entry(&sop->so_stateids,
struct nfs4_stateid, st_perstateowner);
release_lock_stateid(stp);
}
}
static void release_lockowner(struct nfs4_stateowner *sop)
{
unhash_lockowner(sop);
nfs4_put_stateowner(sop);
}
static void
release_stateid_lockowners(struct nfs4_stateid *open_stp)
{
struct nfs4_stateowner *lock_sop;
while (!list_empty(&open_stp->st_lockowners)) {
lock_sop = list_entry(open_stp->st_lockowners.next,
struct nfs4_stateowner, so_perstateid);
/* list_del(&open_stp->st_lockowners); */
BUG_ON(lock_sop->so_is_open_owner);
release_lockowner(lock_sop);
}
}
static void release_open_stateid(struct nfs4_stateid *stp)
{
unhash_generic_stateid(stp); unhash_generic_stateid(stp);
release_stateid_lockowners(stp); release_stateid_lockowners(stp);
nfs4_file_put_access(stp->st_file, oflag);
free_generic_stateid(stp); free_generic_stateid(stp);
} }
...@@ -608,7 +608,8 @@ static void init_forechannel_attrs(struct nfsd4_channel_attrs *new, struct nfsd4 ...@@ -608,7 +608,8 @@ static void init_forechannel_attrs(struct nfsd4_channel_attrs *new, struct nfsd4
u32 maxrpc = nfsd_serv->sv_max_mesg; u32 maxrpc = nfsd_serv->sv_max_mesg;
new->maxreqs = numslots; new->maxreqs = numslots;
new->maxresp_cached = slotsize + NFSD_MIN_HDR_SEQ_SZ; new->maxresp_cached = min_t(u32, req->maxresp_cached,
slotsize + NFSD_MIN_HDR_SEQ_SZ);
new->maxreq_sz = min_t(u32, req->maxreq_sz, maxrpc); new->maxreq_sz = min_t(u32, req->maxreq_sz, maxrpc);
new->maxresp_sz = min_t(u32, req->maxresp_sz, maxrpc); new->maxresp_sz = min_t(u32, req->maxresp_sz, maxrpc);
new->maxops = min_t(u32, req->maxops, NFSD_MAX_OPS_PER_COMPOUND); new->maxops = min_t(u32, req->maxops, NFSD_MAX_OPS_PER_COMPOUND);
...@@ -3735,6 +3736,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc ...@@ -3735,6 +3736,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
stp->st_stateid.si_stateownerid = sop->so_id; stp->st_stateid.si_stateownerid = sop->so_id;
stp->st_stateid.si_fileid = fp->fi_id; stp->st_stateid.si_fileid = fp->fi_id;
stp->st_stateid.si_generation = 0; stp->st_stateid.si_generation = 0;
stp->st_access_bmap = 0;
stp->st_deny_bmap = open_stp->st_deny_bmap; stp->st_deny_bmap = open_stp->st_deny_bmap;
stp->st_openstp = open_stp; stp->st_openstp = open_stp;
...@@ -3749,6 +3751,17 @@ check_lock_length(u64 offset, u64 length) ...@@ -3749,6 +3751,17 @@ check_lock_length(u64 offset, u64 length)
LOFF_OVERFLOW(offset, length))); LOFF_OVERFLOW(offset, length)));
} }
static void get_lock_access(struct nfs4_stateid *lock_stp, u32 access)
{
struct nfs4_file *fp = lock_stp->st_file;
int oflag = nfs4_access_to_omode(access);
if (test_bit(access, &lock_stp->st_access_bmap))
return;
nfs4_file_get_access(fp, oflag);
__set_bit(access, &lock_stp->st_access_bmap);
}
/* /*
* LOCK operation * LOCK operation
*/ */
...@@ -3765,7 +3778,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -3765,7 +3778,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct file_lock conflock; struct file_lock conflock;
__be32 status = 0; __be32 status = 0;
unsigned int strhashval; unsigned int strhashval;
unsigned int cmd;
int err; int err;
dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
...@@ -3847,22 +3859,18 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -3847,22 +3859,18 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
switch (lock->lk_type) { switch (lock->lk_type) {
case NFS4_READ_LT: case NFS4_READ_LT:
case NFS4_READW_LT: case NFS4_READW_LT:
if (find_readable_file(lock_stp->st_file)) { filp = find_readable_file(lock_stp->st_file);
nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_READ); if (filp)
filp = find_readable_file(lock_stp->st_file); get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ);
}
file_lock.fl_type = F_RDLCK; file_lock.fl_type = F_RDLCK;
cmd = F_SETLK; break;
break;
case NFS4_WRITE_LT: case NFS4_WRITE_LT:
case NFS4_WRITEW_LT: case NFS4_WRITEW_LT:
if (find_writeable_file(lock_stp->st_file)) { filp = find_writeable_file(lock_stp->st_file);
nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_WRITE); if (filp)
filp = find_writeable_file(lock_stp->st_file); get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE);
}
file_lock.fl_type = F_WRLCK; file_lock.fl_type = F_WRLCK;
cmd = F_SETLK; break;
break;
default: default:
status = nfserr_inval; status = nfserr_inval;
goto out; goto out;
...@@ -3886,7 +3894,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -3886,7 +3894,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
* Note: locks.c uses the BKL to protect the inode's lock list. * Note: locks.c uses the BKL to protect the inode's lock list.
*/ */
err = vfs_lock_file(filp, cmd, &file_lock, &conflock); err = vfs_lock_file(filp, F_SETLK, &file_lock, &conflock);
switch (-err) { switch (-err) {
case 0: /* success! */ case 0: /* success! */
update_stateid(&lock_stp->st_stateid); update_stateid(&lock_stp->st_stateid);
......
...@@ -1142,7 +1142,7 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, ...@@ -1142,7 +1142,7 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
u32 dummy; u32 dummy;
char *machine_name; char *machine_name;
int i, j; int i;
int nr_secflavs; int nr_secflavs;
READ_BUF(16); READ_BUF(16);
...@@ -1215,8 +1215,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, ...@@ -1215,8 +1215,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
READ_BUF(4); READ_BUF(4);
READ32(dummy); READ32(dummy);
READ_BUF(dummy * 4); READ_BUF(dummy * 4);
for (j = 0; j < dummy; ++j)
READ32(dummy);
break; break;
case RPC_AUTH_GSS: case RPC_AUTH_GSS:
dprintk("RPC_AUTH_GSS callback secflavor " dprintk("RPC_AUTH_GSS callback secflavor "
...@@ -1232,7 +1230,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, ...@@ -1232,7 +1230,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
READ_BUF(4); READ_BUF(4);
READ32(dummy); READ32(dummy);
READ_BUF(dummy); READ_BUF(dummy);
p += XDR_QUADLEN(dummy);
break; break;
default: default:
dprintk("Illegal callback secflavor\n"); dprintk("Illegal callback secflavor\n");
......
...@@ -12,13 +12,14 @@ ...@@ -12,13 +12,14 @@
#include <linux/nfsd/syscall.h> #include <linux/nfsd/syscall.h>
#include <linux/lockd/lockd.h> #include <linux/lockd/lockd.h>
#include <linux/sunrpc/clnt.h> #include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/gss_api.h>
#include "idmap.h" #include "idmap.h"
#include "nfsd.h" #include "nfsd.h"
#include "cache.h" #include "cache.h"
/* /*
* We have a single directory with 9 nodes in it. * We have a single directory with several nodes in it.
*/ */
enum { enum {
NFSD_Root = 1, NFSD_Root = 1,
...@@ -42,6 +43,7 @@ enum { ...@@ -42,6 +43,7 @@ enum {
NFSD_Versions, NFSD_Versions,
NFSD_Ports, NFSD_Ports,
NFSD_MaxBlkSize, NFSD_MaxBlkSize,
NFSD_SupportedEnctypes,
/* /*
* The below MUST come last. Otherwise we leave a hole in nfsd_files[] * The below MUST come last. Otherwise we leave a hole in nfsd_files[]
* with !CONFIG_NFSD_V4 and simple_fill_super() goes oops * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
...@@ -187,6 +189,34 @@ static struct file_operations export_features_operations = { ...@@ -187,6 +189,34 @@ static struct file_operations export_features_operations = {
.release = single_release, .release = single_release,
}; };
#ifdef CONFIG_SUNRPC_GSS
static int supported_enctypes_show(struct seq_file *m, void *v)
{
struct gss_api_mech *k5mech;
k5mech = gss_mech_get_by_name("krb5");
if (k5mech == NULL)
goto out;
if (k5mech->gm_upcall_enctypes != NULL)
seq_printf(m, k5mech->gm_upcall_enctypes);
gss_mech_put(k5mech);
out:
return 0;
}
static int supported_enctypes_open(struct inode *inode, struct file *file)
{
return single_open(file, supported_enctypes_show, NULL);
}
static struct file_operations supported_enctypes_ops = {
.open = supported_enctypes_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#endif /* CONFIG_SUNRPC_GSS */
extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); extern int nfsd_pool_stats_release(struct inode *inode, struct file *file);
...@@ -1397,6 +1427,9 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) ...@@ -1397,6 +1427,9 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
[NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
#ifdef CONFIG_SUNRPC_GSS
[NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
#endif /* CONFIG_SUNRPC_GSS */
#ifdef CONFIG_NFSD_V4 #ifdef CONFIG_NFSD_V4
[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
......
...@@ -367,16 +367,12 @@ struct nfs4_file { ...@@ -367,16 +367,12 @@ struct nfs4_file {
struct list_head fi_delegations; struct list_head fi_delegations;
/* One each for O_RDONLY, O_WRONLY, O_RDWR: */ /* One each for O_RDONLY, O_WRONLY, O_RDWR: */
struct file * fi_fds[3]; struct file * fi_fds[3];
/* One each for O_RDONLY, O_WRONLY: */
atomic_t fi_access[2];
/* /*
* Each open stateid contributes 1 to either fi_readers or * Each open or lock stateid contributes 1 to either
* fi_writers, or both, depending on the open mode. A * fi_access[O_RDONLY], fi_access[O_WRONLY], or both, depending
* delegation also takes an fi_readers reference. Lock * on open or lock mode:
* stateid's take none.
*/ */
atomic_t fi_readers; atomic_t fi_access[2];
atomic_t fi_writers;
struct file *fi_deleg_file; struct file *fi_deleg_file;
struct file_lock *fi_lease; struct file_lock *fi_lease;
atomic_t fi_delegees; atomic_t fi_delegees;
......
...@@ -1749,8 +1749,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, ...@@ -1749,8 +1749,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
if (host_err) if (host_err)
goto out_drop_write; goto out_drop_write;
} }
if (host_err)
goto out_drop_write;
host_err = vfs_rename(fdir, odentry, tdir, ndentry); host_err = vfs_rename(fdir, odentry, tdir, ndentry);
if (!host_err) { if (!host_err) {
host_err = commit_metadata(tfhp); host_err = commit_metadata(tfhp);
......
...@@ -38,6 +38,14 @@ struct unix_domain { ...@@ -38,6 +38,14 @@ struct unix_domain {
extern struct auth_ops svcauth_unix; extern struct auth_ops svcauth_unix;
static void svcauth_unix_domain_release(struct auth_domain *dom)
{
struct unix_domain *ud = container_of(dom, struct unix_domain, h);
kfree(dom->name);
kfree(ud);
}
struct auth_domain *unix_domain_find(char *name) struct auth_domain *unix_domain_find(char *name)
{ {
struct auth_domain *rv; struct auth_domain *rv;
...@@ -47,7 +55,7 @@ struct auth_domain *unix_domain_find(char *name) ...@@ -47,7 +55,7 @@ struct auth_domain *unix_domain_find(char *name)
while(1) { while(1) {
if (rv) { if (rv) {
if (new && rv != &new->h) if (new && rv != &new->h)
auth_domain_put(&new->h); svcauth_unix_domain_release(&new->h);
if (rv->flavour != &svcauth_unix) { if (rv->flavour != &svcauth_unix) {
auth_domain_put(rv); auth_domain_put(rv);
...@@ -74,14 +82,6 @@ struct auth_domain *unix_domain_find(char *name) ...@@ -74,14 +82,6 @@ struct auth_domain *unix_domain_find(char *name)
} }
EXPORT_SYMBOL_GPL(unix_domain_find); EXPORT_SYMBOL_GPL(unix_domain_find);
static void svcauth_unix_domain_release(struct auth_domain *dom)
{
struct unix_domain *ud = container_of(dom, struct unix_domain, h);
kfree(dom->name);
kfree(ud);
}
/************************************************** /**************************************************
* cache for IP address to unix_domain * cache for IP address to unix_domain
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment