aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/libfs.c96
-rw-r--r--include/linux/fs.h2
2 files changed, 98 insertions, 0 deletions
diff --git a/fs/libfs.c b/fs/libfs.c
index cb1fb4b9b637..02813592e121 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1093,3 +1093,99 @@ simple_nosetlease(struct file *filp, long arg, struct file_lock **flp,
1093 return -EINVAL; 1093 return -EINVAL;
1094} 1094}
1095EXPORT_SYMBOL(simple_nosetlease); 1095EXPORT_SYMBOL(simple_nosetlease);
1096
1097
1098/*
1099 * Operations for a permanently empty directory.
1100 */
1101static struct dentry *empty_dir_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
1102{
1103 return ERR_PTR(-ENOENT);
1104}
1105
1106static int empty_dir_getattr(struct vfsmount *mnt, struct dentry *dentry,
1107 struct kstat *stat)
1108{
1109 struct inode *inode = d_inode(dentry);
1110 generic_fillattr(inode, stat);
1111 return 0;
1112}
1113
1114static int empty_dir_setattr(struct dentry *dentry, struct iattr *attr)
1115{
1116 return -EPERM;
1117}
1118
1119static int empty_dir_setxattr(struct dentry *dentry, const char *name,
1120 const void *value, size_t size, int flags)
1121{
1122 return -EOPNOTSUPP;
1123}
1124
1125static ssize_t empty_dir_getxattr(struct dentry *dentry, const char *name,
1126 void *value, size_t size)
1127{
1128 return -EOPNOTSUPP;
1129}
1130
1131static int empty_dir_removexattr(struct dentry *dentry, const char *name)
1132{
1133 return -EOPNOTSUPP;
1134}
1135
1136static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t size)
1137{
1138 return -EOPNOTSUPP;
1139}
1140
1141static const struct inode_operations empty_dir_inode_operations = {
1142 .lookup = empty_dir_lookup,
1143 .permission = generic_permission,
1144 .setattr = empty_dir_setattr,
1145 .getattr = empty_dir_getattr,
1146 .setxattr = empty_dir_setxattr,
1147 .getxattr = empty_dir_getxattr,
1148 .removexattr = empty_dir_removexattr,
1149 .listxattr = empty_dir_listxattr,
1150};
1151
1152static loff_t empty_dir_llseek(struct file *file, loff_t offset, int whence)
1153{
1154 /* An empty directory has two entries . and .. at offsets 0 and 1 */
1155 return generic_file_llseek_size(file, offset, whence, 2, 2);
1156}
1157
1158static int empty_dir_readdir(struct file *file, struct dir_context *ctx)
1159{
1160 dir_emit_dots(file, ctx);
1161 return 0;
1162}
1163
1164static const struct file_operations empty_dir_operations = {
1165 .llseek = empty_dir_llseek,
1166 .read = generic_read_dir,
1167 .iterate = empty_dir_readdir,
1168 .fsync = noop_fsync,
1169};
1170
1171
1172void make_empty_dir_inode(struct inode *inode)
1173{
1174 set_nlink(inode, 2);
1175 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
1176 inode->i_uid = GLOBAL_ROOT_UID;
1177 inode->i_gid = GLOBAL_ROOT_GID;
1178 inode->i_rdev = 0;
1179 inode->i_size = 2;
1180 inode->i_blkbits = PAGE_SHIFT;
1181 inode->i_blocks = 0;
1182
1183 inode->i_op = &empty_dir_inode_operations;
1184 inode->i_fop = &empty_dir_operations;
1185}
1186
1187bool is_empty_dir_inode(struct inode *inode)
1188{
1189 return (inode->i_fop == &empty_dir_operations) &&
1190 (inode->i_op == &empty_dir_inode_operations);
1191}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 35ec87e490b1..0d5ae7d5dc53 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2780,6 +2780,8 @@ extern struct dentry *simple_lookup(struct inode *, struct dentry *, unsigned in
2780extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *); 2780extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
2781extern const struct file_operations simple_dir_operations; 2781extern const struct file_operations simple_dir_operations;
2782extern const struct inode_operations simple_dir_inode_operations; 2782extern const struct inode_operations simple_dir_inode_operations;
2783extern void make_empty_dir_inode(struct inode *inode);
2784extern bool is_empty_dir_inode(struct inode *inode);
2783struct tree_descr { char *name; const struct file_operations *ops; int mode; }; 2785struct tree_descr { char *name; const struct file_operations *ops; int mode; };
2784struct dentry *d_alloc_name(struct dentry *, const char *); 2786struct dentry *d_alloc_name(struct dentry *, const char *);
2785extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *); 2787extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *);