Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f90933c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

* 'for-2.6.37' of git://linux-nfs.org/~bfields/linux:
  locks: remove dead lease error-handling code
  locks: fix leak on merging leases
  nfsd4: fix 4.1 connection registration race
parents e2b34835 8896b93f
Loading
Loading
Loading
Loading
+7 −12
Original line number Original line Diff line number Diff line
@@ -1504,9 +1504,8 @@ static int do_fcntl_delete_lease(struct file *filp)


static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
{
{
	struct file_lock *fl;
	struct file_lock *fl, *ret;
	struct fasync_struct *new;
	struct fasync_struct *new;
	struct inode *inode = filp->f_path.dentry->d_inode;
	int error;
	int error;


	fl = lease_alloc(filp, arg);
	fl = lease_alloc(filp, arg);
@@ -1518,13 +1517,16 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
		locks_free_lock(fl);
		locks_free_lock(fl);
		return -ENOMEM;
		return -ENOMEM;
	}
	}
	ret = fl;
	lock_flocks();
	lock_flocks();
	error = __vfs_setlease(filp, arg, &fl);
	error = __vfs_setlease(filp, arg, &ret);
	if (error) {
	if (error) {
		unlock_flocks();
		unlock_flocks();
		locks_free_lock(fl);
		locks_free_lock(fl);
		goto out_free_fasync;
		goto out_free_fasync;
	}
	}
	if (ret != fl)
		locks_free_lock(fl);


	/*
	/*
	 * fasync_insert_entry() returns the old entry if any.
	 * fasync_insert_entry() returns the old entry if any.
@@ -1532,17 +1534,10 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
	 * inserted it into the fasync list. Clear new so that
	 * inserted it into the fasync list. Clear new so that
	 * we don't release it here.
	 * we don't release it here.
	 */
	 */
	if (!fasync_insert_entry(fd, filp, &fl->fl_fasync, new))
	if (!fasync_insert_entry(fd, filp, &ret->fl_fasync, new))
		new = NULL;
		new = NULL;


	if (error < 0) {
		/* remove lease just inserted by setlease */
		fl->fl_type = F_UNLCK | F_INPROGRESS;
		fl->fl_break_time = jiffies - 10;
		time_out_leases(inode);
	} else {
	error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
	error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
	}
	unlock_flocks();
	unlock_flocks();


out_free_fasync:
out_free_fasync:
+12 −4
Original line number Original line Diff line number Diff line
@@ -673,16 +673,17 @@ static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses)
	spin_unlock(&clp->cl_lock);
	spin_unlock(&clp->cl_lock);
}
}


static void nfsd4_register_conn(struct nfsd4_conn *conn)
static int nfsd4_register_conn(struct nfsd4_conn *conn)
{
{
	conn->cn_xpt_user.callback = nfsd4_conn_lost;
	conn->cn_xpt_user.callback = nfsd4_conn_lost;
	register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
	return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
}
}


static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
{
{
	struct nfsd4_conn *conn;
	struct nfsd4_conn *conn;
	u32 flags = NFS4_CDFC4_FORE;
	u32 flags = NFS4_CDFC4_FORE;
	int ret;


	if (ses->se_flags & SESSION4_BACK_CHAN)
	if (ses->se_flags & SESSION4_BACK_CHAN)
		flags |= NFS4_CDFC4_BACK;
		flags |= NFS4_CDFC4_BACK;
@@ -690,7 +691,10 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
	if (!conn)
	if (!conn)
		return nfserr_jukebox;
		return nfserr_jukebox;
	nfsd4_hash_conn(conn, ses);
	nfsd4_hash_conn(conn, ses);
	nfsd4_register_conn(conn);
	ret = nfsd4_register_conn(conn);
	if (ret)
		/* oops; xprt is already down: */
		nfsd4_conn_lost(&conn->cn_xpt_user);
	return nfs_ok;
	return nfs_ok;
}
}


@@ -1644,6 +1648,7 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi
{
{
	struct nfs4_client *clp = ses->se_client;
	struct nfs4_client *clp = ses->se_client;
	struct nfsd4_conn *c;
	struct nfsd4_conn *c;
	int ret;


	spin_lock(&clp->cl_lock);
	spin_lock(&clp->cl_lock);
	c = __nfsd4_find_conn(new->cn_xprt, ses);
	c = __nfsd4_find_conn(new->cn_xprt, ses);
@@ -1654,7 +1659,10 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi
	}
	}
	__nfsd4_hash_conn(new, ses);
	__nfsd4_hash_conn(new, ses);
	spin_unlock(&clp->cl_lock);
	spin_unlock(&clp->cl_lock);
	nfsd4_register_conn(new);
	ret = nfsd4_register_conn(new);
	if (ret)
		/* oops; xprt is already down: */
		nfsd4_conn_lost(&new->cn_xpt_user);
	return;
	return;
}
}


+14 −4
Original line number Original line Diff line number Diff line
@@ -82,18 +82,28 @@ struct svc_xprt {
	struct net		*xpt_net;
	struct net		*xpt_net;
};
};


static inline void register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
{
{
	spin_lock(&xpt->xpt_lock);
	spin_lock(&xpt->xpt_lock);
	list_add(&u->list, &xpt->xpt_users);
	list_del_init(&u->list);
	spin_unlock(&xpt->xpt_lock);
	spin_unlock(&xpt->xpt_lock);
}
}


static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
static inline int register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
{
{
	spin_lock(&xpt->xpt_lock);
	spin_lock(&xpt->xpt_lock);
	list_del_init(&u->list);
	if (test_bit(XPT_CLOSE, &xpt->xpt_flags)) {
		/*
		 * The connection is about to be deleted soon (or,
		 * worse, may already be deleted--in which case we've
		 * already notified the xpt_users).
		 */
		spin_unlock(&xpt->xpt_lock);
		spin_unlock(&xpt->xpt_lock);
		return -ENOTCONN;
	}
	list_add(&u->list, &xpt->xpt_users);
	spin_unlock(&xpt->xpt_lock);
	return 0;
}
}


int	svc_reg_xprt_class(struct svc_xprt_class *);
int	svc_reg_xprt_class(struct svc_xprt_class *);