diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 09:02:13 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 09:02:13 -0800 | 
| commit | 2608e3d0fa63b892f37a9f1921c2d2b37c7933c1 (patch) | |
| tree | aca8b61fd63390edf5ddfe17b8ae35dfd56ed74d | |
| parent | 33673dcb372b5d8179c22127ca71deb5f3dc7016 (diff) | |
| parent | b6f4bee02f682d1c86ece297871b78ae01afaaf4 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
Pull v9fs updates from Eric Van Hensbergen:
 "Just fixes and simplifications"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
  fs/9p: Fix atomic_open
  fs/9p: Don't use O_TRUNC flag in TOPEN and TLOPEN request
  locking in fs/9p ->readdir()
| -rw-r--r-- | fs/9p/vfs_dir.c | 92 | ||||
| -rw-r--r-- | fs/9p/vfs_file.c | 4 | ||||
| -rw-r--r-- | fs/9p/vfs_inode.c | 3 | ||||
| -rw-r--r-- | fs/9p/vfs_inode_dotl.c | 11 | 
4 files changed, 31 insertions, 79 deletions
| diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index ff911e779651..be1e34adc3c6 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -52,10 +52,9 @@   */  struct p9_rdir { -	struct mutex mutex;  	int head;  	int tail; -	uint8_t *buf; +	uint8_t buf[];  };  /** @@ -93,33 +92,12 @@ static void p9stat_init(struct p9_wstat *stbuf)   *   */ -static int v9fs_alloc_rdir_buf(struct file *filp, int buflen) +static struct p9_rdir *v9fs_alloc_rdir_buf(struct file *filp, int buflen)  { -	struct p9_rdir *rdir; -	struct p9_fid *fid; -	int err = 0; - -	fid = filp->private_data; -	if (!fid->rdir) { -		rdir = kmalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL); - -		if (rdir == NULL) { -			err = -ENOMEM; -			goto exit; -		} -		spin_lock(&filp->f_dentry->d_lock); -		if (!fid->rdir) { -			rdir->buf = (uint8_t *)rdir + sizeof(struct p9_rdir); -			mutex_init(&rdir->mutex); -			rdir->head = rdir->tail = 0; -			fid->rdir = (void *) rdir; -			rdir = NULL; -		} -		spin_unlock(&filp->f_dentry->d_lock); -		kfree(rdir); -	} -exit: -	return err; +	struct p9_fid *fid = filp->private_data; +	if (!fid->rdir) +		fid->rdir = kzalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL); +	return fid->rdir;  }  /** @@ -145,20 +123,16 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)  	buflen = fid->clnt->msize - P9_IOHDRSZ; -	err = v9fs_alloc_rdir_buf(filp, buflen); -	if (err) -		goto exit; -	rdir = (struct p9_rdir *) fid->rdir; +	rdir = v9fs_alloc_rdir_buf(filp, buflen); +	if (!rdir) +		return -ENOMEM; -	err = mutex_lock_interruptible(&rdir->mutex); -	if (err) -		return err; -	while (err == 0) { +	while (1) {  		if (rdir->tail == rdir->head) {  			err = v9fs_file_readn(filp, rdir->buf, NULL,  							buflen, filp->f_pos);  			if (err <= 0) -				goto unlock_and_exit; +				return err;  			rdir->head = 0;  			rdir->tail = err; @@ -169,9 +143,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)  					  rdir->tail - rdir->head, &st);  			if (err) {  				p9_debug(P9_DEBUG_VFS, "returned %d\n", err); -				err = -EIO;  				p9stat_free(&st); -				goto unlock_and_exit; +				return -EIO;  			}  			reclen = st.size+2; @@ -180,19 +153,13 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)  			p9stat_free(&st); -			if (over) { -				err = 0; -				goto unlock_and_exit; -			} +			if (over) +				return 0; +  			rdir->head += reclen;  			filp->f_pos += reclen;  		}  	} - -unlock_and_exit: -	mutex_unlock(&rdir->mutex); -exit: -	return err;  }  /** @@ -218,21 +185,16 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,  	buflen = fid->clnt->msize - P9_READDIRHDRSZ; -	err = v9fs_alloc_rdir_buf(filp, buflen); -	if (err) -		goto exit; -	rdir = (struct p9_rdir *) fid->rdir; +	rdir = v9fs_alloc_rdir_buf(filp, buflen); +	if (!rdir) +		return -ENOMEM; -	err = mutex_lock_interruptible(&rdir->mutex); -	if (err) -		return err; - -	while (err == 0) { +	while (1) {  		if (rdir->tail == rdir->head) {  			err = p9_client_readdir(fid, rdir->buf, buflen,  						filp->f_pos);  			if (err <= 0) -				goto unlock_and_exit; +				return err;  			rdir->head = 0;  			rdir->tail = err; @@ -245,8 +207,7 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,  					    &curdirent);  			if (err < 0) {  				p9_debug(P9_DEBUG_VFS, "returned %d\n", err); -				err = -EIO; -				goto unlock_and_exit; +				return -EIO;  			}  			/* d_off in dirent structure tracks the offset into @@ -261,20 +222,13 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,  					curdirent.d_type);  			oldoffset = curdirent.d_off; -			if (over) { -				err = 0; -				goto unlock_and_exit; -			} +			if (over) +				return 0;  			filp->f_pos = curdirent.d_off;  			rdir->head += err;  		}  	} - -unlock_and_exit: -	mutex_unlock(&rdir->mutex); -exit: -	return err;  } diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index c2483e97beee..7a3399767570 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -80,10 +80,6 @@ int v9fs_file_open(struct inode *inode, struct file *file)  			p9_client_clunk(fid);  			return err;  		} -		if (file->f_flags & O_TRUNC) { -			i_size_write(inode, 0); -			inode->i_blocks = 0; -		}  		if ((file->f_flags & O_APPEND) &&  			(!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)))  			generic_file_llseek(file, 0, SEEK_END); diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 890bed538f9b..57d017ac68e4 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -192,9 +192,6 @@ int v9fs_uflags2omode(int uflags, int extended)  		break;  	} -	if (uflags & O_TRUNC) -		ret |= P9_OTRUNC; -  	if (extended) {  		if (uflags & O_EXCL)  			ret |= P9_OEXCL; diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 40895546e103..8d24ad66dfb8 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -186,7 +186,6 @@ static int v9fs_mapped_dotl_flags(int flags)  		{ O_CREAT,	P9_DOTL_CREATE },  		{ O_EXCL,	P9_DOTL_EXCL },  		{ O_NOCTTY,	P9_DOTL_NOCTTY }, -		{ O_TRUNC,	P9_DOTL_TRUNC },  		{ O_APPEND,	P9_DOTL_APPEND },  		{ O_NONBLOCK,	P9_DOTL_NONBLOCK },  		{ O_DSYNC,	P9_DOTL_DSYNC }, @@ -268,8 +267,14 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,  	}  	/* Only creates */ -	if (!(flags & O_CREAT) || dentry->d_inode) -		return finish_no_open(file, res); +	if (!(flags & O_CREAT)) +		return	finish_no_open(file, res); +	else if (dentry->d_inode) { +		if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) +			return -EEXIST; +		else +			return finish_no_open(file, res); +	}  	v9ses = v9fs_inode2v9ses(dir); | 
