Commit 38d7463e authored by James Simmons's avatar James Simmons

Merge bk://linus.bkbits.net/linux-2.5

into maxwell.earthlink.net:/usr/src/linus-2.5
parents bca102e6 c39f7320
...@@ -56,11 +56,8 @@ ...@@ -56,11 +56,8 @@
#include <linux/blk.h> #include <linux/blk.h>
#define DEBUG 0 #define DEBUG 0
#if DEBUG #define dprintk(x...) ((void)(DEBUG && printk(x)))
# define dprintk(x...) printk(x)
#else
# define dprintk(x...) do { } while(0)
#endif
#ifndef MODULE #ifndef MODULE
static void autostart_arrays (void); static void autostart_arrays (void);
...@@ -604,18 +601,6 @@ static void export_array(mddev_t *mddev) ...@@ -604,18 +601,6 @@ static void export_array(mddev_t *mddev)
mddev->raid_disks = 0; mddev->raid_disks = 0;
} }
static void free_mddev(mddev_t *mddev)
{
if (!mddev) {
MD_BUG();
return;
}
export_array(mddev);
md_size[mdidx(mddev)] = 0;
set_capacity(disks[mdidx(mddev)], 0);
}
#undef BAD_CSUM #undef BAD_CSUM
#undef BAD_MAGIC #undef BAD_MAGIC
#undef OUT_OF_MEM #undef OUT_OF_MEM
...@@ -1533,7 +1518,6 @@ static int do_md_stop(mddev_t * mddev, int ro) ...@@ -1533,7 +1518,6 @@ static int do_md_stop(mddev_t * mddev, int ro)
{ {
int err = 0; int err = 0;
kdev_t dev = mddev_to_kdev(mddev); kdev_t dev = mddev_to_kdev(mddev);
struct gendisk *disk;
if (atomic_read(&mddev->active)>1) { if (atomic_read(&mddev->active)>1) {
printk(STILL_IN_USE, mdidx(mddev)); printk(STILL_IN_USE, mdidx(mddev));
...@@ -1582,6 +1566,16 @@ static int do_md_stop(mddev_t * mddev, int ro) ...@@ -1582,6 +1566,16 @@ static int do_md_stop(mddev_t * mddev, int ro)
if (ro) if (ro)
set_device_ro(dev, 1); set_device_ro(dev, 1);
} }
/*
* Free resources if final stop
*/
if (!ro) {
struct gendisk *disk;
printk(KERN_INFO "md: md%d stopped.\n", mdidx(mddev));
export_array(mddev);
md_size[mdidx(mddev)] = 0;
disk = disks[mdidx(mddev)]; disk = disks[mdidx(mddev)];
disks[mdidx(mddev)] = NULL; disks[mdidx(mddev)] = NULL;
...@@ -1591,12 +1585,6 @@ static int do_md_stop(mddev_t * mddev, int ro) ...@@ -1591,12 +1585,6 @@ static int do_md_stop(mddev_t * mddev, int ro)
kfree(disk); kfree(disk);
} }
/*
* Free resources if final stop
*/
if (!ro) {
printk(KERN_INFO "md: md%d stopped.\n", mdidx(mddev));
free_mddev(mddev);
} else } else
printk(KERN_INFO "md: md%d switched to read-only mode.\n", mdidx(mddev)); printk(KERN_INFO "md: md%d switched to read-only mode.\n", mdidx(mddev));
err = 0; err = 0;
...@@ -2593,7 +2581,7 @@ static void md_recover_arrays(void) ...@@ -2593,7 +2581,7 @@ static void md_recover_arrays(void)
void md_error(mddev_t *mddev, mdk_rdev_t *rdev) void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
{ {
dprintk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n", dprintk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",
MD_MAJOR,mdidx(mddev),MAJOR(bdev->bd_dev),MINOR(bdev->bd_dev), MD_MAJOR,mdidx(mddev),MAJOR(rdev->bdev->bd_dev),MINOR(rdev->bdev->bd_dev),
__builtin_return_address(0),__builtin_return_address(1), __builtin_return_address(0),__builtin_return_address(1),
__builtin_return_address(2),__builtin_return_address(3)); __builtin_return_address(2),__builtin_return_address(3));
...@@ -3149,11 +3137,11 @@ request_queue_t * md_queue_proc(kdev_t dev) ...@@ -3149,11 +3137,11 @@ request_queue_t * md_queue_proc(kdev_t dev)
{ {
mddev_t *mddev = mddev_find(minor(dev)); mddev_t *mddev = mddev_find(minor(dev));
request_queue_t *q = BLK_DEFAULT_QUEUE(MAJOR_NR); request_queue_t *q = BLK_DEFAULT_QUEUE(MAJOR_NR);
if (!mddev || atomic_read(&mddev->active)<2) if (mddev) {
BUG();
if (mddev->pers) if (mddev->pers)
q = &mddev->queue; q = &mddev->queue;
mddev_put(mddev); /* the caller must hold a reference... */ mddev_put(mddev);
}
return q; return q;
} }
......
...@@ -37,20 +37,6 @@ ...@@ -37,20 +37,6 @@
#define NR_RESERVED_BUFS 32 #define NR_RESERVED_BUFS 32
/*
* The following can be used to debug the driver
*/
#define MULTIPATH_DEBUG 0
#if MULTIPATH_DEBUG
#define PRINTK(x...) printk(x)
#define inline
#define __inline__
#else
#define PRINTK(x...) do { } while (0)
#endif
static mdk_personality_t multipath_personality; static mdk_personality_t multipath_personality;
static spinlock_t retry_list_lock = SPIN_LOCK_UNLOCKED; static spinlock_t retry_list_lock = SPIN_LOCK_UNLOCKED;
struct multipath_bh *multipath_retry_list = NULL, **multipath_retry_tail; struct multipath_bh *multipath_retry_list = NULL, **multipath_retry_tail;
......
...@@ -49,12 +49,10 @@ ...@@ -49,12 +49,10 @@
# define CHECK_DEVLOCK() # define CHECK_DEVLOCK()
#endif #endif
#define PRINTK(x...) ((void)(RAID5_DEBUG && printk(x)))
#if RAID5_DEBUG #if RAID5_DEBUG
#define PRINTK(x...) printk(x)
#define inline #define inline
#define __inline__ #define __inline__
#else
#define PRINTK(x...) do { } while (0)
#endif #endif
static void print_raid5_conf (raid5_conf_t *conf); static void print_raid5_conf (raid5_conf_t *conf);
...@@ -933,13 +931,16 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -933,13 +931,16 @@ static void handle_stripe(struct stripe_head *sh)
test_bit(R5_UPTODATE, &dev->flags)) test_bit(R5_UPTODATE, &dev->flags))
|| (failed == 1 && failed_num == sh->pd_idx)) || (failed == 1 && failed_num == sh->pd_idx))
) { ) {
/* any written block on an uptodate or failed drive can be returned */ /* any written block on an uptodate or failed drive can be returned.
* Note that if we 'wrote' to a failed drive, it will be UPTODATE, but
* never LOCKED, so we don't need to test 'failed' directly.
*/
for (i=disks; i--; ) for (i=disks; i--; )
if (sh->dev[i].written) { if (sh->dev[i].written) {
dev = &sh->dev[i]; dev = &sh->dev[i];
if (!test_bit(R5_Insync, &sh->dev[sh->pd_idx].flags) && if (!test_bit(R5_LOCKED, &dev->flags) &&
(!test_bit(R5_LOCKED, &dev->flags) && test_bit(R5_UPTODATE, &dev->flags)) ) { test_bit(R5_UPTODATE, &dev->flags) ) {
/* maybe we can return some write requests */ /* We can return any write requests */
struct bio *wbi, *wbi2; struct bio *wbi, *wbi2;
PRINTK("Return write for disc %d\n", i); PRINTK("Return write for disc %d\n", i);
wbi = dev->written; wbi = dev->written;
...@@ -1164,7 +1165,7 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -1164,7 +1165,7 @@ static void handle_stripe(struct stripe_head *sh)
md_sync_acct(rdev, STRIPE_SECTORS); md_sync_acct(rdev, STRIPE_SECTORS);
bi->bi_bdev = rdev->bdev; bi->bi_bdev = rdev->bdev;
PRINTK("for %ld schedule op %d on disc %d\n", sh->sector, bi->bi_rw, i); PRINTK("for %ld schedule op %ld on disc %d\n", sh->sector, bi->bi_rw, i);
atomic_inc(&sh->count); atomic_inc(&sh->count);
bi->bi_sector = sh->sector; bi->bi_sector = sh->sector;
bi->bi_flags = 0; bi->bi_flags = 0;
...@@ -1175,7 +1176,7 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -1175,7 +1176,7 @@ static void handle_stripe(struct stripe_head *sh)
bi->bi_next = NULL; bi->bi_next = NULL;
generic_make_request(bi); generic_make_request(bi);
} else { } else {
PRINTK("skip op %d on disc %d for sector %ld\n", bi->bi_rw, i, sh->sector); PRINTK("skip op %ld on disc %d for sector %ld\n", bi->bi_rw, i, sh->sector);
clear_bit(R5_LOCKED, &dev->flags); clear_bit(R5_LOCKED, &dev->flags);
set_bit(STRIPE_HANDLE, &sh->state); set_bit(STRIPE_HANDLE, &sh->state);
} }
...@@ -1242,8 +1243,8 @@ static int make_request (request_queue_t *q, struct bio * bi) ...@@ -1242,8 +1243,8 @@ static int make_request (request_queue_t *q, struct bio * bi)
new_sector = raid5_compute_sector(logical_sector, new_sector = raid5_compute_sector(logical_sector,
raid_disks, data_disks, &dd_idx, &pd_idx, conf); raid_disks, data_disks, &dd_idx, &pd_idx, conf);
PRINTK("raid5: make_request, sector %ul logical %ul\n", PRINTK("raid5: make_request, sector %Lu logical %Lu\n",
new_sector, logical_sector); (unsigned long long)new_sector, (unsigned long long)logical_sector);
sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK)); sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK));
if (sh) { if (sh) {
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#define NLM_HOST_MAX 64 #define NLM_HOST_MAX 64
#define NLM_HOST_NRHASH 32 #define NLM_HOST_NRHASH 32
#define NLM_ADDRHASH(addr) (ntohl(addr) & (NLM_HOST_NRHASH-1)) #define NLM_ADDRHASH(addr) (ntohl(addr) & (NLM_HOST_NRHASH-1))
#define NLM_PTRHASH(ptr) ((((u32)(unsigned long) ptr) / 32) & (NLM_HOST_NRHASH-1))
#define NLM_HOST_REBIND (60 * HZ) #define NLM_HOST_REBIND (60 * HZ)
#define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ) #define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ)
#define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ) #define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ)
...@@ -42,7 +41,7 @@ static void nlm_gc_hosts(void); ...@@ -42,7 +41,7 @@ static void nlm_gc_hosts(void);
struct nlm_host * struct nlm_host *
nlmclnt_lookup_host(struct sockaddr_in *sin, int proto, int version) nlmclnt_lookup_host(struct sockaddr_in *sin, int proto, int version)
{ {
return nlm_lookup_host(NULL, sin, proto, version); return nlm_lookup_host(0, sin, proto, version);
} }
/* /*
...@@ -51,44 +50,24 @@ nlmclnt_lookup_host(struct sockaddr_in *sin, int proto, int version) ...@@ -51,44 +50,24 @@ nlmclnt_lookup_host(struct sockaddr_in *sin, int proto, int version)
struct nlm_host * struct nlm_host *
nlmsvc_lookup_host(struct svc_rqst *rqstp) nlmsvc_lookup_host(struct svc_rqst *rqstp)
{ {
return nlm_lookup_host(rqstp->rq_client, &rqstp->rq_addr, return nlm_lookup_host(1, &rqstp->rq_addr,
rqstp->rq_prot, rqstp->rq_vers); rqstp->rq_prot, rqstp->rq_vers);
} }
/*
* Match the given host against client/address
*/
static inline int
nlm_match_host(struct nlm_host *host, struct svc_client *clnt,
struct sockaddr_in *sin)
{
if (clnt)
return host->h_exportent == clnt;
return nlm_cmp_addr(&host->h_addr, sin);
}
/* /*
* Common host lookup routine for server & client * Common host lookup routine for server & client
*/ */
struct nlm_host * struct nlm_host *
nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin, nlm_lookup_host(int server, struct sockaddr_in *sin,
int proto, int version) int proto, int version)
{ {
struct nlm_host *host, **hp; struct nlm_host *host, **hp;
u32 addr; u32 addr;
int hash; int hash;
if (!clnt && !sin) {
printk(KERN_NOTICE "lockd: no clnt or addr in lookup_host!\n");
return NULL;
}
dprintk("lockd: nlm_lookup_host(%08x, p=%d, v=%d)\n", dprintk("lockd: nlm_lookup_host(%08x, p=%d, v=%d)\n",
(unsigned)(sin? ntohl(sin->sin_addr.s_addr) : 0), proto, version); (unsigned)(sin? ntohl(sin->sin_addr.s_addr) : 0), proto, version);
if (clnt)
hash = NLM_PTRHASH(clnt);
else
hash = NLM_ADDRHASH(sin->sin_addr.s_addr); hash = NLM_ADDRHASH(sin->sin_addr.s_addr);
/* Lock hash table */ /* Lock hash table */
...@@ -98,12 +77,14 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin, ...@@ -98,12 +77,14 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin,
nlm_gc_hosts(); nlm_gc_hosts();
for (hp = &nlm_hosts[hash]; (host = *hp); hp = &host->h_next) { for (hp = &nlm_hosts[hash]; (host = *hp); hp = &host->h_next) {
if (proto && host->h_proto != proto) if (host->h_proto != proto)
continue; continue;
if (version && host->h_version != version) if (host->h_version != version)
continue;
if (host->h_server != server)
continue; continue;
if (nlm_match_host(host, clnt, sin)) { if (nlm_cmp_addr(&host->h_addr, sin)) {
if (hp != nlm_hosts + hash) { if (hp != nlm_hosts + hash) {
*hp = host->h_next; *hp = host->h_next;
host->h_next = nlm_hosts[hash]; host->h_next = nlm_hosts[hash];
...@@ -115,10 +96,6 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin, ...@@ -115,10 +96,6 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin,
} }
} }
/* special hack for nlmsvc_invalidate_client */
if (sin == NULL)
goto nohost;
/* Ooops, no host found, create it */ /* Ooops, no host found, create it */
dprintk("lockd: creating host entry\n"); dprintk("lockd: creating host entry\n");
...@@ -146,8 +123,7 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin, ...@@ -146,8 +123,7 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin,
init_waitqueue_head(&host->h_gracewait); init_waitqueue_head(&host->h_gracewait);
host->h_state = 0; /* pseudo NSM state */ host->h_state = 0; /* pseudo NSM state */
host->h_nsmstate = 0; /* real NSM state */ host->h_nsmstate = 0; /* real NSM state */
host->h_exportent = clnt; host->h_server = server;
host->h_next = nlm_hosts[hash]; host->h_next = nlm_hosts[hash];
nlm_hosts[hash] = host; nlm_hosts[hash] = host;
...@@ -159,6 +135,30 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin, ...@@ -159,6 +135,30 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin,
return host; return host;
} }
struct nlm_host *
nlm_find_client(void)
{
/* find a nlm_host for a client for which h_killed == 0.
* and return it
*/
int hash;
down(&nlm_host_sema);
for (hash = 0 ; hash < NLM_HOST_NRHASH; hash++) {
struct nlm_host *host, **hp;
for (hp = &nlm_hosts[hash]; (host = *hp) ; hp = &host->h_next) {
if (host->h_server &&
host->h_killed == 0) {
nlm_get_host(host);
up(&nlm_host_sema);
return host;
}
}
}
up(&nlm_host_sema);
return NULL;
}
/* /*
* Create the NLM RPC client for an NLM peer * Create the NLM RPC client for an NLM peer
*/ */
......
...@@ -32,7 +32,6 @@ EXPORT_SYMBOL(lockd_down); ...@@ -32,7 +32,6 @@ EXPORT_SYMBOL(lockd_down);
EXPORT_SYMBOL(nlmclnt_proc); EXPORT_SYMBOL(nlmclnt_proc);
/* NFS server entry points/hooks */ /* NFS server entry points/hooks */
EXPORT_SYMBOL(nlmsvc_invalidate_client);
EXPORT_SYMBOL(nlmsvc_ops); EXPORT_SYMBOL(nlmsvc_ops);
#endif /* CONFIG_MODULES */ #endif /* CONFIG_MODULES */
...@@ -42,6 +42,7 @@ nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res) ...@@ -42,6 +42,7 @@ nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res)
goto out; goto out;
args.addr = host->h_addr.sin_addr.s_addr; args.addr = host->h_addr.sin_addr.s_addr;
args.proto= (host->h_proto<<1) | host->h_server;
args.prog = NLM_PROGRAM; args.prog = NLM_PROGRAM;
args.vers = host->h_version; args.vers = host->h_version;
args.proc = NLMPROC_NSM_NOTIFY; args.proc = NLMPROC_NSM_NOTIFY;
...@@ -167,8 +168,8 @@ xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) ...@@ -167,8 +168,8 @@ xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
/* This is the private part. Needed only for SM_MON call */ /* This is the private part. Needed only for SM_MON call */
if (rqstp->rq_task->tk_msg.rpc_proc == SM_MON) { if (rqstp->rq_task->tk_msg.rpc_proc == SM_MON) {
*p++ = argp->addr; *p++ = argp->addr;
*p++ = 0; *p++ = argp->vers;
*p++ = 0; *p++ = argp->proto;
*p++ = 0; *p++ = 0;
} }
...@@ -206,61 +207,60 @@ xdr_decode_stat(struct rpc_rqst *rqstp, u32 *p, struct nsm_res *resp) ...@@ -206,61 +207,60 @@ xdr_decode_stat(struct rpc_rqst *rqstp, u32 *p, struct nsm_res *resp)
static struct rpc_procinfo nsm_procedures[] = { static struct rpc_procinfo nsm_procedures[] = {
{ {
p_procname: "sm_null", .p_procname = "sm_null",
p_encode: (kxdrproc_t) xdr_error, .p_encode = (kxdrproc_t) xdr_error,
p_decode: (kxdrproc_t) xdr_error, .p_decode = (kxdrproc_t) xdr_error,
}, },
{ {
p_procname: "sm_stat", .p_procname = "sm_stat",
p_encode: (kxdrproc_t) xdr_error, .p_encode = (kxdrproc_t) xdr_error,
p_decode: (kxdrproc_t) xdr_error, .p_decode = (kxdrproc_t) xdr_error,
}, },
{ {
p_procname: "sm_mon", .p_procname = "sm_mon",
p_encode: (kxdrproc_t) xdr_encode_mon, .p_encode = (kxdrproc_t) xdr_encode_mon,
p_decode: (kxdrproc_t) xdr_decode_stat_res, .p_decode = (kxdrproc_t) xdr_decode_stat_res,
p_bufsiz: MAX(SM_mon_sz, SM_monres_sz) << 2, .p_bufsiz = MAX(SM_mon_sz, SM_monres_sz) << 2,
}, },
{ {
p_procname: "sm_unmon", .p_procname = "sm_unmon",
p_encode: (kxdrproc_t) xdr_encode_mon, .p_encode = (kxdrproc_t) xdr_encode_mon,
p_decode: (kxdrproc_t) xdr_decode_stat, .p_decode = (kxdrproc_t) xdr_decode_stat,
p_bufsiz: MAX(SM_mon_id_sz, SM_unmonres_sz) << 2, .p_bufsiz = MAX(SM_mon_id_sz, SM_unmonres_sz) << 2,
}, },
{ {
p_procname: "sm_unmon_all", .p_procname = "sm_unmon_all",
p_encode: (kxdrproc_t) xdr_error, .p_encode = (kxdrproc_t) xdr_error,
p_decode: (kxdrproc_t) xdr_error, .p_decode = (kxdrproc_t) xdr_error,
}, },
{ {
p_procname: "sm_simu_crash", .p_procname = "sm_simu_crash",
p_encode: (kxdrproc_t) xdr_error, .p_encode = (kxdrproc_t) xdr_error,
p_decode: (kxdrproc_t) xdr_error, 0, 0 .p_decode = (kxdrproc_t) xdr_error,
}, },
{ {
p_procname: "sm_notify", .p_procname = "sm_notify",
p_encode: (kxdrproc_t) xdr_error, .p_encode = (kxdrproc_t) xdr_error,
p_decode: (kxdrproc_t) xdr_error, .p_decode = (kxdrproc_t) xdr_error,
}, },
}; };
static struct rpc_version nsm_version1 = { static struct rpc_version nsm_version1 = {
number: 1, .number = 1,
nrprocs: sizeof(nsm_procedures)/sizeof(nsm_procedures[0]), .nrprocs = sizeof(nsm_procedures)/sizeof(nsm_procedures[0]),
procs: nsm_procedures .procs = nsm_procedures
}; };
static struct rpc_version * nsm_version[] = { static struct rpc_version * nsm_version[] = {
NULL, [1] = &nsm_version1,
&nsm_version1,
}; };
static struct rpc_stat nsm_stats; static struct rpc_stat nsm_stats;
struct rpc_program nsm_program = { struct rpc_program nsm_program = {
name: "statd", .name = "statd",
number: SM_PROGRAM, .number = SM_PROGRAM,
nrvers: sizeof(nsm_version)/sizeof(nsm_version[0]), .nrvers = sizeof(nsm_version)/sizeof(nsm_version[0]),
version: nsm_version, .version = nsm_version,
stats: &nsm_stats .stats = &nsm_stats
}; };
...@@ -130,7 +130,7 @@ lockd(struct svc_rqst *rqstp) ...@@ -130,7 +130,7 @@ lockd(struct svc_rqst *rqstp)
flush_signals(current); flush_signals(current);
spin_unlock_irq(&current->sigmask_lock); spin_unlock_irq(&current->sigmask_lock);
if (nlmsvc_ops) { if (nlmsvc_ops) {
nlmsvc_ops->detach(); nlmsvc_invalidate_all();
grace_period_expire = set_grace_period(); grace_period_expire = set_grace_period();
} }
} }
...@@ -163,22 +163,8 @@ lockd(struct svc_rqst *rqstp) ...@@ -163,22 +163,8 @@ lockd(struct svc_rqst *rqstp)
dprintk("lockd: request from %08x\n", dprintk("lockd: request from %08x\n",
(unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr)); (unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr));
/*
* Look up the NFS client handle. The handle is needed for
* all but the GRANTED callback RPCs.
*/
rqstp->rq_client = NULL;
if (nlmsvc_ops) {
nlmsvc_ops->exp_readlock();
rqstp->rq_client =
nlmsvc_ops->exp_getclient(&rqstp->rq_addr);
}
svc_process(serv, rqstp); svc_process(serv, rqstp);
/* Unlock export hash tables */
if (nlmsvc_ops)
nlmsvc_ops->exp_unlock();
} }
/* /*
...@@ -187,7 +173,7 @@ lockd(struct svc_rqst *rqstp) ...@@ -187,7 +173,7 @@ lockd(struct svc_rqst *rqstp)
*/ */
if (!nlmsvc_pid || current->pid == nlmsvc_pid) { if (!nlmsvc_pid || current->pid == nlmsvc_pid) {
if (nlmsvc_ops) if (nlmsvc_ops)
nlmsvc_ops->detach(); nlmsvc_invalidate_all();
nlm_shutdown_hosts(); nlm_shutdown_hosts();
nlmsvc_pid = 0; nlmsvc_pid = 0;
} else } else
...@@ -369,29 +355,27 @@ __setup("lockd.tcpport=", tcpport_set); ...@@ -369,29 +355,27 @@ __setup("lockd.tcpport=", tcpport_set);
* Define NLM program and procedures * Define NLM program and procedures
*/ */
static struct svc_version nlmsvc_version1 = { static struct svc_version nlmsvc_version1 = {
vs_vers: 1, .vs_vers = 1,
vs_nproc: 17, .vs_nproc = 17,
vs_proc: nlmsvc_procedures, .vs_proc = nlmsvc_procedures,
}; };
static struct svc_version nlmsvc_version3 = { static struct svc_version nlmsvc_version3 = {
vs_vers: 3, .vs_vers = 3,
vs_nproc: 24, .vs_nproc = 24,
vs_proc: nlmsvc_procedures, .vs_proc = nlmsvc_procedures,
}; };
#ifdef CONFIG_LOCKD_V4 #ifdef CONFIG_LOCKD_V4
static struct svc_version nlmsvc_version4 = { static struct svc_version nlmsvc_version4 = {
vs_vers: 4, .vs_vers = 4,
vs_nproc: 24, .vs_nproc = 24,
vs_proc: nlmsvc_procedures4, .vs_proc = nlmsvc_procedures4,
}; };
#endif #endif
static struct svc_version * nlmsvc_version[] = { static struct svc_version * nlmsvc_version[] = {
NULL, [1] = &nlmsvc_version1,
&nlmsvc_version1, [3] = &nlmsvc_version3,
NULL,
&nlmsvc_version3,
#ifdef CONFIG_LOCKD_V4 #ifdef CONFIG_LOCKD_V4
&nlmsvc_version4, [4] = &nlmsvc_version4,
#endif #endif
}; };
...@@ -399,11 +383,11 @@ static struct svc_stat nlmsvc_stats; ...@@ -399,11 +383,11 @@ static struct svc_stat nlmsvc_stats;
#define NLM_NRVERS (sizeof(nlmsvc_version)/sizeof(nlmsvc_version[0])) #define NLM_NRVERS (sizeof(nlmsvc_version)/sizeof(nlmsvc_version[0]))
struct svc_program nlmsvc_program = { struct svc_program nlmsvc_program = {
pg_prog: NLM_PROGRAM, /* program number */ .pg_prog = NLM_PROGRAM, /* program number */
pg_lovers: 1, // version .pg_lovers = 1, /* version */
pg_hivers: NLM_NRVERS-1, // range .pg_hivers = NLM_NRVERS-1, /* range */
pg_nvers: NLM_NRVERS, /* number of entries in nlmsvc_version */ .pg_nvers = NLM_NRVERS, /* number of entries in nlmsvc_version */
pg_vers: nlmsvc_version, /* version table */ .pg_vers = nlmsvc_version, /* version table */
pg_name: "lockd", /* service name */ .pg_name = "lockd", /* service name */
pg_stats: &nlmsvc_stats, /* stats table */ .pg_stats = &nlmsvc_stats, /* stats table */
}; };
...@@ -40,15 +40,6 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, ...@@ -40,15 +40,6 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
if (!nlmsvc_ops) if (!nlmsvc_ops)
return nlm_lck_denied_nolocks; return nlm_lck_denied_nolocks;
/* Obtain handle for client host */
if (rqstp->rq_client == NULL) {
printk(KERN_NOTICE
"lockd: unauthenticated request from (%08x:%d)\n",
ntohl(rqstp->rq_addr.sin_addr.s_addr),
ntohs(rqstp->rq_addr.sin_port));
return nlm_lck_denied_nolocks;
}
/* Obtain host handle */ /* Obtain host handle */
if (!(host = nlmsvc_lookup_host(rqstp)) if (!(host = nlmsvc_lookup_host(rqstp))
|| (argp->monitor && !host->h_monitored && nsm_monitor(host) < 0)) || (argp->monitor && !host->h_monitored && nsm_monitor(host) < 0))
...@@ -420,8 +411,9 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, ...@@ -420,8 +411,9 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
void *resp) void *resp)
{ {
struct sockaddr_in saddr = rqstp->rq_addr; struct sockaddr_in saddr = rqstp->rq_addr;
int vers = rqstp->rq_vers; int vers = argp->vers;
int prot = rqstp->rq_prot; int prot = argp->proto >> 1;
struct nlm_host *host; struct nlm_host *host;
dprintk("lockd: SM_NOTIFY called\n"); dprintk("lockd: SM_NOTIFY called\n");
...@@ -438,24 +430,20 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, ...@@ -438,24 +430,20 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
* reclaim all locks we hold on this server. * reclaim all locks we hold on this server.
*/ */
saddr.sin_addr.s_addr = argp->addr; saddr.sin_addr.s_addr = argp->addr;
if ((argp->proto & 1)==0) {
if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) { if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) {
nlmclnt_recovery(host, argp->state); nlmclnt_recovery(host, argp->state);
nlm_release_host(host); nlm_release_host(host);
} }
} else {
/* If we run on an NFS server, delete all locks held by the client */ /* If we run on an NFS server, delete all locks held by the client */
if (nlmsvc_ops != NULL) {
struct svc_client *clnt; if ((host = nlm_lookup_host(1, &saddr, prot, vers)) != NULL) {
saddr.sin_addr.s_addr = argp->addr;
nlmsvc_ops->exp_readlock();
if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL
&& (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) {
nlmsvc_free_host_resources(host); nlmsvc_free_host_resources(host);
}
nlm_release_host(host); nlm_release_host(host);
nlmsvc_ops->exp_unlock();
} }
}
return rpc_success; return rpc_success;
} }
...@@ -527,15 +515,13 @@ nlm4svc_callback_exit(struct rpc_task *task) ...@@ -527,15 +515,13 @@ nlm4svc_callback_exit(struct rpc_task *task)
struct nlm_void { int dummy; }; struct nlm_void { int dummy; };
#define PROC(name, xargt, xrest, argt, rest, respsize) \ #define PROC(name, xargt, xrest, argt, rest, respsize) \
{ (svc_procfunc) nlm4svc_proc_##name, \ { .pc_func = (svc_procfunc) nlm4svc_proc_##name, \
(kxdrproc_t) nlm4svc_decode_##xargt, \ .pc_decode = (kxdrproc_t) nlm4svc_decode_##xargt, \
(kxdrproc_t) nlm4svc_encode_##xrest, \ .pc_encode = (kxdrproc_t) nlm4svc_encode_##xrest, \
NULL, \ .pc_release = NULL, \
sizeof(struct nlm_##argt), \ .pc_argsize = sizeof(struct nlm_##argt), \
sizeof(struct nlm_##rest), \ .pc_ressize = sizeof(struct nlm_##rest), \
0, \ .pc_xdrressize = respsize, \
0, \
respsize, \
} }
#define Ck (1+8) /* cookie */ #define Ck (1+8) /* cookie */
#define No (1+1024/4) /* netobj */ #define No (1+1024/4) /* netobj */
......
...@@ -69,15 +69,6 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, ...@@ -69,15 +69,6 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
if (!nlmsvc_ops) if (!nlmsvc_ops)
return nlm_lck_denied_nolocks; return nlm_lck_denied_nolocks;
/* Obtain handle for client host */
if (rqstp->rq_client == NULL) {
printk(KERN_NOTICE
"lockd: unauthenticated request from (%08x:%d)\n",
ntohl(rqstp->rq_addr.sin_addr.s_addr),
ntohs(rqstp->rq_addr.sin_port));
return nlm_lck_denied_nolocks;
}
/* Obtain host handle */ /* Obtain host handle */
if (!(host = nlmsvc_lookup_host(rqstp)) if (!(host = nlmsvc_lookup_host(rqstp))
|| (argp->monitor && !host->h_monitored && nsm_monitor(host) < 0)) || (argp->monitor && !host->h_monitored && nsm_monitor(host) < 0))
...@@ -448,8 +439,8 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, ...@@ -448,8 +439,8 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
void *resp) void *resp)
{ {
struct sockaddr_in saddr = rqstp->rq_addr; struct sockaddr_in saddr = rqstp->rq_addr;
int vers = rqstp->rq_vers; int vers = argp->vers;
int prot = rqstp->rq_prot; int prot = argp->proto >> 1;
struct nlm_host *host; struct nlm_host *host;
dprintk("lockd: SM_NOTIFY called\n"); dprintk("lockd: SM_NOTIFY called\n");
...@@ -466,22 +457,17 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, ...@@ -466,22 +457,17 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
* reclaim all locks we hold on this server. * reclaim all locks we hold on this server.
*/ */
saddr.sin_addr.s_addr = argp->addr; saddr.sin_addr.s_addr = argp->addr;
if ((argp->proto & 1)==0) {
if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) { if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) {
nlmclnt_recovery(host, argp->state); nlmclnt_recovery(host, argp->state);
nlm_release_host(host); nlm_release_host(host);
} }
} else {
/* If we run on an NFS server, delete all locks held by the client */ /* If we run on an NFS server, delete all locks held by the client */
if (nlmsvc_ops != NULL) { if ((host = nlm_lookup_host(1, &saddr, prot, vers)) != NULL) {
struct svc_client *clnt;
saddr.sin_addr.s_addr = argp->addr;
nlmsvc_ops->exp_readlock();
if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL
&& (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) {
nlmsvc_free_host_resources(host); nlmsvc_free_host_resources(host);
}
nlm_release_host(host); nlm_release_host(host);
nlmsvc_ops->exp_unlock(); }
} }
return rpc_success; return rpc_success;
...@@ -555,15 +541,13 @@ nlmsvc_callback_exit(struct rpc_task *task) ...@@ -555,15 +541,13 @@ nlmsvc_callback_exit(struct rpc_task *task)
struct nlm_void { int dummy; }; struct nlm_void { int dummy; };
#define PROC(name, xargt, xrest, argt, rest, respsize) \ #define PROC(name, xargt, xrest, argt, rest, respsize) \
{ (svc_procfunc) nlmsvc_proc_##name, \ { .pc_func = (svc_procfunc) nlmsvc_proc_##name, \
(kxdrproc_t) nlmsvc_decode_##xargt, \ .pc_decode = (kxdrproc_t) nlmsvc_decode_##xargt, \
(kxdrproc_t) nlmsvc_encode_##xrest, \ .pc_encode = (kxdrproc_t) nlmsvc_encode_##xrest, \
NULL, \ .pc_release = NULL, \
sizeof(struct nlm_##argt), \ .pc_argsize = sizeof(struct nlm_##argt), \
sizeof(struct nlm_##rest), \ .pc_ressize = sizeof(struct nlm_##rest), \
0, \ .pc_xdrressize = respsize, \
0, \
respsize, \
} }
#define Ck (1+8) /* cookie */ #define Ck (1+8) /* cookie */
......
...@@ -294,15 +294,13 @@ nlmsvc_free_host_resources(struct nlm_host *host) ...@@ -294,15 +294,13 @@ nlmsvc_free_host_resources(struct nlm_host *host)
} }
/* /*
* Delete a client when the nfsd entry is removed. * delete all hosts structs for clients
*/ */
void void
nlmsvc_invalidate_client(struct svc_client *clnt) nlmsvc_invalidate_all(void)
{ {
struct nlm_host *host; struct nlm_host *host;
while ((host = nlm_find_client()) != NULL) {
if ((host = nlm_lookup_host(clnt, NULL, 0, 0)) != NULL) {
dprintk("lockd: invalidating client for %s\n", host->h_name);
nlmsvc_free_host_resources(host); nlmsvc_free_host_resources(host);
host->h_expires = 0; host->h_expires = 0;
host->h_killed = 1; host->h_killed = 1;
......
...@@ -369,6 +369,8 @@ nlmsvc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp) ...@@ -369,6 +369,8 @@ nlmsvc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp)
argp->state = ntohl(*p++); argp->state = ntohl(*p++);
/* Preserve the address in network byte order */ /* Preserve the address in network byte order */
argp->addr = *p++; argp->addr = *p++;
argp->vers = *p++;
argp->proto = *p++;
return xdr_argsize_check(rqstp, p); return xdr_argsize_check(rqstp, p);
} }
...@@ -602,15 +604,15 @@ static struct rpc_procinfo nlm_procedures[] = { ...@@ -602,15 +604,15 @@ static struct rpc_procinfo nlm_procedures[] = {
}; };
static struct rpc_version nlm_version1 = { static struct rpc_version nlm_version1 = {
number: 1, .number = 1,
nrprocs: 16, .nrprocs = 16,
procs: nlm_procedures, .procs = nlm_procedures,
}; };
static struct rpc_version nlm_version3 = { static struct rpc_version nlm_version3 = {
number: 3, .number = 3,
nrprocs: 24, .nrprocs = 24,
procs: nlm_procedures, .procs = nlm_procedures,
}; };
#ifdef CONFIG_LOCKD_V4 #ifdef CONFIG_LOCKD_V4
...@@ -618,23 +620,21 @@ extern struct rpc_version nlm_version4; ...@@ -618,23 +620,21 @@ extern struct rpc_version nlm_version4;
#endif #endif
static struct rpc_version * nlm_versions[] = { static struct rpc_version * nlm_versions[] = {
NULL, [1] = &nlm_version1,
&nlm_version1, [3] = &nlm_version3,
NULL,
&nlm_version3,
#ifdef CONFIG_LOCKD_V4 #ifdef CONFIG_LOCKD_V4
&nlm_version4, [4] = &nlm_version4,
#endif #endif
}; };
static struct rpc_stat nlm_stats; static struct rpc_stat nlm_stats;
struct rpc_program nlm_program = { struct rpc_program nlm_program = {
name: "lockd", .name = "lockd",
number: NLM_PROGRAM, .number = NLM_PROGRAM,
nrvers: sizeof(nlm_versions) / sizeof(nlm_versions[0]), .nrvers = sizeof(nlm_versions) / sizeof(nlm_versions[0]),
version: nlm_versions, .version = nlm_versions,
stats: &nlm_stats, .stats = &nlm_stats,
}; };
#ifdef LOCKD_DEBUG #ifdef LOCKD_DEBUG
......
...@@ -608,7 +608,7 @@ static struct rpc_procinfo nlm4_procedures[] = { ...@@ -608,7 +608,7 @@ static struct rpc_procinfo nlm4_procedures[] = {
}; };
struct rpc_version nlm_version4 = { struct rpc_version nlm_version4 = {
number: 4, .number = 4,
nrprocs: 24, .nrprocs = 24,
procs: nlm4_procedures, .procs = nlm4_procedures,
}; };
This diff is collapsed.
...@@ -31,12 +31,19 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file *filp) ...@@ -31,12 +31,19 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file *filp)
memcpy((char*)&fh.fh_handle.fh_base, f->data, f->size); memcpy((char*)&fh.fh_handle.fh_base, f->data, f->size);
fh.fh_export = NULL; fh.fh_export = NULL;
exp_readlock();
rqstp->rq_client = exp_getclient(&rqstp->rq_addr);
if (rqstp->rq_client == NULL)
nfserr = nfserr_stale;
else
nfserr = nfsd_open(rqstp, &fh, S_IFREG, MAY_LOCK, filp); nfserr = nfsd_open(rqstp, &fh, S_IFREG, MAY_LOCK, filp);
if (!nfserr) { if (!nfserr) {
dget(filp->f_dentry); dget(filp->f_dentry);
mntget(filp->f_vfsmnt); mntget(filp->f_vfsmnt);
} }
fh_put(&fh); fh_put(&fh);
rqstp->rq_client = NULL;
exp_readunlock();
/* nlm and nfsd don't share error codes. /* nlm and nfsd don't share error codes.
* we invent: 0 = no error * we invent: 0 = no error
* 1 = stale file handle * 1 = stale file handle
...@@ -61,24 +68,10 @@ nlm_fclose(struct file *filp) ...@@ -61,24 +68,10 @@ nlm_fclose(struct file *filp)
} }
struct nlmsvc_binding nfsd_nlm_ops = { struct nlmsvc_binding nfsd_nlm_ops = {
.exp_readlock = exp_readlock, /* lock export table for reading */
.exp_unlock = exp_readunlock, /* unlock export table */
.exp_getclient = exp_getclient, /* look up NFS client */
.fopen = nlm_fopen, /* open file for locking */ .fopen = nlm_fopen, /* open file for locking */
.fclose = nlm_fclose, /* close file */ .fclose = nlm_fclose, /* close file */
.detach = exp_nlmdetach, /* lockd shutdown notification */
}; };
/*
* When removing an NFS client entry, notify lockd that it is gone.
* FIXME: We should do the same when unexporting an NFS volume.
*/
void
nfsd_lockd_unexport(struct svc_client *clnt)
{
nlmsvc_invalidate_client(clnt);
}
void void
nfsd_lockd_init(void) nfsd_lockd_init(void)
{ {
......
...@@ -127,13 +127,30 @@ static struct file_operations reader_ops = { ...@@ -127,13 +127,30 @@ static struct file_operations reader_ops = {
extern struct seq_operations nfs_exports_op; extern struct seq_operations nfs_exports_op;
static int exports_open(struct inode *inode, struct file *file) static int exports_open(struct inode *inode, struct file *file)
{ {
return seq_open(file, &nfs_exports_op); int res;
res = seq_open(file, &nfs_exports_op);
if (!res) {
char *namebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (namebuf == NULL)
res = -ENOMEM;
else
((struct seq_file *)file->private_data)->private = namebuf;
}
return res;
} }
static int exports_release(struct inode *inode, struct file *file)
{
struct seq_file *m = (struct seq_file *)file->private_data;
kfree(m->private);
m->private = NULL;
return seq_release(inode, file);
}
static struct file_operations exports_operations = { static struct file_operations exports_operations = {
.open = exports_open, .open = exports_open,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = seq_release, .release = exports_release,
}; };
/* /*
......
...@@ -97,14 +97,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) ...@@ -97,14 +97,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
rqstp->rq_reffh = fh; rqstp->rq_reffh = fh;
if (!fhp->fh_dentry) { if (!fhp->fh_dentry) {
dev_t xdev = 0;
ino_t xino = 0;
__u32 *datap=NULL; __u32 *datap=NULL;
__u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */ __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */
int fileid_type; int fileid_type;
int data_left = fh->fh_size/4; int data_left = fh->fh_size/4;
int nfsdev;
int fsid = 0;
error = nfserr_stale; error = nfserr_stale;
if (rqstp->rq_vers > 2) if (rqstp->rq_vers > 2)
...@@ -113,6 +109,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) ...@@ -113,6 +109,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
return nfserr_nofilehandle; return nfserr_nofilehandle;
if (fh->fh_version == 1) { if (fh->fh_version == 1) {
int len;
datap = fh->fh_auth; datap = fh->fh_auth;
if (--data_left<0) goto out; if (--data_left<0) goto out;
switch (fh->fh_auth_type) { switch (fh->fh_auth_type) {
...@@ -122,39 +119,37 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) ...@@ -122,39 +119,37 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
switch (fh->fh_fsid_type) { switch (fh->fh_fsid_type) {
case 0: case 0:
if ((data_left-=2)<0) goto out; len = 2;
nfsdev = ntohl(*datap++);
xdev = MKDEV(nfsdev>>16, nfsdev&0xFFFF);
xino = *datap++;
break; break;
case 1: case 1:
if ((data_left-=1)<0) goto out; len = 1;
fsid = *datap++;
break; break;
default: default:
goto out; goto out;
} }
if ((data_left -= len)<0) goto out;
exp = exp_find(rqstp->rq_client, fh->fh_fsid_type, datap);
datap += len;
} else { } else {
dev_t xdev;
ino_t xino;
if (fh->fh_size != NFS_FHSIZE) if (fh->fh_size != NFS_FHSIZE)
goto out; goto out;
/* assume old filehandle format */ /* assume old filehandle format */
xdev = u32_to_dev_t(fh->ofh_xdev); xdev = u32_to_dev_t(fh->ofh_xdev);
xino = u32_to_ino_t(fh->ofh_xino); xino = u32_to_ino_t(fh->ofh_xino);
mk_fsid_v0(tfh, xdev, xino);
exp = exp_find(rqstp->rq_client, 0, tfh);
} }
/* /*
* Look up the export entry. * Look up the export entry.
*/ */
error = nfserr_stale; error = nfserr_stale;
if (fh->fh_version == 1 && fh->fh_fsid_type == 1)
exp = exp_get_fsid(rqstp->rq_client, fsid);
else
exp = exp_get(rqstp->rq_client, xdev, xino);
if (!exp) { if (!exp)
/* export entry revoked */ /* export entry revoked */
goto out; goto out;
}
/* Check if the request originated from a secure port. */ /* Check if the request originated from a secure port. */
error = nfserr_perm; error = nfserr_perm;
...@@ -322,9 +317,11 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st ...@@ -322,9 +317,11 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
struct inode * inode = dentry->d_inode; struct inode * inode = dentry->d_inode;
struct dentry *parent = dentry->d_parent; struct dentry *parent = dentry->d_parent;
__u32 *datap; __u32 *datap;
dev_t ex_dev = exp->ex_dentry->d_inode->i_sb->s_dev;
dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n", dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n",
MAJOR(exp->ex_dev), MINOR(exp->ex_dev), (long) exp->ex_ino, MAJOR(ex_dev), MINOR(ex_dev),
(long) exp->ex_dentry->d_inode->i_ino,
parent->d_name.name, dentry->d_name.name, parent->d_name.name, dentry->d_name.name,
(inode ? inode->i_ino : 0)); (inode ? inode->i_ino : 0));
...@@ -351,9 +348,9 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st ...@@ -351,9 +348,9 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE); memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE);
fhp->fh_handle.fh_size = NFS_FHSIZE; fhp->fh_handle.fh_size = NFS_FHSIZE;
fhp->fh_handle.ofh_dcookie = 0xfeebbaca; fhp->fh_handle.ofh_dcookie = 0xfeebbaca;
fhp->fh_handle.ofh_dev = htonl((MAJOR(exp->ex_dev)<<16)| MINOR(exp->ex_dev)); fhp->fh_handle.ofh_dev = htonl((MAJOR(ex_dev)<<16)| MINOR(ex_dev));
fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev; fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev;
fhp->fh_handle.ofh_xino = ino_t_to_u32(exp->ex_ino); fhp->fh_handle.ofh_xino = ino_t_to_u32(exp->ex_dentry->d_inode->i_ino);
fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry)); fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry));
if (inode) if (inode)
_fh_update_old(dentry, exp, &fhp->fh_handle); _fh_update_old(dentry, exp, &fhp->fh_handle);
...@@ -365,13 +362,14 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st ...@@ -365,13 +362,14 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
(ref_fh_fsid_type == 1)) { (ref_fh_fsid_type == 1)) {
fhp->fh_handle.fh_fsid_type = 1; fhp->fh_handle.fh_fsid_type = 1;
/* fsid_type 1 == 4 bytes filesystem id */ /* fsid_type 1 == 4 bytes filesystem id */
*datap++ = exp->ex_fsid; mk_fsid_v1(datap, exp->ex_fsid);
datap += 1;
fhp->fh_handle.fh_size = 2*4; fhp->fh_handle.fh_size = 2*4;
} else { } else {
fhp->fh_handle.fh_fsid_type = 0; fhp->fh_handle.fh_fsid_type = 0;
/* fsid_type 0 == 2byte major, 2byte minor, 4byte inode */ /* fsid_type 0 == 2byte major, 2byte minor, 4byte inode */
*datap++ = htonl((MAJOR(exp->ex_dev)<<16)| MINOR(exp->ex_dev)); mk_fsid_v0(datap, ex_dev, exp->ex_dentry->d_inode->i_ino);
*datap++ = ino_t_to_u32(exp->ex_ino); datap += 2;
fhp->fh_handle.fh_size = 3*4; fhp->fh_handle.fh_size = 3*4;
} }
if (inode) { if (inode) {
......
...@@ -119,24 +119,24 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, ...@@ -119,24 +119,24 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
else { else {
/* checking mountpoint crossing is very different when stepping up */ /* checking mountpoint crossing is very different when stepping up */
struct svc_export *exp2 = NULL; struct svc_export *exp2 = NULL;
struct dentry *dp, *old; struct dentry *dp;
struct vfsmount *mnt = mntget(exp->ex_mnt); struct vfsmount *mnt = mntget(exp->ex_mnt);
dentry = dget(dparent); dentry = dget(dparent);
while(follow_up(&mnt, &dentry)) while(follow_up(&mnt, &dentry))
; ;
old = dentry;
read_lock(&dparent_lock); read_lock(&dparent_lock);
dp = dentry->d_parent; dp = dget(dentry->d_parent);
for ( ; !exp2 && dp->d_parent != dp; dp=dp->d_parent) read_unlock(&dparent_lock);
exp2 = exp_get_by_name(exp->ex_client, mnt, dp); dput(dentry);
dentry = dp;
exp2 = exp_parent(exp->ex_client, mnt, dentry);
if (!exp2) { if (!exp2) {
dput(dentry);
dentry = dget(dparent); dentry = dget(dparent);
} else { } else {
dget(dentry->d_parent);
exp = exp2; exp = exp2;
} }
read_unlock(&dparent_lock);
dput(old);
mntput(mnt); mntput(mnt);
} }
} else { } else {
......
...@@ -19,14 +19,10 @@ struct svc_client; /* opaque type */ ...@@ -19,14 +19,10 @@ struct svc_client; /* opaque type */
* This is the set of functions for lockd->nfsd communication * This is the set of functions for lockd->nfsd communication
*/ */
struct nlmsvc_binding { struct nlmsvc_binding {
void (*exp_readlock)(void);
void (*exp_unlock)(void);
struct svc_client * (*exp_getclient)(struct sockaddr_in *);
u32 (*fopen)(struct svc_rqst *, u32 (*fopen)(struct svc_rqst *,
struct nfs_fh *, struct nfs_fh *,
struct file *); struct file *);
void (*fclose)(struct file *); void (*fclose)(struct file *);
void (*detach)(void);
}; };
extern struct nlmsvc_binding * nlmsvc_ops; extern struct nlmsvc_binding * nlmsvc_ops;
...@@ -34,7 +30,6 @@ extern struct nlmsvc_binding * nlmsvc_ops; ...@@ -34,7 +30,6 @@ extern struct nlmsvc_binding * nlmsvc_ops;
/* /*
* Functions exported by the lockd module * Functions exported by the lockd module
*/ */
extern void nlmsvc_invalidate_client(struct svc_client *clnt);
extern int nlmclnt_proc(struct inode *, int, struct file_lock *); extern int nlmclnt_proc(struct inode *, int, struct file_lock *);
extern int lockd_up(void); extern int lockd_up(void);
extern void lockd_down(void); extern void lockd_down(void);
......
...@@ -39,13 +39,13 @@ ...@@ -39,13 +39,13 @@
struct nlm_host { struct nlm_host {
struct nlm_host * h_next; /* linked list (hash table) */ struct nlm_host * h_next; /* linked list (hash table) */
struct sockaddr_in h_addr; /* peer address */ struct sockaddr_in h_addr; /* peer address */
struct svc_client * h_exportent; /* NFS client */
struct rpc_clnt * h_rpcclnt; /* RPC client to talk to peer */ struct rpc_clnt * h_rpcclnt; /* RPC client to talk to peer */
char h_name[20]; /* remote hostname */ char h_name[20]; /* remote hostname */
u32 h_version; /* interface version */ u32 h_version; /* interface version */
unsigned short h_proto; /* transport proto */ unsigned short h_proto; /* transport proto */
unsigned short h_authflavor; /* RPC authentication type */ unsigned short h_authflavor; /* RPC authentication type */
unsigned short h_reclaiming : 1, unsigned short h_reclaiming : 1,
h_server : 1, /* server side, not client side */
h_inuse : 1, h_inuse : 1,
h_killed : 1, h_killed : 1,
h_monitored : 1; h_monitored : 1;
...@@ -143,13 +143,14 @@ void nlmclnt_freegrantargs(struct nlm_rqst *); ...@@ -143,13 +143,14 @@ void nlmclnt_freegrantargs(struct nlm_rqst *);
*/ */
struct nlm_host * nlmclnt_lookup_host(struct sockaddr_in *, int, int); struct nlm_host * nlmclnt_lookup_host(struct sockaddr_in *, int, int);
struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *); struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *);
struct nlm_host * nlm_lookup_host(struct svc_client *, struct nlm_host * nlm_lookup_host(int server, struct sockaddr_in *, int, int);
struct sockaddr_in *, int, int);
struct rpc_clnt * nlm_bind_host(struct nlm_host *); struct rpc_clnt * nlm_bind_host(struct nlm_host *);
void nlm_rebind_host(struct nlm_host *); void nlm_rebind_host(struct nlm_host *);
struct nlm_host * nlm_get_host(struct nlm_host *); struct nlm_host * nlm_get_host(struct nlm_host *);
void nlm_release_host(struct nlm_host *); void nlm_release_host(struct nlm_host *);
void nlm_shutdown_hosts(void); void nlm_shutdown_hosts(void);
extern struct nlm_host *nlm_find_client(void);
/* /*
* Server-side lock handling * Server-side lock handling
...@@ -173,6 +174,7 @@ u32 nlm_lookup_file(struct svc_rqst *, struct nlm_file **, ...@@ -173,6 +174,7 @@ u32 nlm_lookup_file(struct svc_rqst *, struct nlm_file **,
void nlm_release_file(struct nlm_file *); void nlm_release_file(struct nlm_file *);
void nlmsvc_mark_resources(void); void nlmsvc_mark_resources(void);
void nlmsvc_free_host_resources(struct nlm_host *); void nlmsvc_free_host_resources(struct nlm_host *);
void nlmsvc_invalidate_all(void);
static __inline__ struct inode * static __inline__ struct inode *
nlmsvc_file_inode(struct nlm_file *file) nlmsvc_file_inode(struct nlm_file *file)
......
...@@ -28,6 +28,7 @@ struct nsm_args { ...@@ -28,6 +28,7 @@ struct nsm_args {
u32 prog; /* RPC callback info */ u32 prog; /* RPC callback info */
u32 vers; u32 vers;
u32 proc; u32 proc;
u32 proto; /* protocol (udp/tcp) plus server/client flag */
}; };
/* /*
......
...@@ -76,6 +76,8 @@ struct nlm_reboot { ...@@ -76,6 +76,8 @@ struct nlm_reboot {
int len; int len;
u32 state; u32 state;
u32 addr; u32 addr;
u32 vers;
u32 proto;
}; };
/* /*
......
...@@ -23,23 +23,5 @@ ...@@ -23,23 +23,5 @@
*/ */
void nfsd_setuser(struct svc_rqst *, struct svc_export *); void nfsd_setuser(struct svc_rqst *, struct svc_export *);
#if 0
/*
* These must match the actual size of uid_t and gid_t
*/
#define UGID_BITS (8 * sizeof(uid_t))
#define UGID_SHIFT 8
#define UGID_MASK ((1 << UGID_SHIFT) - 1)
#define UGID_NRENTRIES ((1 << (UGID_BITS - UGID_SHIFT)) + 1)
#define UGID_NONE ((unsigned short)-1)
typedef struct svc_uidmap {
uid_t * um_ruid[UGID_NRENTRIES];
uid_t * um_luid[UGID_NRENTRIES];
gid_t * um_rgid[UGID_NRENTRIES];
gid_t * um_lgid[UGID_NRENTRIES];
} svc_uidmap;
#endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* LINUX_NFSD_AUTH_H */ #endif /* LINUX_NFSD_AUTH_H */
...@@ -45,38 +45,36 @@ ...@@ -45,38 +45,36 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
/* The following are hashtable sizes and must be powers of 2 */
#define NFSCLNT_EXPMAX 16
struct svc_client { struct svc_client {
struct svc_client * cl_next; struct svc_client * cl_next;
char cl_ident[NFSCLNT_IDMAX]; char cl_ident[NFSCLNT_IDMAX];
int cl_idlen;
int cl_naddr;
struct in_addr cl_addr[NFSCLNT_ADDRMAX];
struct svc_uidmap * cl_umap;
struct list_head cl_export[NFSCLNT_EXPMAX];
struct list_head cl_expfsid[NFSCLNT_EXPMAX];
struct list_head cl_list;
}; };
struct svc_export { struct svc_export {
struct list_head ex_hash; struct list_head ex_hash;
struct list_head ex_fsid_hash;
struct list_head ex_list;
char ex_path[NFS_MAXPATHLEN+1];
struct svc_export * ex_parent;
struct svc_client * ex_client; struct svc_client * ex_client;
int ex_flags; int ex_flags;
struct vfsmount * ex_mnt; struct vfsmount * ex_mnt;
struct dentry * ex_dentry; struct dentry * ex_dentry;
dev_t ex_dev;
ino_t ex_ino;
uid_t ex_anon_uid; uid_t ex_anon_uid;
gid_t ex_anon_gid; gid_t ex_anon_gid;
int ex_fsid; int ex_fsid;
}; };
/* an "export key" (expkey) maps a filehandlefragement to an
* svc_export for a given client. There can be two per export, one
* for type 0 (dev/ino), one for type 1 (fsid)
*/
struct svc_expkey {
struct list_head ek_hash;
struct svc_client *ek_client;
int ek_fsidtype;
u32 ek_fsid[2];
struct svc_export *ek_export;
};
#define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT)) #define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT))
#define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC)) #define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
#define EX_RDONLY(exp) ((exp)->ex_flags & NFSEXP_READONLY) #define EX_RDONLY(exp) ((exp)->ex_flags & NFSEXP_READONLY)
...@@ -94,16 +92,25 @@ void exp_readlock(void); ...@@ -94,16 +92,25 @@ void exp_readlock(void);
void exp_readunlock(void); void exp_readunlock(void);
struct svc_client * exp_getclient(struct sockaddr_in *sin); struct svc_client * exp_getclient(struct sockaddr_in *sin);
void exp_putclient(struct svc_client *clp); void exp_putclient(struct svc_client *clp);
struct svc_export * exp_get(struct svc_client *clp, dev_t dev, ino_t ino); struct svc_expkey * exp_find_key(struct svc_client *clp, int fsid_type, u32 *fsidv);
struct svc_export * exp_get_fsid(struct svc_client *clp, int fsid);
struct svc_export * exp_get_by_name(struct svc_client *clp, struct svc_export * exp_get_by_name(struct svc_client *clp,
struct vfsmount *mnt, struct vfsmount *mnt,
struct dentry *dentry); struct dentry *dentry);
struct svc_export * exp_parent(struct svc_client *clp, struct vfsmount *mnt,
struct dentry *dentry);
int exp_rootfh(struct svc_client *, int exp_rootfh(struct svc_client *,
char *path, struct knfsd_fh *, int maxsize); char *path, struct knfsd_fh *, int maxsize);
int nfserrno(int errno); int nfserrno(int errno);
void exp_nlmdetach(void);
static inline struct svc_export *
exp_find(struct svc_client *clp, int fsid_type, u32 *fsidv)
{
struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv);
if (ek)
return ek->ek_export;
else
return NULL;
}
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -199,6 +199,19 @@ typedef struct svc_fh { ...@@ -199,6 +199,19 @@ typedef struct svc_fh {
} svc_fh; } svc_fh;
static inline void mk_fsid_v0(u32 *fsidv, dev_t dev, ino_t ino)
{
fsidv[0] = htonl((MAJOR(dev)<<16) |
MINOR(dev));
fsidv[1] = ino_t_to_u32(ino);
}
static inline void mk_fsid_v1(u32 *fsidv, u32 fsid)
{
fsidv[0] = fsid;
}
/* /*
* Shorthand for dprintk()'s * Shorthand for dprintk()'s
*/ */
......
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