aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_ioctl.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2009-02-08 15:51:14 -0500
committerChristoph Hellwig <hch@brick.lst.de>2009-02-08 15:51:14 -0500
commit4346cdd4647e5eef15817dbfc2c091cac55e33d9 (patch)
tree36dd9ea7127149bb7f3f80d4e36c7a48fec9c9ba /fs/xfs/linux-2.6/xfs_ioctl.c
parentef8f7fc549bf345d92f396f5aa7b152b4969cbf7 (diff)
xfs: cleanup xfs_find_handle
Remove the superflous igrab by keeping a reference on the path/file all the time and clean up various bits of surrounding code. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Felix Blyakher <felixb@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_ioctl.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c106
1 files changed, 44 insertions, 62 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 4bd112313f33..6f04493b8aba 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -78,92 +78,74 @@ xfs_find_handle(
78 int hsize; 78 int hsize;
79 xfs_handle_t handle; 79 xfs_handle_t handle;
80 struct inode *inode; 80 struct inode *inode;
81 struct file *file = NULL;
82 struct path path;
83 int error;
84 struct xfs_inode *ip;
81 85
82 memset((char *)&handle, 0, sizeof(handle)); 86 if (cmd == XFS_IOC_FD_TO_HANDLE) {
83 87 file = fget(hreq->fd);
84 switch (cmd) { 88 if (!file)
85 case XFS_IOC_PATH_TO_FSHANDLE: 89 return -EBADF;
86 case XFS_IOC_PATH_TO_HANDLE: { 90 inode = file->f_path.dentry->d_inode;
87 struct path path; 91 } else {
88 int error = user_lpath((const char __user *)hreq->path, &path); 92 error = user_lpath((const char __user *)hreq->path, &path);
89 if (error) 93 if (error)
90 return error; 94 return error;
91 95 inode = path.dentry->d_inode;
92 ASSERT(path.dentry);
93 ASSERT(path.dentry->d_inode);
94 inode = igrab(path.dentry->d_inode);
95 path_put(&path);
96 break;
97 } 96 }
97 ip = XFS_I(inode);
98 98
99 case XFS_IOC_FD_TO_HANDLE: { 99 /*
100 struct file *file; 100 * We can only generate handles for inodes residing on a XFS filesystem,
101 101 * and only for regular files, directories or symbolic links.
102 file = fget(hreq->fd); 102 */
103 if (!file) 103 error = -EINVAL;
104 return -EBADF; 104 if (inode->i_sb->s_magic != XFS_SB_MAGIC)
105 goto out_put;
105 106
106 ASSERT(file->f_path.dentry); 107 error = -EBADF;
107 ASSERT(file->f_path.dentry->d_inode); 108 if (!S_ISREG(inode->i_mode) &&
108 inode = igrab(file->f_path.dentry->d_inode); 109 !S_ISDIR(inode->i_mode) &&
109 fput(file); 110 !S_ISLNK(inode->i_mode))
110 break; 111 goto out_put;
111 }
112 112
113 default:
114 ASSERT(0);
115 return -XFS_ERROR(EINVAL);
116 }
117 113
118 if (inode->i_sb->s_magic != XFS_SB_MAGIC) { 114 memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
119 /* we're not in XFS anymore, Toto */
120 iput(inode);
121 return -XFS_ERROR(EINVAL);
122 }
123 115
124 switch (inode->i_mode & S_IFMT) { 116 if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
125 case S_IFREG: 117 /*
126 case S_IFDIR: 118 * This handle only contains an fsid, zero the rest.
127 case S_IFLNK: 119 */
128 break; 120 memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
129 default: 121 hsize = sizeof(xfs_fsid_t);
130 iput(inode); 122 } else {
131 return -XFS_ERROR(EBADF);
132 }
133
134 /* now we can grab the fsid */
135 memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid,
136 sizeof(xfs_fsid_t));
137 hsize = sizeof(xfs_fsid_t);
138
139 if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
140 xfs_inode_t *ip = XFS_I(inode);
141 int lock_mode; 123 int lock_mode;
142 124
143 /* need to get access to the xfs_inode to read the generation */
144 lock_mode = xfs_ilock_map_shared(ip); 125 lock_mode = xfs_ilock_map_shared(ip);
145
146 /* fill in fid section of handle from inode */
147 handle.ha_fid.fid_len = sizeof(xfs_fid_t) - 126 handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
148 sizeof(handle.ha_fid.fid_len); 127 sizeof(handle.ha_fid.fid_len);
149 handle.ha_fid.fid_pad = 0; 128 handle.ha_fid.fid_pad = 0;
150 handle.ha_fid.fid_gen = ip->i_d.di_gen; 129 handle.ha_fid.fid_gen = ip->i_d.di_gen;
151 handle.ha_fid.fid_ino = ip->i_ino; 130 handle.ha_fid.fid_ino = ip->i_ino;
152
153 xfs_iunlock_map_shared(ip, lock_mode); 131 xfs_iunlock_map_shared(ip, lock_mode);
154 132
155 hsize = XFS_HSIZE(handle); 133 hsize = XFS_HSIZE(handle);
156 } 134 }
157 135
158 /* now copy our handle into the user buffer & write out the size */ 136 error = -EFAULT;
159 if (copy_to_user(hreq->ohandle, &handle, hsize) || 137 if (copy_to_user(hreq->ohandle, &handle, hsize) ||
160 copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) { 138 copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
161 iput(inode); 139 goto out_put;
162 return -XFS_ERROR(EFAULT);
163 }
164 140
165 iput(inode); 141 error = 0;
166 return 0; 142
143 out_put:
144 if (cmd == XFS_IOC_FD_TO_HANDLE)
145 fput(file);
146 else
147 path_put(&path);
148 return error;
167} 149}
168 150
169/* 151/*