aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iops.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-08-12 06:50:09 -0400
committerBen Myers <bpm@sgi.com>2013-08-22 09:40:24 -0400
commit0cb97766f2928579f1029ea7b28ae946cdd6fbe1 (patch)
tree4e64fcd122c5b3ddda050e23efc940eaaea4bb9c /fs/xfs/xfs_iops.c
parented56f34f11da4f491680cd39482fd533134fd589 (diff)
xfs: Add read-only support for dirent filetype field
Add support for the file type field in directory entries so that readdir can return the type of the inode the dirent points to to userspace without first having to read the inode off disk. The encoding of the type field is a single byte that is added to the end of the directory entry name length. For all intents and purposes, it appends a "hidden" byte to the name field which contains the type information. As the directory entry is already of dynamic size, helpers are already required to access and decode the direct entry structures. Hence the relevent extraction and iteration helpers are updated to understand the hidden byte. Helpers for reading and writing the filetype field from the directory entries are also added. Only the read helpers are used by this patch. It also adds all the code necessary to read the type information out of the dirents on disk. Further we add the superblock feature bit and helpers to indicate that we understand the on-disk format change. This is not a compatible change - existing kernels cannot read the new format successfully - so an incompatible feature flag is added. We don't yet allow filesystems to mount with this flag yet - that will be added once write support is added. Finally, the code to take the type from the VFS, convert it to an XFS on-disk type and put it into the xfs_name structures passed around is added, but the directory code does not use this field yet. That will be in the next patch. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_iops.c')
-rw-r--r--fs/xfs/xfs_iops.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 6d7e9e2d7651..2b8952d9199b 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -40,6 +40,9 @@
40#include "xfs_trace.h" 40#include "xfs_trace.h"
41#include "xfs_icache.h" 41#include "xfs_icache.h"
42#include "xfs_symlink.h" 42#include "xfs_symlink.h"
43#include "xfs_da_btree.h"
44#include "xfs_dir2_format.h"
45#include "xfs_dir2_priv.h"
43 46
44#include <linux/capability.h> 47#include <linux/capability.h>
45#include <linux/xattr.h> 48#include <linux/xattr.h>
@@ -88,10 +91,12 @@ xfs_init_security(
88static void 91static void
89xfs_dentry_to_name( 92xfs_dentry_to_name(
90 struct xfs_name *namep, 93 struct xfs_name *namep,
91 struct dentry *dentry) 94 struct dentry *dentry,
95 int mode)
92{ 96{
93 namep->name = dentry->d_name.name; 97 namep->name = dentry->d_name.name;
94 namep->len = dentry->d_name.len; 98 namep->len = dentry->d_name.len;
99 namep->type = xfs_mode_to_ftype[(mode & S_IFMT) >> S_SHIFT];
95} 100}
96 101
97STATIC void 102STATIC void
@@ -107,7 +112,7 @@ xfs_cleanup_inode(
107 * xfs_init_security we must back out. 112 * xfs_init_security we must back out.
108 * ENOSPC can hit here, among other things. 113 * ENOSPC can hit here, among other things.
109 */ 114 */
110 xfs_dentry_to_name(&teardown, dentry); 115 xfs_dentry_to_name(&teardown, dentry, 0);
111 116
112 xfs_remove(XFS_I(dir), &teardown, XFS_I(inode)); 117 xfs_remove(XFS_I(dir), &teardown, XFS_I(inode));
113 iput(inode); 118 iput(inode);
@@ -147,7 +152,7 @@ xfs_vn_mknod(
147 mode &= ~current_umask(); 152 mode &= ~current_umask();
148 } 153 }
149 154
150 xfs_dentry_to_name(&name, dentry); 155 xfs_dentry_to_name(&name, dentry, mode);
151 error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); 156 error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
152 if (unlikely(error)) 157 if (unlikely(error))
153 goto out_free_acl; 158 goto out_free_acl;
@@ -208,7 +213,7 @@ xfs_vn_lookup(
208 if (dentry->d_name.len >= MAXNAMELEN) 213 if (dentry->d_name.len >= MAXNAMELEN)
209 return ERR_PTR(-ENAMETOOLONG); 214 return ERR_PTR(-ENAMETOOLONG);
210 215
211 xfs_dentry_to_name(&name, dentry); 216 xfs_dentry_to_name(&name, dentry, 0);
212 error = xfs_lookup(XFS_I(dir), &name, &cip, NULL); 217 error = xfs_lookup(XFS_I(dir), &name, &cip, NULL);
213 if (unlikely(error)) { 218 if (unlikely(error)) {
214 if (unlikely(error != ENOENT)) 219 if (unlikely(error != ENOENT))
@@ -235,7 +240,7 @@ xfs_vn_ci_lookup(
235 if (dentry->d_name.len >= MAXNAMELEN) 240 if (dentry->d_name.len >= MAXNAMELEN)
236 return ERR_PTR(-ENAMETOOLONG); 241 return ERR_PTR(-ENAMETOOLONG);
237 242
238 xfs_dentry_to_name(&xname, dentry); 243 xfs_dentry_to_name(&xname, dentry, 0);
239 error = xfs_lookup(XFS_I(dir), &xname, &ip, &ci_name); 244 error = xfs_lookup(XFS_I(dir), &xname, &ip, &ci_name);
240 if (unlikely(error)) { 245 if (unlikely(error)) {
241 if (unlikely(error != ENOENT)) 246 if (unlikely(error != ENOENT))
@@ -270,7 +275,7 @@ xfs_vn_link(
270 struct xfs_name name; 275 struct xfs_name name;
271 int error; 276 int error;
272 277
273 xfs_dentry_to_name(&name, dentry); 278 xfs_dentry_to_name(&name, dentry, inode->i_mode);
274 279
275 error = xfs_link(XFS_I(dir), XFS_I(inode), &name); 280 error = xfs_link(XFS_I(dir), XFS_I(inode), &name);
276 if (unlikely(error)) 281 if (unlikely(error))
@@ -289,7 +294,7 @@ xfs_vn_unlink(
289 struct xfs_name name; 294 struct xfs_name name;
290 int error; 295 int error;
291 296
292 xfs_dentry_to_name(&name, dentry); 297 xfs_dentry_to_name(&name, dentry, 0);
293 298
294 error = -xfs_remove(XFS_I(dir), &name, XFS_I(dentry->d_inode)); 299 error = -xfs_remove(XFS_I(dir), &name, XFS_I(dentry->d_inode));
295 if (error) 300 if (error)
@@ -319,7 +324,7 @@ xfs_vn_symlink(
319 324
320 mode = S_IFLNK | 325 mode = S_IFLNK |
321 (irix_symlink_mode ? 0777 & ~current_umask() : S_IRWXUGO); 326 (irix_symlink_mode ? 0777 & ~current_umask() : S_IRWXUGO);
322 xfs_dentry_to_name(&name, dentry); 327 xfs_dentry_to_name(&name, dentry, mode);
323 328
324 error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip); 329 error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip);
325 if (unlikely(error)) 330 if (unlikely(error))
@@ -351,12 +356,12 @@ xfs_vn_rename(
351 struct xfs_name oname; 356 struct xfs_name oname;
352 struct xfs_name nname; 357 struct xfs_name nname;
353 358
354 xfs_dentry_to_name(&oname, odentry); 359 xfs_dentry_to_name(&oname, odentry, 0);
355 xfs_dentry_to_name(&nname, ndentry); 360 xfs_dentry_to_name(&nname, ndentry, odentry->d_inode->i_mode);
356 361
357 return -xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode), 362 return -xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode),
358 XFS_I(ndir), &nname, new_inode ? 363 XFS_I(ndir), &nname, new_inode ?
359 XFS_I(new_inode) : NULL); 364 XFS_I(new_inode) : NULL);
360} 365}
361 366
362/* 367/*